
#include <ngx_config.h>
#include <ngx_string.h>
#include <ngx_file.h>
#include <ngx_hunk.h>
#include <ngx_http.h>

ngx_http_module_t  ngx_http_static_module;


#if 0
/* STUB */
static ngx_http_static_ctx_t module_ctx;

void ngx_http_static_init()
{
     module_ctx.out = NULL;

     ngx_http_static_module.ctx = &module_ctx;
}
/* */
#endif


int ngx_http_static_handler(ngx_http_request_t *r)
{
    int  rc;
    ngx_err_t    err;
    ngx_hunk_t  *h;
    ngx_http_log_ctx_t  *ctx;

#if 0
    ngx_http_event_static_handler_loc_conf_t  *cf;

    cf = (ngx_http_event_static_handler_loc_conf_t *)
             ngx_get_module_loc_conf(r, &ngx_http_event_static_handler_module);

#endif

    ngx_http_discard_body(r);
    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);

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

        if (err == NGX_ENOENT)
            return NGX_HTTP_NOT_FOUND;
#if (WIN32)
        else if (err == ERROR_PATH_NOT_FOUND)
            return NGX_HTTP_NOT_FOUND;
#endif
        else
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    if (!r->file.info_valid) {
        if (ngx_stat_fd(r->file.fd, &r->file.info) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
                          "ngx_http_static_handler: "
                          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_ERR, r->connection->log, ngx_errno,
                              "ngx_http_static_handler: "
                              ngx_close_file_n " %s failed", r->file.name.data);

            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        r->file.info_valid = 1;
    }

#if !(WIN32) /* it's probably Unix specific */

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

        if (ngx_close_file(r->file.fd) == NGX_FILE_ERROR)
            ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
                          "ngx_http_static_handler: "
                          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 = 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 = 12;
    r->headers_out.content_type->key.data = "Content-Type";

    /* STUB */
    if (r->exten.len) {
        if (strcasecmp(r->exten.data, "html") == 0) {
            r->headers_out.content_type->value.len = 25;
            r->headers_out.content_type->value.data =
                                                   "text/html; charset=koi8-r";
        } else if (strcasecmp(r->exten.data, "gif") == 0) {
            r->headers_out.content_type->value.len = 9;
            r->headers_out.content_type->value.data = "image/gif";
        } else if (strcasecmp(r->exten.data, "jpg") == 0) {
            r->headers_out.content_type->value.len = 10;
            r->headers_out.content_type->value.data = "image/jpeg";
        }

    } else {
        r->headers_out.content_type->value.len = 25;
        r->headers_out.content_type->value.data = "text/html; charset=koi8-r";
    }
    /**/

    /* we need to allocate them before 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 (r->header_only)
        return rc;

    h->type = NGX_HUNK_FILE|NGX_HUNK_LAST;
    h->pos.file = 0;
    h->last.file = ngx_file_size(r->file.info);

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

    rc = ngx_http_output_filter(r, h);

    ngx_log_debug(r->connection->log, "0 output_filter: %d" _ rc);

    return rc;
}
