<commit_before>var gHandlers = [];

function addHandler(handler) {
	var added = false;
	for (var i in gHandlers) {
		if (gHandlers[i].method == handler.method && gHandlers[i].path == handler.path) {
			gHandlers[i] = handler;
			added = true;
			break;
		}
	}
	if (!added) {
		gHandlers.push(handler);
		added = true;
	}
}

function get(prefix, handler) {
	addHandler({
		owner: this,
		method: "GET",
		path: prefix,
		invoke: handler,
	});
}

function all(prefix, handler) {
	addHandler({
		owner: this,
		path: prefix,
		invoke: handler,
	});
}

function Request(method, uri, version, headers, body, client) {
	this.method = method;
	var index = uri.indexOf("?");
	if (index != -1) {
		this.uri = uri.slice(0, index);
		this.query = uri.slice(index + 1);
	} else {
		this.uri = uri;
		this.query = undefined;
	}
	this.version = version;
	this.headers = headers;
	this.client = {peerName: client.peerName};
	this.body = body;
	return this;
}

function findHandler(request) {
	var matchedHandler = null;
	for (var name in gHandlers) {
		var handler = gHandlers[name];
		if ((!handler.method || handler.method == request.method)
			&& (request.uri == handler.path || request.uri.slice(0, handler.path.length + 1) == handler.path + '/')) {
			matchedHandler = handler;
			break;
		}
	}
	return matchedHandler;
}

function Response(client) {
	var kStatusText = {
		200: 'OK',
		303: 'See other',
		404: 'File not found',
		500: 'Internal server error',
	};
	return {
		writeHead: function(status) {
			var reason;
			var headers;
			if (arguments.length == 3) {
				reason = arguments[1];
				headers = arguments[2];
			} else {
				reason = kStatusText[status];
				headers = arguments[1];
			}
			client.write("HTTP/1.0 " + status + " " + reason + "\n");
			for (var i in headers) {
				client.write(i + ": " + headers[i] + "\n");
			}
			client.write("\n");
		},
		/*write: function(data) {
			client.write(data);
		},*/
		end: function(data) {
			if (data) {
				client.write(data);
			}
			client.shutdown();
		},
		isConnected: function() { return client.isConnected; },
	};
}

function handleRequest(request, response) {
	var  handler = findHandler(request);

	if (request.uri != "/log/get") {
		imports.log.append(request.client.peerName + " - - [" + new Date() + "] " + request.method + " " + request.uri + " " + request.version + " \"" + request.headers["user-agent"] + "\"");
	}

	if (handler) {
		handler.invoke(request, response);
	} else {
		response.writeHead(200, {"Content-Type": "text/plain; encoding=utf-8", "Connection": "close"});
		response.end("No handler found for request: " + request.uri);
	}
}

