<commit_before>const BadRequestHttpException = Jymfony.Component.HttpFoundation.Exception.BadRequestHttpException;
const HttpExceptionInterface = Jymfony.Component.HttpFoundation.Exception.HttpExceptionInterface;
const NotFoundHttpException = Jymfony.Component.HttpFoundation.Exception.NotFoundHttpException;
const RequestExceptionInterface = Jymfony.Component.HttpFoundation.Exception.RequestExceptionInterface;
const ContentType = Jymfony.Component.HttpFoundation.Header.ContentType;
const Request = Jymfony.Component.HttpFoundation.Request;
const Response = Jymfony.Component.HttpFoundation.Response;
const Event = Jymfony.Component.HttpServer.Event;
const RequestParser = Jymfony.Component.HttpServer.RequestParser;

/**
 * @memberOf Jymfony.Component.HttpServer
 */
class HttpServer {
    /**
     * Constructor.
     *
     * @param {Jymfony.Component.EventDispatcher.EventDispatcherInterface} dispatcher
     * @param {Jymfony.Component.HttpFoundation.Controller.ControllerResolverInterface} resolver
     * @param {http.Server} http
     */
    __construct(dispatcher, resolver, http = require('http')) {
        /**
         * @type {Jymfony.Component.EventDispatcher.EventDispatcherInterface}
         * @protected
         */
        this._dispatcher = dispatcher;

        /**
         * @type {Jymfony.Component.HttpFoundation.Controller.ControllerResolverInterface}
         * @protected
         */
        this._resolver = resolver;

        /**
         * @type {http.Server}
         * @protected
         */
        this._http = new http.Server(this._incomingRequest.bind(this));
    }

    /**
     * Listen and handle connections.
     *
     * @returns {Promise<void>}
     */
    listen({ port = 80, host = '0.0.0.0', path = undefined } = {}) {
        return new Promise((resolve, reject) => {
            this._http.on('error', e => {
                this._http.removeAllListeners('close');
                this._http.close();

                reject(e);
            });

            this._http.on('close', resolve);

            if (!! path) {
                this._http.listen({ path });
            } else {
                this._http.listen({ host, port });
            }
        });
    }

    /**
     * Handles an incoming request from the http server.
     *
     * @param {IncomingMessage} req
     * @param {ServerResponse} res
     *
     * @private
     */
    _incomingRequest(req, res) {
        return __jymfony.Async
            .run(this._handleRequest(req, res))
            .catch(() => {
                res.writeHead(500, { 'Content-Type': 'text/plain' });
                res.write('Unknown error while handling your request.\r\n');
                res.end();
            });
    }

    /**
     * Converts an IncomingMessage to an HttpFoundation request
     * and sends it to the Kernel.
     *
     * @param {IncomingMessage} req
     * @param {ServerResponse} res
     *
     * @protected
     */
    * _handleRequest(req, res) {
        const contentType = new ContentType(req.headers['content-type'] || 'application/x-www-form-urlencoded');
        let requestParams, content;

        try {
            [ requestParams, content ] = yield this._parseRequestContent(req, contentType);
        } catch (e) {
            if (e instanceof BadRequestException) {
                res.writeHead(400, {'Content-Type': 'text/plain'});
            } else {
                res.writeHead(500, {'Content-Type': 'text/plain'});
            }

            res.end();
            return;
        }

        const request = new Request(req.url, requestParams, {}, req.headers, {
            'REQUEST_METHOD': req.method,
            'REMOTE_ADDR': req.connection.remoteAddress,
            'SCHEME': this._getScheme(),
            'SERVER_PROTOCOL': 'HTTP/'+req.httpVersion,
        }, content);

        const response = yield this.handle(request);
        response.prepare(request);

        res.writeHead(response.statusCode, response.statusText, response.headers.all);
        yield new Promise((resolve) => {
            res.write(response.content, 'utf8', () => {
                resolve();
            });
        });

        res.end();
    }

