Request: new request session flag to mark those files opened by FDT

This patch aims to fix a potential DDoS problem that can be caused
in the server quering repetitive non-existent resources.

When serving a static file, the core use Vhost FDT mechanism, but if
it sends a static error page it does a direct open(2). When closing
the resources for the same request it was just calling mk_vhost_close()
which did not clear properly the file descriptor.

This patch adds a new field on the struct session_request called 'fd_is_fdt',
which contains MK_TRUE or MK_FALSE depending of how fd_file was opened.

Thanks to Matthew Daley <mattd@bugfuzz.com> for report and troubleshoot this
problem.

Signed-off-by: Eduardo Silva <eduardo@monkey.io>
void mk_vhost_set_single(char *path)
{
    struct host *host;
    struct host_alias *halias;
    struct stat checkdir;
    unsigned long len = 0;

    /* Set the default host */
    host = mk_mem_malloc_z(sizeof(struct host));
    mk_list_init(&host->error_pages);
    mk_list_init(&host->server_names);

    /* Prepare the unique alias */
    halias = mk_mem_malloc_z(sizeof(struct host_alias));
    halias->name = mk_string_dup("127.0.0.1");
    mk_list_add(&halias->_head, &host->server_names);

    host->documentroot.data = mk_string_dup(path);
    host->documentroot.len = strlen(path);
    host->header_redirect.data = NULL;

    /* Validate document root configured */
    if (stat(host->documentroot.data, &checkdir) == -1) {
        mk_err("Invalid path to DocumentRoot in %s", path);
        exit(EXIT_FAILURE);
    }
    else if (!(checkdir.st_mode & S_IFDIR)) {
        mk_err("DocumentRoot variable in %s has an invalid directory path", path);
        exit(EXIT_FAILURE);
    }

    /* Server Signature */
    if (config->hideversion == MK_FALSE) {
        mk_string_build(&host->host_signature, &len,
                        "Monkey/%s", VERSION);
    }
    else {
        mk_string_build(&host->host_signature, &len, "Monkey");
    }

    mk_string_build(&host->header_host_signature.data,
                    &host->header_host_signature.len,
                    "Server: %s", host->host_signature);

    mk_list_add(&host->_head, &config->hosts);
}

void mk_vhost_set_single(char *path)
{
    struct host *host;
    struct host_alias *halias;
    struct stat checkdir;
    unsigned long len = 0;

    /* Set the default host */
    host = mk_mem_malloc_z(sizeof(struct host));
    mk_list_init(&host->error_pages);
    mk_list_init(&host->server_names);

    /* Prepare the unique alias */
    halias = mk_mem_malloc_z(sizeof(struct host_alias));
    halias->name = mk_string_dup("127.0.0.1");
    mk_list_add(&halias->_head, &host->server_names);

    host->documentroot.data = mk_string_dup(path);
    host->documentroot.len = strlen(path);
    host->header_redirect.data = NULL;

    /* Validate document root configured */
    if (stat(host->documentroot.data, &checkdir) == -1) {
        mk_err("Invalid path to DocumentRoot in %s", path);
        exit(EXIT_FAILURE);
    }
    else if (!(checkdir.st_mode & S_IFDIR)) {
        mk_err("DocumentRoot variable in %s has an invalid directory path", path);
        exit(EXIT_FAILURE);
    }

    /* Server Signature */
    if (config->hideversion == MK_FALSE) {
        mk_string_build(&host->host_signature, &len,
                        "Monkey/%s", VERSION);
    }
    else {
        mk_string_build(&host->host_signature, &len, "Monkey");
    }

    mk_string_build(&host->header_host_signature.data,
                    &host->header_host_signature.len,
                    "Server: %s", host->host_signature);

    mk_list_add(&host->_head, &config->hosts);
}
