<commit_before>var superagent = require('superagent'),
	RLS = require('./RequestLocalStorage').getNamespace(),
	logger = require('../logging').getLogger(__LOGGER__),
	config = require("../config"),
	Q = require('q');

/**
 * Wrapper around superagent.Request. Passes through function calls
 * to the wrapped request, except for end() which it enhances with
 * caching for server-side requests.
 */
function Request(req) {
	logger.debug("Making wrapped request");
	this._req = req;
}

// mix in properties from superagent.Request,
// but skip the 'end' method -- we'll do that manaully
Object.keys(superagent.Request.prototype)
	.filter( propName => propName !== 'end' )
	.forEach( propName => {
		var originalProp = superagent.Request.prototype[propName];
		if (typeof originalProp === 'function') {
			Request.prototype[propName] = () => originalProp.apply(this._req, arguments);
		} else {
			Request.prototype[propName] = originalProp;
		}
	});

/**
 * Wrap superagent's end() method to create an entry in a request-local
 * data cache that will be serialized to the client and replayed in the
 * browser.
 */
Request.prototype.end = function (fn) {
	var superagentRequestEnd = superagent.Request.prototype.end;

	// TODO: support both (err, res) and (res) function signatures
	if (fn.length !== 2) {
		throw `Callback passed to end() must be the two-arg version: (err, res)`;
	}

	// only do caching for responses for GET requests for now
	if (this._req.method !== 'GET') {
		return superagentRequestEnd.apply(this._req, arguments);
	}

	var url = this._req.url;

	// get cache entry for url if exists; if server-side, create one if it doesn't already exist
	var entry = makeRequest.cache().entry(url, SERVER_SIDE /* createIfMissing */);
	if (!SERVER_SIDE && !entry) {
		return superagentRequestEnd.apply(this._req, arguments);
	}

	// no previous requesters? fire the request
	if (entry.requesters === 0) {
		superagentRequestEnd.call(this._req, function (err, res) {
			if (err) {
				entry.setError(err);
				return;
			}
			entry.setResponse(res);
		});
	}

	entry.whenDataReady().nodeify(fn);

	return this;
}

/**
 * Convenience method to treat the request as then-able (promise-like).
 * This is shorthand for the simple case. If you want access to the full
 * power of the underlying promise library, use `Request.asPromise()`
 */
Request.prototype.then = function (/*arguments*/) {
	var dfd = this.asPromise();
	return dfd.then.apply(dfd, arguments);
};

/**
 * Convenience method wrapping `.end()` and returning a promise
 * that is resolved if the request is successful, and rejected if
 * the request results in an error.
 */
Request.prototype.asPromise = function () {
	var dfd = Q.defer();
	this.end(dfd.makeNodeResolver());
	return dfd.promise;
}

// wrapper for superagent
function makeRequest (method, url) {
	var req = superagent.apply(null, arguments);
	
	// add default headers to request (if necessary)
	var defaultHeaders = makeRequest.defaultHeaders();
	if (defaultHeaders) {
		req.set(defaultHeaders);
	}

	return new Request(req);
}
module.exports = makeRequest;


makeRequest.get = function (url, data, fn) {
	var req = makeRequest('GET', url);
	if ('function' == typeof data) fn = data, data = null;
	if (data) req.query(data);
	if (fn) req.end(fn);
	return req;
}

makeRequest.head = function (url, data, fn){
	var req = makeRequest('HEAD', url);
	if ('function' == typeof data) fn = data, data = null;
	if (data) req.send(data);
	if (fn) req.end(fn);
	return req;
};

makeRequest.del = function (url, fn){
	var req = makeRequest('DELETE', url);
	if (fn) req.end(fn);
	return req;
};

makeRequest.patch = function (url, data, fn){
	var req = makeRequest('PATCH', url);
	if ('function' == typeof data) fn = data, data = null;
	if (data) req.send(data);
	if (fn) req.end(fn);
	return req;
};

