<commit_before>"use strict";
var inherits = require('util').inherits;
var send = require('send');
var ops = require('ops');
var errors = require('../errors');
var HttpOnly = require('./http_only');


var Static = function (rootPath, opt_options) {
	HttpOnly.call(this, opt_options && opt_options.errorHandler);
	this.options = ops.cloneWithDefaults(opt_options, {
		single: false,
		matchKey: 'path',
		pathFunc: null,
		redirect: false,
		maxAge: 0,
		allowIndex: false,
		index: 'index.html'
	});

	this.rootPath = rootPath;
};
inherits(Static, HttpOnly);

Static.prototype.name = 'Static';

Static.prototype.handleHttpRequest = function (ctx) {
	var options = this.options;
	var self = this;

	send(ctx.req, this.extractPath(ctx))
		.root(this.rootPath)
		.hidden(options.hidden)
		.maxage(options.maxAge)
		.index(options.allowIndex && options.index)
		.on('error', function (err) {
			self.onError(ctx, err);
		})
		.on('directory', function () {
			self.onDir(ctx);
		})
		.on('end', function () {
			self.onEnd(ctx);
		})
		.pipe(ctx.res);
};

Static.prototype.extractPath = function (ctx) {
	var result = '';
	if (!this.options.single) {
		if (this.options.pathFunc != null) {
			result = this.options.pathFunc(this, ctx);
		}
		else if (ctx.pathMatchResult != null && this.options.matchKey != null) {
			result = ctx.pathMatchResult[this.options.matchKey] || '';
		}
	}
	return result;
};

Static.prototype.onError = function (ctx, err) {
	var status = err.status;
	if (status != null && status >= 400 && status < 500) {
		if ([400, 403, 404].indexOf(status) != -1) {
			// actually all of these are just bad paths
			err = new errors.NotFound();
		}
		else if (status == 416) {
			err = new errors.RequestedRangeNotSatisfiable();
		}
		// don't expect 'send' to provide any other HTTP errors
	}
	this.error(ctx, err);
};

Static.prototype.onDir = function (ctx) {
	var res = ctx.res;
	if (this.options.redirect) {
		res.redirect(ctx.req.path + '/', 301);
		ctx.responseSent();
		ctx.next();
	}
	else {
		this.error(ctx, new errors.NotFound());
	}
};

Static.prototype.onEnd = function (ctx) {
	ctx.res.end();
	ctx.responseSent();
	ctx.next();
};

Static.st = function (rootPath, opt_options) {
	return new Static(rootPath, opt_options);
};


module.exports = Static;<commit_msg>static handler fixes<commit_after>"use strict";
var inherits = require('util').inherits;
var send = require('send');
var ops = require('ops');
var errors = require('../errors');
var HttpOnly = require('./http_only');


var Static = function (rootPath, opt_options) {
	HttpOnly.call(this, opt_options && opt_options.errorHandler);
	this.options = ops.cloneWithDefaults(opt_options, {
		single: false,
		matchKey: 'path',
		pathFunc: null,
		redirect: false,
		maxAge: 0,
		allowIndex: false,
		index: 'index.html'
	});

	this.rootPath = rootPath;
};
inherits(Static, HttpOnly);

Static.prototype.name = 'Static';

Static.prototype.handleHttpRequest = function (ctx) {
	var path = this.extractPath(ctx);
	var options = this.options;
	var self = this;
	var sendStream = send(ctx.req, path)
		.root(this.rootPath)
		.hidden(options.hidden)
		.maxage(options.maxAge)
		.index(options.allowIndex && options.index)
		.on('error', function (err) {
			self.onError(ctx, sendStream, err);
		})
		.on('directory', function () {
			self.onDir(ctx, sendStream);
		})
		.on('end', function () {
			self.onEnd(ctx, sendStream);
		});
	sendStream.pipe(ctx.res);
};

Static.prototype.extractPath = function (ctx) {
	var result = '';
	if (!this.options.single) {
		if (this.options.pathFunc != null) {
			result = this.options.pathFunc(this, ctx);
		}
		else if (ctx.pathMatchResult != null && this.options.matchKey != null) {
			result = ctx.pathMatchResult[this.options.matchKey] || '';
		}
	}
	return result;
};

Static.prototype.onError = function (ctx, sendStream, err) {
	var status = err.status;
	if (status != null && status >= 400 && status < 500) {
		if ([400, 403, 404].indexOf(status) != -1) {
			// actually all of these are just bad paths
			err = new errors.NotFound();
		}
		else if (status == 416) {
			err = new errors.RequestedRangeNotSatisfiable();
		}
		// don't expect 'send' to provide any other HTTP errors
	}
	this.error(ctx, err);
};

Static.prototype.onDir = function (ctx, sendStream) {
	var res = ctx.res;
	var path = ctx.res.path;
	if (this.options.redirect && !(path && path[path.length - 1] == '/')) {
		res.redirect(ctx.req.path + '/', 301);
		ctx.responseSent();
		ctx.next();
	}
	else {
		this.error(ctx, new errors.NotFound());
	}
};

Static.prototype.onEnd = function (ctx, sendStream) {
	ctx.res.end();
	ctx.responseSent();
	ctx.next();
};

Static.st = function (rootPath, opt_options) {
	return new Static(rootPath, opt_options);
};


module.exports = Static;
{'fraction_non_alphanumeric': 0.1707214765100671, 'fraction_numerical': 0.00985738255033557, 'mean_word_length': 3.9215686274509802, 'pattern_counts': {'":': 0, '<': 5, '<?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': '6474237', 'n_tokens_mistral': 1801, 'n_tokens_neox': 1640, 'n_words': 374}