<commit_before>var path = require('path');
var util = require('util');
var http = require('http');
var url = require('url');

var NTLM = require(path.join(path.dirname(module.filename), '..', '..', 'lib', 'NTLM.js'));
var Flags = require(path.join(path.dirname(module.filename), '..', '..', 'lib', 'Flags.js'));

/**
 * @constructor
 * @class
 *
 * @param {Function} getUserCredentialsCallback
 */
var NTLMProxy = function(getUserCredentialsCallback){
	'use strict';

	if (!(this instanceof NTLMProxy)) {
		return new NTLMProxy(getUserCredentialsCallback);
	}

	var self = http.createServer();
	var ntlm = new NTLM();

	var respondUnauthorized = function(req, res) {
		var text = 'Proxy Authentication Required';
		res.writeHead(407, {
			'Content-Type': 'text/plain; charset=UTF8',
			'Content-Length': text.length,
			'Date': (new Date()).toUTCString(),
			'Proxy-Authenticate': 'NTLM',
			'Connection': 'close'
		});
		res.end(text);

		if (req.connection) {
			req.connection.end();
		}
	};

	var respondWithMessage = function(req, res, message) {
		var text = 'Proxy Authentication Required';
		res.writeHead(407, {
			'Content-Type': 'text/plain; charset=UTF8',
			'Content-Length': text.length,
			'Date': (new Date()).toUTCString(),
			'Proxy-Authenticate': 'NTLM '+message.toString('base64'),
			'Connection': 'keep-alive'
		});
		res.end(text);
	};

	var tunnelRequest = function(request, response) {
		var reqURL = url.parse(request.url, false, true);
		reqURL.protocol = reqURL.protocol || (request.connection.encrypted ? 'https:' : 'http:');
		reqURL.host = reqURL.host || ''; // Ugly: Just to allow splitting in next two lines.
		reqURL.hostname = reqURL.hostname || reqURL.host.split(':')[0] || request.headers.host.split(':')[0];
		reqURL.port = reqURL.port || reqURL.host.split(':')[1] || request.headers.host.split(':')[1] || (reqURL.protocol === 'https:' ? 443 : 80);
		reqURL.host = reqURL.hostname + (reqURL.port === 443 || reqURL.port === 80 ? '' : ':' + reqURL.port);
		reqURL.pathname = reqURL.pathname || '/';
		reqURL.path = reqURL.path || reqURL.pathname + (reqURL.search || '');
		reqURL.href = url.format(reqURL);

		var reqOptions = {
			host: reqURL.hostname,
			port: reqURL.port,
			path: reqURL.path,
			headers: request.headers,
			method: request.method
		};

		var destination = http.request(reqOptions, function(source){
			source.on('close', function(){
				source.connection.end();
			});

			source.on('error', function(error){
				self.emit('error', error, {hostname: reqURL.hostname, state: 'sourceError'});
			});

			response.writeHead(source.statusCode, source.headers);
			source.pipe(response);
		});

		destination.on('error', function(error){
			self.emit('error', error, {hostname: reqURL.hostname, state: 'destinationError'});
			response.end();
		});

		request.pipe(destination);

		request.on('close', function(){
			if (destination.connection) {
				destination.connection.end();
			}
		});

		request.on('error', function(error){
			response.end();
			self.emit('error', error, {hostname: reqURL.hostname, state: 'requestError'});
		});
	};

	self.on('socket', function(socket){
		console.log('socket!');
		socket.ntlmState = false;
	});

	self.on('request', function(req, res){
		var text = '';

		if (!req.headers.hasOwnProperty('proxy-authorization')) {
			return respondUnauthorized(req, res);
		}

		if (!req.connection.ntlmState) {
			var message1 = ntlm.readType1Message(req.headers['proxy-authorization']);

			if (!message1) {
				return respondUnauthorized(req, res);
			}

			var message2 = ntlm.createType2Message('hyperProxy', new Flags(ntlm.FLAGS.negotiateUnicode | ntlm.FLAGS.targetTypeDomain | ntlm.FLAGS.negotiateNTLM | ntlm.FLAGS.negotiateTargetInfo, ntlm.FLAGS), new Buffer('0123456789abcdef', 'hex'), null, {
				computerName: new Buffer('test', 'utf8').toString('ucs2'),
				domainName: new Buffer('hyperProxy', 'utf8').toString('ucs2'),
				dnsComputerName: new Buffer('test.hyperProxy.fake', 'utf8').toString('ucs2'),
				dnsDomainName: new Buffer('hyperProxy.fake', 'utf8').toString('ucs2')<commit_msg>Cleaned up NTLMProxy used for testing.<commit_after>var path = require('path');
var util = require('util');
var http = require('http');
var url = require('url');

var NTLM = require(path.join(path.dirname(module.filename), '..', '..', 'lib', 'NTLM.js'));
var Flags = require(path.join(path.dirname(module.filename), '..', '..', 'lib', 'Flags.js'));

/**
 * @constructor
 * @class
 *
 * @param {Function} getUserCredentialsCallback
 */
var NTLMProxy = function(getUserCredentialsCallback){
	'use strict';

	if (!(this instanceof NTLMProxy)) {
		return new NTLMProxy(getUserCredentialsCallback);
	}

	var self = http.createServer();
	var ntlm = new NTLM();

	var respondUnauthorized = function(req, res) {
		var text = 'Proxy Authentication Required';
		res.writeHead(407, {
			'Content-Type': 'text/plain; charset=UTF8',
			'Content-Length': text.length,
			'Date': (new Date()).toUTCString(),
			'Proxy-Authenticate': 'NTLM',
			'Connection': 'close'
		});
		res.end(text);

		if (req.connection) {
			req.connection.end();
		}
	};

	var respondWithMessage = function(req, res, message) {
		var text = 'Proxy Authentication Required';
		res.writeHead(407, {
			'Content-Type': 'text/plain; charset=UTF8',
			'Content-Length': text.length,
			'Date': (new Date()).toUTCString(),
			'Proxy-Authenticate': 'NTLM '+message.toString('base64'),
			'Connection': 'keep-alive'
		});
		res.end(text);
	};

	var tunnelRequest = function(request, response) {
		var reqURL = url.parse(request.url, false, true);
		reqURL.protocol = reqURL.protocol || (request.connection.encrypted ? 'https:' : 'http:');
		reqURL.host = reqURL.host || ''; // Ugly: Just to allow splitting in next two lines.
		reqURL.hostname = reqURL.hostname || reqURL.host.split(':')[0] || request.headers.host.split(':')[0];
		reqURL.port = reqURL.port || reqURL.host.split(':')[1] || request.headers.host.split(':')[1] || (reqURL.protocol === 'https:' ? 443 : 80);
		reqURL.host = reqURL.hostname + (reqURL.port === 443 || reqURL.port === 80 ? '' : ':' + reqURL.port);
		reqURL.pathname = reqURL.pathname || '/';
		reqURL.path = reqURL.path || reqURL.pathname + (reqURL.search || '');
		reqURL.href = url.format(reqURL);

		var reqOptions = {
			host: reqURL.hostname,
			port: reqURL.port,
			path: reqURL.path,
			headers: request.headers,
			method: request.method
		};

		var destination = http.request(reqOptions, function(source){
			source.on('close', function(){
				source.connection.end();
			});

			source.on('error', function(error){
				self.emit('error', error, {hostname: reqURL.hostname, state: 'sourceError'});
			});

			response.writeHead(source.statusCode, source.headers);
			source.pipe(response);
		});

		destination.on('error', function(error){
			self.emit('error', error, {hostname: reqURL.hostname, state: 'destinationError'});
			response.end();
		});

		request.pipe(destination);

		request.on('close', function(){
			if (destination.connection) {
				destination.connection.end();
			}
		});

		request.on('error', function(error){
			response.end();
			self.emit('error', error, {hostname: reqURL.hostname, state: 'requestError'});
		});
	};

	self.on('connection', function(socket){
		socket.ntlmState = false;
	});

	self.on('request', function(req, res){
		var text = '';

		if (!req.headers.hasOwnProperty('proxy-authorization')) {
			return respondUnauthorized(req, res);
		}

		if (!req.connection.ntlmState) {
			var message1 = ntlm.readType1Message(req.headers['proxy-authorization']);

			if (!message1) {
				return respondUnauthorized(req, res);
			}

			var message2 = ntlm.createType2Message('hyperProxy', new Flags(ntlm.FLAGS.negotiateUnicode | ntlm.FLAGS.targetTypeDomain | ntlm.FLAGS.negotiateNTLM | ntlm.FLAGS.negotiateTargetInfo, ntlm.FLAGS), new Buffer('0123456789abcdef', 'hex'), null, {
				computerName: new Buffer('test', 'utf8').toString('ucs2'),
				domainName: new Buffer('hyperProxy', 'utf8').toString('ucs2'),
				dnsComputerName: new Buffer('test.hyperProxy.fake', 'utf8').toString('ucs2'),
				dnsDomainName: new Buffer('hyperProxy.fake', 'utf8').toString('ucs2')
{'fraction_non_alphanumeric': 0.1868037703513282, 'fraction_numerical': 0.011506916391235158, 'mean_word_length': 4.486903962390866, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '782860', 'n_tokens_mistral': 3036, 'n_tokens_neox': 2712, 'n_words': 517}