makeRequest.post = function (url, data, fn){
	var req = makeRequest('POST', url);
	if ('function' == typeof data) fn = data, data = null;
	if (data) req.send(data);
	if (fn) req.end(fn);
	return req;
};

makeRequest.put = function (url, data, fn){
	var req = makeRequest('PUT', url);
	if ('function' == typeof data) fn = data, data = null;
	if (data) req.send(data);
	if (fn) req.end(fn);
	return req;
};



makeRequest.cache = function () {

	var cache = RLS().cache;
	if (!cache) {
		cache = RLS().cache = new RequestDataCache();
	}
	return cache;
}

/**
 * Get or set the default headers for TritonAgent's http requests.
 * If `headers` is specified, set them; else, return them.
 */
makeRequest.defaultHeaders = function (headers) {
	if (SERVER_SIDE) {
		if (typeof headers === 'undefined') {
			return RLS().defaultHeaders;
		}
		RLS().defaultHeaders = headers;
	} else {
		logger.warning("Attempted to set defaultHeaders in TritonAgent on the client");
	}
}

/**
 * An entry in the RequestDataCache
 */
class CacheEntry {

	constructor (cache, url) {
		this.cache = cache;
		this.url = url;
		this.requesters = 0;
		this.dfd = Q.defer();
		this.dfd.promise.fin/*ally*/( () => logger.debug(`Data resolved for: ${url}`) );
		this.loaded = false;
		this.res = undefined;
		this.err = undefined;
	}

	dehydrate () {
		return {
			url: this.url,
			requesters: this.requesters,
			loaded: this.loaded,
			res: this.res,
			err: this.err // TODO: does this do something reasonable for Error objects?
		};
	}