    /**
     * Handles a Request to convert it to a Response.
     *
     * When catchExceptions is true, catches all exceptions
     * and do its best to convert them to a Response instance.
     *<commit_msg>[HttpServer] do not wait for response write if has no content<commit_after>const BadRequestHttpException = Jymfony.Component.HttpFoundation.Exception.BadRequestHttpException;
const HttpExceptionInterface = Jymfony.Component.HttpFoundation.Exception.HttpExceptionInterface;
const NotFoundHttpException = Jymfony.Component.HttpFoundation.Exception.NotFoundHttpException;
const RequestExceptionInterface = Jymfony.Component.HttpFoundation.Exception.RequestExceptionInterface;
const ContentType = Jymfony.Component.HttpFoundation.Header.ContentType;
const Request = Jymfony.Component.HttpFoundation.Request;
const Response = Jymfony.Component.HttpFoundation.Response;
const Event = Jymfony.Component.HttpServer.Event;
const RequestParser = Jymfony.Component.HttpServer.RequestParser;

/**
 * @memberOf Jymfony.Component.HttpServer
 */
class HttpServer {
    /**
     * Constructor.
     *
     * @param {Jymfony.Component.EventDispatcher.EventDispatcherInterface} dispatcher
     * @param {Jymfony.Component.HttpFoundation.Controller.ControllerResolverInterface} resolver
     * @param {http.Server} http
     */
    __construct(dispatcher, resolver, http = require('http')) {
        /**
         * @type {Jymfony.Component.EventDispatcher.EventDispatcherInterface}
         * @protected
         */
        this._dispatcher = dispatcher;

        /**
         * @type {Jymfony.Component.HttpFoundation.Controller.ControllerResolverInterface}
         * @protected
         */
        this._resolver = resolver;

        /**
         * @type {http.Server}
         * @protected
         */
        this._http = new http.Server(this._incomingRequest.bind(this));
    }

    /**
     * Listen and handle connections.
     *
     * @returns {Promise<void>}
     */
    listen({ port = 80, host = '0.0.0.0', path = undefined } = {}) {
        return new Promise((resolve, reject) => {
            this._http.on('error', e => {
                this._http.removeAllListeners('close');
                this._http.close();

                reject(e);
            });

            this._http.on('close', resolve);

            if (!! path) {
                this._http.listen({ path });
            } else {
                this._http.listen({ host, port });
            }
        });
    }

    /**
     * Handles an incoming request from the http server.
     *
     * @param {IncomingMessage} req
     * @param {ServerResponse} res
     *
     * @private
     */
    _incomingRequest(req, res) {
        return __jymfony.Async
            .run(this._handleRequest(req, res))
            .catch(() => {
                res.writeHead(500, { 'Content-Type': 'text/plain' });
                res.write('Unknown error while handling your request.\r\n');
                res.end();
            });
    }

    /**
     * Converts an IncomingMessage to an HttpFoundation request
     * and sends it to the Kernel.
     *
     * @param {IncomingMessage} req
     * @param {ServerResponse} res
     *
     * @protected
     */
    * _handleRequest(req, res) {
        const contentType = new ContentType(req.headers['content-type'] || 'application/x-www-form-urlencoded');
        let requestParams, content;

        try {
            [ requestParams, content ] = yield this._parseRequestContent(req, contentType);
        } catch (e) {
            if (e instanceof BadRequestException) {
                res.writeHead(400, {'Content-Type': 'text/plain'});
            } else {
                res.writeHead(500, {'Content-Type': 'text/plain'});
            }

            res.end();
            return;
        }

        const request = new Request(req.url, requestParams, {}, req.headers, {
            'REQUEST_METHOD': req.method,
            'REMOTE_ADDR': req.connection.remoteAddress,
            'SCHEME': this._getScheme(),
            'SERVER_PROTOCOL': 'HTTP/'+req.httpVersion,
        }, content);

        const response = yield this.handle(request);
        response.prepare(request);

        res.writeHead(response.statusCode, response.statusText, response.headers.all);

        if (! response.isEmpty && response.content) {
            yield new Promise((resolve) => {
                res.write(response.content, 'utf8', () => {
                    resolve();
                });
            });
        }

        res.end();
    }

    /**
     * Handles a Request to convert it to a Response.
     *
     * When catchExceptions is true, catches all exceptions
     * and do its best to convert them to a Response instance.
     *
{'fraction_non_alphanumeric': 0.12036726010525137, 'fraction_numerical': 0.0035830254170865525, 'mean_word_length': 2.132935811995791, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, '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': '3095233', 'n_tokens_mistral': 2435, 'n_tokens_neox': 2354, 'n_words': 479}