
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>


static int ngx_http_static_handler(ngx_http_request_t *r);
static int ngx_http_static_init(ngx_cycle_t *cycle);


static ngx_command_t  ngx_http_static_commands[] = {

    ngx_null_command
};



ngx_http_module_t  ngx_http_static_module_ctx = {
    NULL,                                  /* create main configuration */
    NULL,                                  /* init main configuration */
    
    NULL,                                  /* create server configuration */
    NULL,                                  /* merge server configuration */
    
    NULL,                                  /* create location configuration */
    NULL                                   /* merge location configuration */
};  


ngx_module_t  ngx_http_static_module = {
    NGX_MODULE,
    &ngx_http_static_module_ctx,           /* module context */
    ngx_http_static_commands,              /* module directives */
    NGX_HTTP_MODULE,                       /* module type */
    ngx_http_static_init,                  /* init module */
    NULL                                   /* init child */
};


int ngx_http_static_translate_handler(ngx_http_request_t *r)
{
    char                      *location, *last;
    ngx_err_t                  err;
    ngx_table_elt_t           *h;
    ngx_http_core_loc_conf_t  *clcf;

    if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
        return NGX_HTTP_NOT_ALLOWED;
    }

    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

    if (r->uri.data[r->uri.len - 1] == '/') {
        if (r->path.data == NULL) {
            ngx_test_null(r->path.data,
                          ngx_palloc(r->pool,
                                     clcf->doc_root.len + r->uri.len),
                          NGX_HTTP_INTERNAL_SERVER_ERROR);

            ngx_cpystrn(ngx_cpymem(r->path.data, clcf->doc_root.data,
                                   clcf->doc_root.len),
                        r->uri.data, r->uri.len + 1);

        } else {
            r->path.data[r->path.len] = '\0';
        }

        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "directory index of \"%s\" is forbidden", r->path.data);

        return NGX_HTTP_FORBIDDEN;
    }

    /* "+ 2" is for trailing '/' in redirect and '\0' */
    ngx_test_null(r->file.name.data,
                  ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len + 2),
                  NGX_HTTP_INTERNAL_SERVER_ERROR);

    location = ngx_cpymem(r->file.name.data, clcf->doc_root.data,
                          clcf->doc_root.len),

    last = ngx_cpystrn(location, r->uri.data, r->uri.len + 1);

ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data);

#if (WIN9X)

    /*
     * There is no way to open a file or a directory in Win9X with
     * one syscall: Win9X has no FILE_FLAG_BACKUP_SEMANTICS flag.
     * so we need to check its type before the opening
     */

    r->file.info.dwFileAttributes = GetFileAttributes(r->file.name.data);
    if (r->file.info.dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
        err = ngx_errno;
        ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
                      ngx_file_type_n " \"%s\" failed", r->file.name.data);

        if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
            return NGX_HTTP_NOT_FOUND;

        } else if (err == NGX_EACCES) {
            return NGX_HTTP_FORBIDDEN;

        } else {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }
    }

#else

    if (r->file.fd == NGX_INVALID_FILE) {
        r->file.fd = ngx_open_file(r->file.name.data,
                                   NGX_FILE_RDONLY, NGX_FILE_OPEN);
    }

    if (r->file.fd == NGX_INVALID_FILE) {
        err = ngx_errno;
        ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
                      ngx_open_file_n " \"%s\" failed", r->file.name.data);

        if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
            return NGX_HTTP_NOT_FOUND;

        } else if (err == NGX_EACCES) {
            return NGX_HTTP_FORBIDDEN;

        } else {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }
    }

ngx_log_debug(r->connection->log, "FILE: %d" _ r->file.fd);

    if (!r->file.info_valid) {
        if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
                          ngx_stat_fd_n " \"%s\" failed", r->file.name.data);

            if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
                ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
                              ngx_close_file_n " \"%s\" failed",
                              r->file.name.data);
            }

            r->file.fd = NGX_INVALID_FILE;

            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        r->file.info_valid = 1;
    }
#endif

    if (ngx_is_dir(r->file.info)) {
ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data);

#if !(WIN9X)
        if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
                          ngx_close_file_n " \"%s\" failed", r->file.name.data);
        }

        r->file.fd = NGX_INVALID_FILE;
#endif

        ngx_test_null(h, ngx_push_table(r->headers_out.headers),
                      NGX_HTTP_INTERNAL_SERVER_ERROR);

        *last++ = '/';
        *last = '\0';
        h->key.len = 8;
        h->key.data = "Location" ;
        h->value.len = last - location;
        h->value.data = location;
        r->headers_out.location = h;

        return NGX_HTTP_MOVED_PERMANENTLY;
    }

    r->content_handler = ngx_http_static_handler;

    return NGX_OK;
}


