
/*
 * Copyright (C) Igor Sysoev
 */


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


typedef struct {
    ngx_array_t              indices;
    size_t                   max_index_len;
    ngx_http_cache_hash_t   *index_cache;
} ngx_http_index_loc_conf_t;


typedef struct {
    ngx_uint_t               index;
    u_char                  *last;
    ngx_str_t                path;
    ngx_str_t                redirect;
    ngx_http_cache_entry_t  *cache;
    ngx_uint_t               tested; /* unsigned  tested:1 */
} ngx_http_index_ctx_t;


#define NGX_HTTP_DEFAULT_INDEX   "index.html"


static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
                                         ngx_http_index_ctx_t *ctx);
static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
                                      ngx_http_index_ctx_t *ctx, ngx_err_t err);

static ngx_int_t ngx_http_index_init(ngx_cycle_t *cycle);
static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_index_merge_loc_conf(ngx_conf_t *cf,
                                       void *parent, void *child);
static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
                                      void *conf);


static ngx_command_t  ngx_http_index_commands[] = {

    { ngx_string("index"),
      NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
      ngx_http_index_set_index,
      NGX_HTTP_LOC_CONF_OFFSET,
      0,
      NULL },

#if (NGX_HTTP_CACHE)

    { ngx_string("index_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_index_loc_conf_t, index_cache),
      NULL },

#endif

      ngx_null_command
};


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

    NULL,                                  /* create main configuration */
    NULL,                                  /* init main configuration */

    NULL,                                  /* create server configuration */
    NULL,                                  /* merge server configuration */

    ngx_http_index_create_loc_conf,        /* create location configration */
    ngx_http_index_merge_loc_conf          /* merge location configration */
};


ngx_module_t  ngx_http_index_module = {
    NGX_MODULE,
    &ngx_http_index_module_ctx,            /* module context */
    ngx_http_index_commands,               /* module directives */
    NGX_HTTP_MODULE,                       /* module type */
    ngx_http_index_init,                   /* init module */
    NULL                                   /* init process */
};


/*
 * Try to open the first index file before the test of the directory existence
 * because the valid requests should be many more than invalid ones.
 * If open() would fail, then stat() should be more quickly because some data
 * is already cached in the kernel.
 * Besides, Win32 has ERROR_PATH_NOT_FOUND (NGX_ENOTDIR).
 * Unix has ENOTDIR error, although it less helpfull - it points only
 * that path contains the usual file in place of the directory.
 */

static ngx_int_t ngx_http_index_handler(ngx_http_request_t *r)
{
    u_char                     *name;
    ngx_fd_t                    fd;
    ngx_int_t                   rc;
    ngx_str_t                  *index;
    ngx_err_t                   err;
    ngx_log_t                  *log;
    ngx_http_index_ctx_t       *ctx;
    ngx_http_core_loc_conf_t   *clcf;
    ngx_http_index_loc_conf_t  *ilcf;
#if (NGX_HTTP_CACHE0)
    /* crc must be in ctx !! */
    uint32_t                    crc;
#endif

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

    /* TODO: Win32 */
    if (r->zero_in_uri) {
        return NGX_DECLINED;
    }

    log = r->connection->log;

    /*
     * we use context because the handler supports an async file opening
     * and thus can be called several times
     */

    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
    ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);

    ctx = ngx_http_get_module_ctx(r, ngx_http_index_module);
    if (ctx == NULL) {

        ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_index_ctx_t));
        if (ctx == NULL) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        ngx_http_set_ctx(r, ctx, ngx_http_index_module);

#if (NGX_HTTP_CACHE)

        if (ilcf->index_cache) {
            ctx->cache = ngx_http_cache_get(ilcf->index_cache, NULL,
                                            &r->uri, &crc);

            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
                           "http index cache get: %p", ctx->cache);

            if (ctx->cache && !ctx->cache->expired) {

                ctx->cache->accessed = ngx_cached_time;

                ctx->redirect.len = ctx->cache->data.value.len;
                ctx->redirect.data = ngx_palloc(r->pool, ctx->redirect.len + 1);
                if (ctx->redirect.data == NULL) {
                    ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);
                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
                }

                ngx_memcpy(ctx->redirect.data, ctx->cache->data.value.data,
                           ctx->redirect.len + 1);
                ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);

                return ngx_http_internal_redirect(r, &ctx->redirect, NULL);
            }
        }

#endif

#if 0
        ctx->path.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len
                                             + ilcf->max_index_len
                                             - clcf->alias * clcf->name.len);
        if (ctx->path.data == NULL) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        ctx->redirect.data = ngx_cpymem(ctx->path.data, clcf->root.data,
                                        clcf->root.len);
