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


typedef struct {
    ngx_http_cache_hash_t  *redirect_cache;
} ngx_http_static_loc_conf_t;


static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r);
static void *ngx_http_static_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf,
                                            void *parent, void *child);
static ngx_int_t ngx_http_static_init(ngx_cycle_t *cycle);


static ngx_command_t  ngx_http_static_commands[] = {

    { ngx_string("redirect_cache"),
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE3,
      ngx_http_set_cache_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_static_loc_conf_t, redirect_cache),
      NULL },

      ngx_null_command
};



ngx_http_module_t  ngx_http_static_module_ctx = {
    NULL,                                  /* pre conf */

    NULL,                                  /* create main configuration */
    NULL,                                  /* init main configuration */
    
    NULL,                                  /* create server configuration */
    NULL,                                  /* merge server configuration */
    
    ngx_http_static_create_loc_conf,       /* create location configuration */
    ngx_http_static_merge_loc_conf         /* 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 */
};


static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r)
{
    char                        *last;
    uint32_t                     file_crc, redirect_crc;
    ngx_fd_t                     fd;
    ngx_int_t                    rc, level;
    ngx_str_t                    name, location;
    ngx_err_t                    err;
    ngx_log_t                   *log;
    ngx_hunk_t                  *h;
    ngx_chain_t                  out;
    ngx_file_info_t              fi;
    ngx_http_cache_t            *file, *redirect;
    ngx_http_cleanup_t          *file_cleanup, *redirect_cleanup;
    ngx_http_log_ctx_t          *ctx;
    ngx_http_core_loc_conf_t    *clcf;
    ngx_http_static_loc_conf_t  *slcf;

    if (r->uri.data[r->uri.len - 1] == '/') {
        return NGX_DECLINED;
    }

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

    rc = ngx_http_discard_body(r);

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

    /*
     * there is a valid cached open file, i.e by index handler,
     * and it must be already registered in r->cleanup
     */

    if (r->cache && r->cache->valid) {
        return ngx_http_send_cached(r);
    }

    log = r->connection->log;

    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

    /*
     * make a file name
     * 2 bytes is for a trailing '/' in a possible redirect and for '\0'
     */

    ngx_test_null(name.data,
                  ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len + 2),
                  NGX_HTTP_INTERNAL_SERVER_ERROR);

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

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
                   "http filename: \"%s\"", name.data);


    /* allocate cleanups */

    if (!(file_cleanup = ngx_push_array(&r->cleanup))) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
    file_cleanup->valid = 0;

    slcf = ngx_http_get_module_loc_conf(r, ngx_http_static_module);
    if (slcf->redirect_cache) {
        if (!(redirect_cleanup = ngx_push_array(&r->cleanup))) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }
        redirect_cleanup->valid = 0;

    } else {
        redirect_cleanup = NULL;
    }


    /* look up an open files cache */

    if (clcf->open_files) {
        file = ngx_http_cache_get(clcf->open_files, file_cleanup,
                                  &name, &file_crc);

        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
                       "http open file cache get: " PTR_FMT, file);

        if (file && file->valid) {
            r->cache = file;
            return ngx_http_send_cached(r);
        }

    } else {
        file = NULL;
    }


    /* look up an redirect cache */

    if (slcf->redirect_cache) {
        redirect = ngx_http_cache_get(slcf->redirect_cache, redirect_cleanup,
                                      &name, &redirect_crc);

        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
                       "http redirect cache get: " PTR_FMT, redirect);

        if (redirect && redirect->valid) {

            /*
             * We do not copy a cached value so the cache entry is locked
             * until the end of the request.  In a single threaded model
             * the redirected request should complete before other event
             * will be processed.  In a multithreaded model this locking
             * should keep more popular redirects in cache.
             */

            if (!(r->headers_out.location =
                   ngx_http_add_header(&r->headers_out, ngx_http_headers_out)))
            {
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
            }

            r->headers_out.location->value = redirect->data.value;

            return NGX_HTTP_MOVED_PERMANENTLY;
        }

    } else {
        redirect = NULL;
    }


    /* open file */

#if (WIN9X)

    /* TODO: redirect cache */

    if (ngx_win32_version < NGX_WIN_NT) {

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

        if (ngx_file_info(name.data, &fi) == NGX_FILE_ERROR) {
            err = ngx_errno;
            ngx_log_error(NGX_LOG_ERR, log, err,
                          ngx_file_info_n " \"%s\" failed", 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;
            }
        }

        if (ngx_is_dir(&fi)) {
            ngx_log_debug(log, "HTTP DIR: '%s'" _ name.data);

            if (!(r->headers_out.location =
                   ngx_http_add_header(&r->headers_out, ngx_http_headers_out)))
            {
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
            }

            *last++ = '/';
            *last = '\0';
            r->headers_out.location->value.len = last - location;
            r->headers_out.location->value.data = location;

            return NGX_HTTP_MOVED_PERMANENTLY;
        }
    }