static int ngx_http_static_handler(ngx_http_request_t *r)
{
    int                        rc, key, i;
    ngx_log_e                  level;
    ngx_err_t                  err;
    ngx_hunk_t                *h;
    ngx_chain_t                out;
    ngx_http_type_t           *type;
    ngx_http_log_ctx_t        *ctx;
    ngx_http_core_loc_conf_t  *clcf;

    rc = ngx_http_discard_body(r);

    if (rc != NGX_OK) {
        return rc;
    }

    ctx = r->connection->log->data;
    ctx->action = "sending response";

    if (r->file.fd == NGX_INVALID_FILE) {
        r->file.fd = ngx_open_file(r->file.name.data,
                                   NGX_FILE_RDONLY, NGX_FILE_OPEN);

        if (r->file.fd == NGX_INVALID_FILE) {
            err = ngx_errno;

            if (err == NGX_ENOENT || err == NGX_ENOTDIR) {
                level = NGX_LOG_ERR;
                rc = NGX_HTTP_NOT_FOUND;

            } else {
                level = NGX_LOG_CRIT;
                rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
            }

            ngx_log_error(level, r->connection->log, ngx_errno,
                          ngx_open_file_n " %s failed", r->file.name.data);
            return rc;
        }
    }

    if (!r->file.info_valid) {
        if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
                          ngx_stat_fd_n " %s failed", r->file.name.data);

            if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR)
                ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
                              ngx_close_file_n " %s failed", r->file.name.data);

            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        r->file.info_valid = 1;
    }

#if !(WIN32) /* the not regular files are probably Unix specific */

    if (!ngx_is_file(r->file.info)) {
        ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
                      "%s is not regular file", r->file.name.data);

        if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR)
            ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
                          ngx_close_file_n " %s failed", r->file.name.data);

        return NGX_HTTP_NOT_FOUND;
    }

#endif

    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = ngx_file_size(r->file.info);
    r->headers_out.last_modified_time = ngx_file_mtime(r->file.info);

    ngx_test_null(r->headers_out.content_type,
                  ngx_push_table(r->headers_out.headers),
                  NGX_HTTP_INTERNAL_SERVER_ERROR);

    r->headers_out.content_type->key.len = 0;
    r->headers_out.content_type->key.data = NULL;
    r->headers_out.content_type->value.len = 0;
    r->headers_out.content_type->value.data = NULL;

    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

    if (r->exten.len) {
        ngx_http_types_hash_key(key, r->exten);

        type = (ngx_http_type_t *) clcf->types[key].elts;
        for (i = 0; i < clcf->types[key].nelts; i++) {
            if (r->exten.len != type[i].exten.len) {
                continue;
            }

            if (ngx_strcasecmp(r->exten.data, type[i].exten.data) == 0) {
                r->headers_out.content_type->value.len = type[i].type.len;
                r->headers_out.content_type->value.data = type[i].type.data;

                break;
            }
        }
    }

    if (r->headers_out.content_type->value.len == 0) {
        r->headers_out.content_type->value.len = clcf->default_type.len;
        r->headers_out.content_type->value.data = clcf->default_type.data;
    }

    /* we need to allocate all before the header would be sent */

    ngx_test_null(h, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)),
                  NGX_HTTP_INTERNAL_SERVER_ERROR);

    ngx_test_null(h->file, ngx_pcalloc(r->pool, sizeof(ngx_file_t)),
                  NGX_HTTP_INTERNAL_SERVER_ERROR);


    rc = ngx_http_send_header(r);

    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        return rc;
    }

    h->type = r->main ? NGX_HUNK_FILE : NGX_HUNK_FILE|NGX_HUNK_LAST;

    h->file_pos = 0;
    h->file_last = ngx_file_size(r->file.info);

    h->file->fd = r->file.fd;
    h->file->log = r->connection->log;

    out.hunk = h;
    out.next = NULL;

    return ngx_http_output_filter(r, &out);
}


static int ngx_http_static_init(ngx_cycle_t *cycle)
{
    ngx_http_handler_pt        *h;
    ngx_http_conf_ctx_t        *ctx;
    ngx_http_core_main_conf_t  *cmcf;
    
    ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index];
    cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
    
    ngx_test_null(h, ngx_push_array(
                             &cmcf->phases[NGX_HTTP_TRANSLATE_PHASE].handlers),
                  NGX_ERROR);
    *h = ngx_http_static_translate_handler;

    return NGX_OK;
}