#endif

        if (clcf->alias) {
            ctx->path.data = ngx_palloc(r->pool, clcf->root.len
                                              + r->uri.len + 1 - clcf->name.len
                                              + ilcf->max_index_len);
            if (ctx->path.data == NULL) {
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
            }

            ctx->redirect.data = ngx_palloc(r->pool, r->uri.len
                                            + ilcf->max_index_len);
            if (ctx->redirect.data == NULL) {
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
            }

            ngx_memcpy(ctx->path.data, clcf->root.data, clcf->root.len);

            ctx->last = ngx_cpystrn(ctx->path.data + clcf->root.len,
                                    r->uri.data + clcf->name.len,
                                    r->uri.len + 1 - clcf->name.len);

#if 0
            /*
             * aliases usually have trailling "/",
             * set it in the start of the possible redirect
             */

            if (*ctx->redirect.data != '/') {
                ctx->redirect.data--; 
            }
#endif

        } else {
            ctx->path.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len
                                                 + ilcf->max_index_len);
            if (ctx->path.data == NULL) {
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
            }

            ctx->redirect.data = ngx_cpymem(ctx->path.data, clcf->root.data,
                                            clcf->root.len);

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

    ctx->path.len = ctx->last - ctx->path.data;

    index = ilcf->indices.elts;
    for (/* void */; ctx->index < ilcf->indices.nelts; ctx->index++) {

        if (index[ctx->index].data[0] == '/') {
            name = index[ctx->index].data;

        } else {
            ngx_memcpy(ctx->last, index[ctx->index].data,
                       index[ctx->index].len + 1);
            name = ctx->path.data;
        }

        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
                       "open index \"%s\"", name);

        fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN);

        if (fd == (ngx_fd_t) NGX_AGAIN) {
            return NGX_AGAIN;
        }

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

            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, err,
                           ngx_open_file_n " \"%s\" failed", name);

            if (err == NGX_ENOTDIR) {
                return ngx_http_index_error(r, ctx, err);

            } else if (err == NGX_EACCES) {
                return ngx_http_index_error(r, ctx, err);
            }

            if (!ctx->tested) {
                rc = ngx_http_index_test_dir(r, ctx);

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

                ctx->tested = 1;
            }

            if (err == NGX_ENOENT) {
                continue;
            }

            ngx_log_error(NGX_LOG_ERR, log, err,
                          ngx_open_file_n " \"%s\" failed", name);

            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }


        /* STUB: open file cache */

        r->file.name.data = name;
        r->file.fd = fd;

        if (index[ctx->index].data[0] == '/') {
            r->file.name.len = index[ctx->index].len;
            ctx->redirect.len = index[ctx->index].len;
            ctx->redirect.data = index[ctx->index].data;

        } else {
            if (clcf->alias) {
                name = ngx_cpymem(ctx->redirect.data, r->uri.data, r->uri.len);
                ngx_memcpy(name, index[ctx->index].data,
                           index[ctx->index].len + 1);
            }

            ctx->redirect.len = r->uri.len + index[ctx->index].len;
            r->file.name.len = clcf->root.len + r->uri.len
                                                - clcf->alias * clcf->name.len
                                                       + index[ctx->index].len;
        }

        /**/


#if (NGX_HTTP_CACHE)

        if (ilcf->index_cache) {

            if (ctx->cache) {
                if (ctx->redirect.len == ctx->cache->data.value.len
                    && ngx_memcmp(ctx->cache->data.value.data,
                                  ctx->redirect.data, ctx->redirect.len) == 0)
                {
                    ctx->cache->accessed = ngx_cached_time;
                    ctx->cache->updated = ngx_cached_time;
                    ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);

                    return ngx_http_internal_redirect(r, &ctx->redirect, NULL);
                }
            }

            ctx->redirect.len++;
            ctx->cache = ngx_http_cache_alloc(ilcf->index_cache, ctx->cache,
                                              NULL, &r->uri, crc,
                                              &ctx->redirect, log);
            ctx->redirect.len--;

            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
                           "http index cache alloc: %p", ctx->cache);

            if (ctx->cache) {
                ctx->cache->fd = NGX_INVALID_FILE;
                ctx->cache->accessed = ngx_cached_time;
                ctx->cache->last_modified = 0;
                ctx->cache->updated = ngx_cached_time;
                ctx->cache->memory = 1;
                ngx_http_cache_unlock(ilcf->index_cache, ctx->cache, log);
            }
        }