#endif


    fd = ngx_open_file(name.data, NGX_FILE_RDONLY, NGX_FILE_OPEN);

    if (fd == NGX_INVALID_FILE) {
        err = ngx_errno;

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

        } else if (err == NGX_EACCES) {
            level = NGX_LOG_ERR;
            rc = NGX_HTTP_FORBIDDEN;

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

        ngx_log_error(level, log, err,
                      ngx_open_file_n " \"%s\" failed", name.data);

        return rc;
    }

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", fd);

    if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
        ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
                      ngx_fd_info_n " \"%s\" failed", name.data);

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

        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    if (ngx_is_dir(&fi)) {

        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http dir");

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

        *last++ = '/';
        *last = '\0';

        if (!(r->headers_out.location =
                   ngx_http_add_header(&r->headers_out, ngx_http_headers_out)))
        {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        r->headers_out.location->value = location;

        if (slcf->redirect_cache) {
            if (redirect) {
                if (location.len == redirect->data.value.len
                    && ngx_memcmp(redirect->data.value.data, location.data,
                                                            location.len) == 0)
                {
                    redirect->accessed = ngx_cached_time;
                    redirect->updated = ngx_cached_time;

                    /*
                     * we can unlock the cache entry because
                     * we have the local copy anyway
                     */

                    ngx_http_cache_unlock(slcf->redirect_cache, redirect, log);
                    redirect_cleanup->valid = 0;

                    return NGX_HTTP_MOVED_PERMANENTLY;
                }
            }

            location.len++;
            redirect = ngx_http_cache_alloc(slcf->redirect_cache, redirect,
                                            redirect_cleanup,
                                            &name, redirect_crc,
                                            &location, log);
            location.len--;

            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
                           "http redirect cache alloc: " PTR_FMT, redirect);

            if (redirect) {
                redirect->fd = NGX_INVALID_FILE;
                redirect->accessed = ngx_cached_time;
                redirect->last_modified = 0;
                redirect->updated = ngx_cached_time;
                redirect->valid = 1;
                redirect->memory = 1;
                ngx_http_cache_unlock(slcf->redirect_cache, redirect, log);
                redirect_cleanup->valid = 0;
            }

        }

        return NGX_HTTP_MOVED_PERMANENTLY;
    }

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

    if (!ngx_is_file(&fi)) {
        ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
                      "%s is not a regular file", name.data);

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

        return NGX_HTTP_NOT_FOUND;
    }

#endif


    if (clcf->open_files) {

#if (NGX_USE_HTTP_FILE_CACHE_UNIQ)

        if (file && file->uniq == ngx_file_uniq(&fi)) {
            if (ngx_close_file(fd) == NGX_FILE_ERROR) {
                ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                              ngx_close_file_n " \"%s\" failed", name.data);
            }
            file->accessed = ngx_cached_time;
            file->updated = ngx_cached_time;
            file->valid = 1;
            r->cache = file;

            return ngx_http_send_cached(r);

        } else {
            if (file) {
                ngx_http_cache_unlock(clcf->open_files, file, log);
                file = NULL;
            }

            file = ngx_http_cache_alloc(clcf->open_files, file,
                                        file_cleanup,
                                        &name, file_crc, NULL, log);
            if (file) {
                file->uniq = ngx_file_uniq(&fi);
            }
        }

#else
        file = ngx_http_cache_alloc(clcf->open_files, file,
                                    file_cleanup,
                                    &name, file_crc, NULL, log);
#endif

        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
                       "http open file cache alloc: " PTR_FMT, file);

        if (file) {
            file->fd = fd;
            file->data.size = ngx_file_size(&fi);
            file->accessed = ngx_cached_time;
            file->last_modified = ngx_file_mtime(&fi);
            file->updated = ngx_cached_time;
            file->valid = 1;
            r->cache = file;
        }

        return ngx_http_send_cached(r);
    }


    ctx = log->data;
    ctx->action = "sending response to client";

    file_cleanup->data.file.fd = fd;
    file_cleanup->data.file.name = name.data;
    file_cleanup->valid = 1;
    file_cleanup->cache = 0;

    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = ngx_file_size(&fi);
    r->headers_out.last_modified_time = ngx_file_mtime(&fi);

    if (ngx_http_set_content_type(r) != NGX_OK) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }


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

    if (!(h = ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)))) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    if (!(h->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t)))) {
        return 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(&fi);

    h->file->fd = fd;
    h->file->log = log;

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

    return ngx_http_output_filter(r, &out);
}


static void *ngx_http_static_create_loc_conf(ngx_conf_t *cf)
{
    ngx_http_static_loc_conf_t  *conf;

    if (!(conf = ngx_palloc(cf->pool, sizeof(ngx_http_static_loc_conf_t)))) {
        return NGX_CONF_ERROR;
    }

    conf->redirect_cache = NULL;

    return conf;
}


static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf,
                                            void *parent, void *child)
{
    ngx_http_static_loc_conf_t  *prev = parent;
    ngx_http_static_loc_conf_t  *conf = child;

    if (conf->redirect_cache == NULL) {
        conf->redirect_cache = prev->redirect_cache;
    }

    return NGX_CONF_OK;
}


static ngx_int_t 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];
    
    h = ngx_push_array(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
    if (h == NULL) {
        return NGX_ERROR;
    }

    *h = ngx_http_static_handler;

    return NGX_OK;
}