	rehydrate (state) {
		this.url = state.url;
		this.requesters = state.requesters;<commit_msg>Removing some unnecessary logging<commit_after>var superagent = require('superagent'),
	RLS = require('./RequestLocalStorage').getNamespace(),
	logger = require('../logging').getLogger(__LOGGER__),
	config = require("../config"),
	Q = require('q');

/**
 * Wrapper around superagent.Request. Passes through function calls
 * to the wrapped request, except for end() which it enhances with
 * caching for server-side requests.
 */
function Request(req) {
	logger.debug("Making wrapped request");
	this._req = req;
}

// mix in properties from superagent.Request,
// but skip the 'end' method -- we'll do that manaully
Object.keys(superagent.Request.prototype)
	.filter( propName => propName !== 'end' )
	.forEach( propName => {
		var originalProp = superagent.Request.prototype[propName];
		if (typeof originalProp === 'function') {
			Request.prototype[propName] = () => originalProp.apply(this._req, arguments);
		} else {
			Request.prototype[propName] = originalProp;
		}
	});

/**
 * Wrap superagent's end() method to create an entry in a request-local
 * data cache that will be serialized to the client and replayed in the
 * browser.
 */
Request.prototype.end = function (fn) {
	var superagentRequestEnd = superagent.Request.prototype.end;

	// TODO: support both (err, res) and (res) function signatures
	if (fn.length !== 2) {
		throw `Callback passed to end() must be the two-arg version: (err, res)`;
	}

	// only do caching for responses for GET requests for now
	if (this._req.method !== 'GET') {
		return superagentRequestEnd.apply(this._req, arguments);
	}

	var url = this._req.url;

	// get cache entry for url if exists; if server-side, create one if it doesn't already exist
	var entry = makeRequest.cache().entry(url, SERVER_SIDE /* createIfMissing */);
	if (!SERVER_SIDE && !entry) {
		return superagentRequestEnd.apply(this._req, arguments);
	}

	// no previous requesters? fire the request
	if (entry.requesters === 0) {
		superagentRequestEnd.call(this._req, function (err, res) {
			if (err) {
				entry.setError(err);
				return;
			}
			entry.setResponse(res);
		});
	}

	entry.whenDataReady().nodeify(fn);

	return this;
}

/**
 * Convenience method to treat the request as then-able (promise-like).
 * This is shorthand for the simple case. If you want access to the full
 * power of the underlying promise library, use `Request.asPromise()`
 */
Request.prototype.then = function (/*arguments*/) {
	var dfd = this.asPromise();
	return dfd.then.apply(dfd, arguments);
};

/**
 * Convenience method wrapping `.end()` and returning a promise
 * that is resolved if the request is successful, and rejected if
 * the request results in an error.
 */
Request.prototype.asPromise = function () {
	var dfd = Q.defer();
	this.end(dfd.makeNodeResolver());
	return dfd.promise;
}

// wrapper for superagent
function makeRequest (method, url) {
	var req = superagent.apply(null, arguments);
	
	// add default headers to request (if necessary)
	var defaultHeaders = makeRequest.defaultHeaders();
	if (defaultHeaders) {
		req.set(defaultHeaders);
	}

	return new Request(req);
}
module.exports = makeRequest;


makeRequest.get = function (url, data, fn) {
	var req = makeRequest('GET', url);
	if ('function' == typeof data) fn = data, data = null;
	if (data) req.query(data);
	if (fn) req.end(fn);
	return req;
}

makeRequest.head = function (url, data, fn){
	var req = makeRequest('HEAD', url);
	if ('function' == typeof data) fn = data, data = null;
	if (data) req.send(data);
	if (fn) req.end(fn);
	return req;
};

makeRequest.del = function (url, fn){
	var req = makeRequest('DELETE', url);
	if (fn) req.end(fn);
	return req;
};

makeRequest.patch = function (url, data, fn){
	var req = makeRequest('PATCH', url);
	if ('function' == typeof data) fn = data, data = null;
	if (data) req.send(data);
	if (fn) req.end(fn);
	return req;
};

makeRequest.post = function (url, data, fn){
	var req = makeRequest('POST', url);
	if ('function' == typeof data) fn = data, data = null;
	if (data) req.send(data);
	if (fn) req.end(fn);
	return req;
};

makeRequest.put = function (url, data, fn){
	var req = makeRequest('PUT', url);
	if ('function' == typeof data) fn = data, data = null;
	if (data) req.send(data);
	if (fn) req.end(fn);
	return req;
};



makeRequest.cache = function () {

	var cache = RLS().cache;
	if (!cache) {
		cache = RLS().cache = new RequestDataCache();
	}
	return cache;
}

/**
 * Get or set the default headers for TritonAgent's http requests.
 * If `headers` is specified, set them; else, return them.
 */
makeRequest.defaultHeaders = function (headers) {
	if (SERVER_SIDE) {
		if (typeof headers === 'undefined') {
			return RLS().defaultHeaders;
		}
		RLS().defaultHeaders = headers;
	} else {
		logger.warning("Attempted to set defaultHeaders in TritonAgent on the client");
	}
}

/**
 * An entry in the RequestDataCache
 */
class CacheEntry {

	constructor (cache, url) {
		this.cache = cache;
		this.url = url;
		this.requesters = 0;
		this.dfd = Q.defer();
		this.loaded = false;
		this.res = undefined;
		this.err = undefined;
	}

	dehydrate () {
		return {
			url: this.url,
			requesters: this.requesters,
			loaded: this.loaded,
			res: this.res,
			err: this.err // TODO: does this do something reasonable for Error objects?
		};
	}

	rehydrate (state) {
		this.url = state.url;
		this.requesters = state.requesters;
{'fraction_non_alphanumeric': 0.14561127073871535, 'fraction_numerical': 0.0005561219760867551, 'mean_word_length': 3.8912058023572076, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7186599', 'n_tokens_mistral': 3670, 'n_tokens_neox': 3465, 'n_words': 1091}