#endif

        return ngx_http_internal_redirect(r, &ctx->redirect, NULL);
    }

    return NGX_DECLINED;
}


static ngx_int_t ngx_http_index_test_dir(ngx_http_request_t *r,
                                         ngx_http_index_ctx_t *ctx)
{
    ngx_err_t  err;

    ctx->path.data[ctx->path.len - 1] = '\0';
    ctx->path.data[ctx->path.len] = '\0';

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "http check dir: \"%s\"", ctx->path.data);

    if (ngx_file_info(ctx->path.data, &r->file.info) == -1) {

        err = ngx_errno;

        if (err == NGX_ENOENT) {
            ctx->path.data[ctx->path.len - 1] = '/';
            return ngx_http_index_error(r, ctx, err);
        }

        ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
                      ngx_file_info_n " \"%s\" failed", ctx->path.data);

        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    ctx->path.data[ctx->path.len - 1] = '/';

    if (ngx_is_dir(&r->file.info)) {
        return NGX_OK;
    }

    /* THINK: not reached ??? */
    return ngx_http_index_error(r, ctx, 0);
}


static ngx_int_t ngx_http_index_error(ngx_http_request_t *r,
                                      ngx_http_index_ctx_t *ctx, ngx_err_t err)
{
    if (err == NGX_EACCES) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
                      "\"%s\" is forbidden", ctx->path.data);
    
        return NGX_HTTP_FORBIDDEN;
    }

    ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
                  "\"%s\" is not found", ctx->path.data);
    return NGX_HTTP_NOT_FOUND;
}


static ngx_int_t ngx_http_index_init(ngx_cycle_t *cycle)
{
    ngx_http_handler_pt        *h;
    ngx_http_core_main_conf_t  *cmcf;

    cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module);

    h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
    if (h == NULL) {
        return NGX_ERROR;
    }

    *h = ngx_http_index_handler;

    return NGX_OK;
}


static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf)
{
    ngx_http_index_loc_conf_t  *conf;

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

    if (ngx_array_init(&conf->indices, cf->pool, 2, sizeof(ngx_str_t))
                                                                  == NGX_ERROR)
    {
        return NGX_CONF_ERROR;
    }

    conf->max_index_len = 0;

    conf->index_cache = NULL;

    return conf;
}


/* TODO: remove duplicate indices */

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

    ngx_str_t  *index;

    if (conf->max_index_len == 0) {
        if (prev->max_index_len != 0) {
            ngx_memcpy(conf, prev, sizeof(ngx_http_index_loc_conf_t));
            return NGX_CONF_OK;
        }

        index = ngx_array_push(&conf->indices);
        if (index == NULL) {
            return NGX_CONF_ERROR;
        }

        index->len = sizeof(NGX_HTTP_DEFAULT_INDEX) - 1;
        index->data = (u_char *) NGX_HTTP_DEFAULT_INDEX;
        conf->max_index_len = sizeof(NGX_HTTP_DEFAULT_INDEX);

        return NGX_CONF_OK;
    }

#if 0

    if (prev->max_index_len != 0) {

        prev_index = prev->indices.elts;
        for (i = 0; i < prev->indices.nelts; i++) {
            index = ngx_array_push(&conf->indices);
            if (index == NULL) {
                return NGX_CONF_ERROR;
            }

            index->len = prev_index[i].len;
            index->data = prev_index[i].data;
        }
    }

    if (conf->max_index_len < prev->max_index_len) {
        conf->max_index_len = prev->max_index_len;
    }

#endif

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

    return NGX_CONF_OK;
}


/* TODO: warn about duplicate indices */

static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
                                      void *conf)
{
    ngx_http_index_loc_conf_t *ilcf = conf;

    ngx_uint_t  i;
    ngx_str_t  *index, *value;

    value = cf->args->elts;

    if (value[1].data[0] == '/' && ilcf->indices.nelts == 0) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "first index \"%V\" in \"%V\" directive "
                           "must not be absolute",
                           &value[1], &cmd->name);
        return NGX_CONF_ERROR;
    }

    for (i = 1; i < cf->args->nelts; i++) {
        if (value[i].len == 0) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "index \"%V\" in \"%V\" directive is invalid",
                               &value[1], &cmd->name);
            return NGX_CONF_ERROR;
        }

        index = ngx_array_push(&ilcf->indices);
        if (index == NULL) {
            return NGX_CONF_ERROR;
        }

        index->len = value[i].len;
        index->data = value[i].data;

        if (ilcf->max_index_len < index->len + 1) {
            ilcf->max_index_len = index->len + 1;
        }
    }

    return NGX_CONF_OK;
}