function handleConnection(client) {
	var inputBuffer = "";
	var request;
	var headers = {};
	var lineByLine = true;
	var bodyToRead = -1;
	var body;

	function finish() {
		handleRequest(new Request(request[0], request[1], request[2], headers, body, client), new Response(client));
	}

	function handleLine(line, length) {
		if (bodyToRead == -1) {
			if (!request) {
				request = line.split(' ');
				return true;
			} else if (line) {
				var colon = line.indexOf(':');
				var key = line.slice(0, colon).trim();
				var value = line.slice(colon + 1).trim();
				headers[key.toLowerCase()] = value;
				return true;
			} else {
				if (headers["content-length"] > 0) {
					bodyToRead = headers["content-length"];
					lineByLine = false;
					body = "";
					return true;
				} else {
					handleRequest(new Request(request[0], request[1], request[2], headers, body, client), new Response(client));
					return false;
				}
			}
		} else {
			body += line;
			bodyToRead -= length;<commit_msg>Send HTTP response headers in one call.  Make an effort to display unhandled exceptions thrown while processing a request.<commit_after>var gHandlers = [];

function addHandler(handler) {
	var added = false;
	for (var i in gHandlers) {
		if (gHandlers[i].method == handler.method && gHandlers[i].path == handler.path) {
			gHandlers[i] = handler;
			added = true;
			break;
		}
	}
	if (!added) {
		gHandlers.push(handler);
		added = true;
	}
}

function get(prefix, handler) {
	addHandler({
		owner: this,
		method: "GET",
		path: prefix,
		invoke: handler,
	});
}

function all(prefix, handler) {
	addHandler({
		owner: this,
		path: prefix,
		invoke: handler,
	});
}

function Request(method, uri, version, headers, body, client) {
	this.method = method;
	var index = uri.indexOf("?");
	if (index != -1) {
		this.uri = uri.slice(0, index);
		this.query = uri.slice(index + 1);
	} else {
		this.uri = uri;
		this.query = undefined;
	}
	this.version = version;
	this.headers = headers;
	this.client = {peerName: client.peerName};
	this.body = body;
	return this;
}

function findHandler(request) {
	var matchedHandler = null;
	for (var name in gHandlers) {
		var handler = gHandlers[name];
		if ((!handler.method || handler.method == request.method)
			&& (request.uri == handler.path || request.uri.slice(0, handler.path.length + 1) == handler.path + '/')) {
			matchedHandler = handler;
			break;
		}
	}
	return matchedHandler;
}

function Response(client) {
	var kStatusText = {
		200: 'OK',
		303: 'See other',
		404: 'File not found',
		500: 'Internal server error',
	};
	var _started = false;
	var _finished = false;
	return {
		writeHead: function(status) {
			if (_started) {
				throw new Error("Response.writeHead called multiple times.");
			}
			var reason;
			var headers;
			if (arguments.length == 3) {
				reason = arguments[1];
				headers = arguments[2];
			} else {
				reason = kStatusText[status];
				headers = arguments[1];
			}
			var headerString = "HTTP/1.0 " + status + " " + reason + "\n";
			for (var i in headers) {
				headerString += i + ": " + headers[i] + "\n";
			}
			headerString += "\n";
			_started = true;
			client.write(headerString);
		},
		end: function(data) {
			if (_finished) {
				throw new Error("Response.end called multiple times.");
			}
			if (data) {
				client.write(data);
			}
			_finished = true;
			client.shutdown();
		},
		reportError: function(error) {
			if (!_started) {
				client.write("HTTP/1.0 500 Internal Server Error\nContent-Type: text/plain\n\n");
			}
			if (!_finished) {
				client.write("500 Internal Server Error\n\n" + error.stackTrace);
				client.shutdown();
			}
		},
		isConnected: function() { return client.isConnected; },
	};
}

function handleRequest(request, response) {
	var  handler = findHandler(request);

	if (request.uri != "/log/get") {
		imports.log.append(request.client.peerName + " - - [" + new Date() + "] " + request.method + " " + request.uri + " " + request.version + " \"" + request.headers["user-agent"] + "\"");
	}

	if (handler) {
		handler.invoke(request, response).catch(function(error) {
			response.reportError(error);
		});
	} else {
		response.writeHead(200, {"Content-Type": "text/plain; encoding=utf-8", "Connection": "close"});
		response.end("No handler found for request: " + request.uri);
	}
}

function handleConnection(client) {
	var inputBuffer = "";
	var request;
	var headers = {};
	var lineByLine = true;
	var bodyToRead = -1;
	var body;

	function finish() {
		handleRequest(new Request(request[0], request[1], request[2], headers, body, client), new Response(client))
	}

	function handleLine(line, length) {
		if (bodyToRead == -1) {
			if (!request) {
				request = line.split(' ');
				return true;
			} else if (line) {
				var colon = line.indexOf(':');
				var key = line.slice(0, colon).trim();
				var value = line.slice(colon + 1).trim();
				headers[key.toLowerCase()] = value;
				return true;
			} else {
				if (headers["content-length"] > 0) {
					bodyToRead = headers["content-length"];
					lineByLine = false;
					body = "";
					return true;
				} else {
					handleRequest(new Request(request[0], request[1], request[2], headers, body, client), new Response(client));
					return false;
				}
			}
		} else {
			body += line;
			bodyToRead -= length;
{'fraction_non_alphanumeric': 0.16700353713996968, 'fraction_numerical': 0.010611419909044972, 'mean_word_length': 3.298045602605863, 'pattern_counts': {'":': 6, '<': 3, '<?xml version=': 0, '>': 5, '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': '2723796', 'n_tokens_mistral': 3087, 'n_tokens_neox': 2688, 'n_words': 652}