<commit_before>"use strict";

import { resolve } from 'path'
import debug from 'debug'
import fs from 'fs'
import http from 'http'
import { parse as urlParser } from 'url'
import ResourceResponder from './resource-responder'
import {EventEmitter} from 'events'

const P = f => new Promise(f)
const ____ = debug('faster-titanium:FileServer')
const ___x = debug('faster-titanium:FileServer:error')

/**
 * Serve resource files
 */
export default class FileServer extends EventEmitter {

    /**
     * @param {string} projDir project root directory (absolute path)
     * @param {number} [port=4157]
     * @param {string} [host=127.0.0.1]
     */
    constructor(projDir, port = 4157, host = '127.0.0.1') {
        super()

        this.projDir = projDir
        this.port    = parseInt(port, 10)
        this.host    = host
        this.server  = http.createServer(::this.onRequest)
        this.server.on('error', err => ___x(err) || this.emit('error', err))
    }


    /**
     * listen
     * @public
     * @return {Promise}
     */
    listen() {
        return P(y => this.server.listen(this.port, y)).then(x => {
            ____(`start listening ${this.host}:${this.port}`)
        })
    }


    /**
     * close server
     * @public
     * @return {Promise}
     */
    close() {
        ____(`terminating...`)
        return P(y => this.server.close(y) && y()).then(x => { // TODO this.server.close() doesn't call the given callback.
            ____(`closed`)
        })
    }


    /**
     * @param {http.ServerRequest} req
     * @param {http.ServerResponse} res
     * @private
     */
    onRequest(req, res) {
        try {
            const url = urlParser(req.url).pathname
            ____(`url: ${url}`)<commit_msg>FileServer: destroy connections on closing<commit_after>"use strict";

import { resolve } from 'path'
import debug from 'debug'
import fs from 'fs'
import http from 'http'
import { parse as urlParser } from 'url'
import ResourceResponder from './resource-responder'
import {EventEmitter} from 'events'

const P = f => new Promise(f)
const ____ = debug('faster-titanium:FileServer')
const ___x = debug('faster-titanium:FileServer:error')

/**
 * Serve resource files
 */
export default class FileServer extends EventEmitter {

    /**
     * @param {string} projDir project root directory (absolute path)
     * @param {number} [port=4157]
     * @param {string} [host=127.0.0.1]
     */
    constructor(projDir, port = 4157, host = '127.0.0.1') {
        super()

        /** @type {string} */
        this.projDir = projDir

        /** @type {number} */
        this.port = parseInt(port, 10)

        /** @type {string} */
        this.host = host

        /** @type {net.Socket[]} */
        this.sockets = []

        /** @type {http.Server} */
        this.server = http.createServer(::this.onRequest)
        this.server.on('error', err => ___x(err) || this.emit('error', err))
        this.server.on('connection', socket => this.sockets.push(socket))
    }


    /**
     * listen
     * @public
     * @return {Promise}
     */
    listen() {
        return P(y => this.server.listen(this.port, y)).then(x => {
            ____(`start listening ${this.host}:${this.port}`)
        })
    }


    /**
     * close server
     * @public
     * @return {Promise}
     */
    close() {
        ____(`terminating...`)
        this.sockets.forEach(socket => socket.destroy())
        return P(y => this.server.close(y)).then(x => {
            ____(`terminated`)
        })
    }


    /**
     * @param {http.ServerRequest} req
     * @param {http.ServerResponse} res
     * @private
     */
    onRequest(req, res) {
        try {
            const url = urlParser(req.url).pathname
            ____(`url: ${url}`)
{'fraction_non_alphanumeric': 0.15939329430548163, 'fraction_numerical': 0.011708355508249068, 'mean_word_length': 2.243313201035375, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 4, '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': '3679953', 'n_tokens_mistral': 1224, 'n_tokens_neox': 1166, 'n_words': 273}