# HG changeset patch # User Igor Sysoev # Date 1042178960 0 # Node ID f1ee46c036a4a8c3df1bd6e39222a3d450a0ae71 # Parent 0e81ac0bb3e214ea6cc48888c82810f62978c946 nginx-0.0.1-2003-01-10-09:09:20 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -3,6 +3,7 @@ #include +#include #include #include #include @@ -41,6 +42,7 @@ ngx_array_t ngx_listening_sockets; int main(int argc, char *const *argv) { + int i; ngx_str_t conf_file; ngx_conf_t conf; @@ -70,9 +72,18 @@ int main(int argc, char *const *argv) conf_file.data = "nginx.conf"; if (ngx_conf_parse(&conf, &conf_file) != NGX_CONF_OK) { - exit(1); + return 1; } + for (i = 0; ngx_modules[i]; i++) { + if (ngx_modules[i]->init_module) { + if (ngx_modules[i]->init_module(ngx_pool) == NGX_ERROR) { + return 1; + } + } + } + + #if 0 /* STUB */ /* TODO: init chain of global modules (like ngx_http.c), diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -83,7 +83,7 @@ ngx_log_debug(cf->log, "token %d" _ rc); found = 0; for (i = 0; !found && ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NULL + if (ngx_modules[i]->type != NGX_CONF_MODULE_TYPE && ngx_modules[i]->type != cf->type) { continue; diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h --- a/src/core/ngx_conf_file.h +++ b/src/core/ngx_conf_file.h @@ -31,6 +31,7 @@ #define NGX_CORE_MODULE_TYPE 0x45524f43 /* "CORE" */ +#define NGX_CONF_MODULE_TYPE 0x464E4f43 /* "CONF" */ typedef struct ngx_conf_s ngx_conf_t; diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -29,6 +29,7 @@ typedef struct { #define ngx_memzero bzero +#define ngx_strcasecmp strcasecmp #define ngx_strncmp strncmp #define ngx_strcmp strcmp diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c --- a/src/http/modules/ngx_http_index_handler.c +++ b/src/http/modules/ngx_http_index_handler.c @@ -13,6 +13,7 @@ #include +static int ngx_http_index_init(ngx_pool_t *pool); static void *ngx_http_index_create_conf(ngx_pool_t *pool); static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child); @@ -55,13 +56,13 @@ ngx_module_t ngx_http_index_module = { &ngx_http_index_module_ctx, /* module context */ ngx_http_index_commands, /* module directives */ NGX_HTTP_MODULE_TYPE, /* module type */ - NULL /* init module */ + ngx_http_index_init /* init module */ }; int ngx_http_index_handler(ngx_http_request_t *r) { - int i; + int i, len; char *name, *file; ngx_str_t loc, *index; ngx_err_t err; @@ -76,19 +77,31 @@ int ngx_http_index_handler(ngx_http_requ core_cf = (ngx_http_core_loc_conf_t *) ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); - ngx_test_null(name, + ngx_test_null(r->path.data, ngx_palloc(r->pool, core_cf->doc_root.len + r->uri.len + cf->max_index_len), NGX_HTTP_INTERNAL_SERVER_ERROR); - loc.data = ngx_cpystrn(name, core_cf->doc_root.data, + loc.data = ngx_cpystrn(r->path.data, core_cf->doc_root.data, core_cf->doc_root.len + 1); file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1); + r->path.len = file - r->path.data; index = (ngx_str_t *) cf->indices->elts; for (i = 0; i < cf->indices->nelts; i++) { - ngx_memcpy(file, index[i].data, index[i].len + 1); + + if (index[i].data[0] != '/') { + if (!r->path_not_found) { + continue; + } + + ngx_memcpy(file, index[i].data, index[i].len + 1); + name = r->path.data; + + } else { + name = index[i].data; + } fd = ngx_open_file(name, NGX_FILE_RDONLY); if (fd == NGX_INVALID_FILE) { @@ -98,6 +111,12 @@ int ngx_http_index_handler(ngx_http_requ } #if (WIN32) if (err == ERROR_PATH_NOT_FOUND) { + r->path_not_found = 1; + continue; + } +#else + if (err == NGX_ENOTDIR) { + r->path_not_found = 1; continue; } #endif @@ -108,11 +127,20 @@ int ngx_http_index_handler(ngx_http_requ return NGX_HTTP_INTERNAL_SERVER_ERROR; } - r->file.name.len = core_cf->doc_root.len + r->uri.len + index[i].len; r->file.name.data = name; r->file.fd = fd; - loc.len = r->uri.len + index[i].len; + if (index[i].data[0] == '/') { + r->file.name.len = index[i].len; + loc.len = index[i].len; + loc.data = index[i].data; + + } else { + loc.len = r->uri.len + index[i].len; + r->file.name.len = core_cf->doc_root.len + r->uri.len + + index[i].len; + } + return ngx_http_internal_redirect(r, loc); } @@ -120,6 +148,18 @@ int ngx_http_index_handler(ngx_http_requ } +static int ngx_http_index_init(ngx_pool_t *pool) +{ + ngx_http_handler_pt *h; + + ngx_test_null(h, ngx_push_array(&ngx_http_index_handlers), NGX_ERROR); + + *h = ngx_http_index_handler; + + return NGX_OK; +} + + static void *ngx_http_index_create_conf(ngx_pool_t *pool) { ngx_http_index_conf_t *conf; diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -107,17 +107,17 @@ int ngx_http_static_handler(ngx_http_req /* STUB */ if (r->exten.len) { - if (strcasecmp(r->exten.data, "html") == 0) { + if (ngx_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) { + } else if (ngx_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) { + } else if (ngx_strcasecmp(r->exten.data, "jpg") == 0) { r->headers_out.content_type->value.len = 10; r->headers_out.content_type->value.data = "image/jpeg"; - } else if (strcasecmp(r->exten.data, "pdf") == 0) { + } else if (ngx_strcasecmp(r->exten.data, "pdf") == 0) { r->headers_out.content_type->value.len = 15; r->headers_out.content_type->value.data = "application/pdf"; } diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -26,6 +26,10 @@ int ngx_http_lingering_timeout = 5000; int ngx_http_lingering_time = 30; /**/ + +ngx_array_t ngx_http_index_handlers; + + int (*ngx_http_top_header_filter) (ngx_http_request_t *r); @@ -117,6 +121,9 @@ static char *ngx_http_block(ngx_conf_t * if (rv != NGX_CONF_OK) return rv; + ngx_init_array(ngx_http_index_handlers, + cf->pool, 3, sizeof(ngx_http_handler_pt), NGX_CONF_ERROR); + ngx_http_init_filters(cf->pool, ngx_modules); #if 1 diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -37,6 +37,7 @@ #define NGX_HTTP_MOVED_TEMPORARILY 302 #define NGX_HTTP_NOT_MODIFIED 304 #define NGX_HTTP_BAD_REQUEST 400 +#define NGX_HTTP_FORBIDDEN 403 #define NGX_HTTP_NOT_FOUND 404 #define NGX_HTTP_REQUEST_URI_TOO_LARGE 414 #define NGX_HTTP_INTERNAL_SERVER_ERROR 500 @@ -106,13 +107,6 @@ typedef struct ngx_http_request_s ngx_ht struct ngx_http_request_s { ngx_file_t file; -#if 0 - ngx_str_t filename; - ngx_file_info_t fileinfo; - ngx_fd_t fd; - int filename_len; -#endif - void **ctx; void **srv_conf; void **loc_conf; @@ -145,6 +139,8 @@ struct ngx_http_request_s { ssize_t client_content_length; char *discarded_buffer; + ngx_str_t path; + unsigned keepalive:1; unsigned lingering_close:1; @@ -156,6 +152,7 @@ struct ngx_http_request_s { unsigned header_only:1; unsigned unusual_uri:1; /* URI is not started with '/' - "GET http://" */ unsigned complex_uri:1; /* URI with "/." or with "//" (WIN32) */ + unsigned path_not_found:1; int state; char *uri_start; @@ -180,6 +177,8 @@ typedef struct { } ngx_http_log_ctx_t; +typedef int (*ngx_http_handler_pt)(ngx_http_request_t *r); + typedef int (*ngx_http_output_header_filter_p)(ngx_http_request_t *r); typedef int (*ngx_http_output_body_filter_p) @@ -251,6 +250,9 @@ extern int ngx_http_lingering_timeout; extern int ngx_http_lingering_time; +extern ngx_array_t ngx_http_index_handlers; + + extern ngx_http_module_t *ngx_http_modules[]; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -11,16 +11,16 @@ #if 0 #include #include -#include #endif /* STUB */ #include int ngx_http_static_handler(ngx_http_request_t *r); -int ngx_http_index_handler(ngx_http_request_t *r); int ngx_http_proxy_handler(ngx_http_request_t *r); /**/ +static int ngx_http_core_index_handler(ngx_http_request_t *r); + static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, @@ -173,9 +173,7 @@ ngx_log_debug(r->connection->log, "trans } if (r->uri.data[r->uri.len - 1] == '/') { - /* TODO: find index handler */ - /* STUB */ r->handler = ngx_http_index_handler; - + r->handler = ngx_http_core_index_handler; return NGX_OK; } @@ -234,6 +232,9 @@ ngx_log_debug(r->connection->log, "trans #if (WIN32) } else if (err == ERROR_PATH_NOT_FOUND) { return NGX_HTTP_NOT_FOUND; +#else + } else if (err == NGX_ENOTDIR) { + return NGX_HTTP_NOT_FOUND; #endif } else { return NGX_HTTP_INTERNAL_SERVER_ERROR; @@ -293,6 +294,62 @@ ngx_log_debug(r->connection->log, "trans } +static int ngx_http_core_index_handler(ngx_http_request_t *r) +{ + int i, rc; + ngx_err_t err; + ngx_http_handler_pt *h; + + h = (ngx_http_handler_pt *) ngx_http_index_handlers.elts; + for (i = 0; i < ngx_http_index_handlers.nelts; i++) { + rc = h[i](r); + + if (rc != NGX_DECLINED) { + return rc; + } + } + +#if (WIN32) + + if (r->path_not_found) { + return NGX_HTTP_NOT_FOUND; + + } else { + return NGX_HTTP_FORBIDDEN; + } + +#else + + if (r->path_not_found) { + return NGX_HTTP_NOT_FOUND; + } + + r->path.data[r->path.len] = '\0'; + if (stat(r->path.data, &r->file.info) == -1) { + + err = ngx_errno; + if (err == NGX_ENOENT) { + return NGX_HTTP_NOT_FOUND; + } + + ngx_log_error(NGX_LOG_ERR, r->connection->log, err, + "ngx_http_core_index_handler: " + "stat() %s failed", r->path.data); + + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + if (ngx_is_dir(r->file.info)) { + return NGX_HTTP_FORBIDDEN; + + } else { + return NGX_HTTP_NOT_FOUND; + } + +#endif +} + + int ngx_http_send_header(ngx_http_request_t *r) { return (*ngx_http_top_header_filter)(r); diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -400,7 +400,7 @@ static int ngx_http_process_request_head for (i = 0; headers_in[i].len != 0; i++) { if (headers_in[i].len == h->key.len) { - if (strcasecmp(headers_in[i].data, h->key.data) == 0) { + if (ngx_strcasecmp(headers_in[i].data, h->key.data) == 0) { *((ngx_table_elt_t **) ((char *) &r->headers_in + headers_in[i].offset)) = h; } diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c --- a/src/http/ngx_http_output_filter.c +++ b/src/http/ngx_http_output_filter.c @@ -68,11 +68,10 @@ int ngx_http_output_filter(ngx_http_requ ctx = (ngx_http_output_filter_ctx_t *) ngx_http_get_module_ctx(r->main ? r->main : r, - ngx_http_output_filter_module_ctx); + ngx_http_output_filter_module); if (ctx == NULL) { - ngx_http_create_ctx(r, ctx, - ngx_http_output_filter_module_ctx, + ngx_http_create_ctx(r, ctx, ngx_http_output_filter_module, sizeof(ngx_http_output_filter_ctx_t)); } @@ -183,9 +182,9 @@ int ngx_http_output_filter(ngx_http_requ if (hunk->type & NGX_HUNK_LAST) { conf = (ngx_http_output_filter_conf_t *) - ngx_http_get_module_loc_conf( - r->main ? r->main : r, - ngx_http_output_filter_module_ctx); + ngx_http_get_module_loc_conf( + r->main ? r->main : r, + ngx_http_output_filter_module); size = hunk->last.mem - hunk->pos.mem; if (size > conf->hunk_size) { diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -19,6 +19,13 @@ static char error_400_page[] = "

400 Bad Request

" CRLF ; +static char error_403_page[] = +"" CRLF +"403 Forbidden" CRLF +"" CRLF +"

403 Forbidden

" CRLF +; + static char error_404_page[] = "" CRLF "404 Not Found" CRLF @@ -36,7 +43,7 @@ static ngx_str_t error_pages[] = { { sizeof(error_400_page) - 1, error_400_page }, { 0, NULL}, /* 401 */ { 0, NULL}, /* 402 */ - { 0, NULL}, /* 403 */ + { sizeof(error_403_page) - 1, error_403_page }, { sizeof(error_404_page) - 1, error_404_page }, { 0, NULL} /* 500 */ diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -66,10 +66,9 @@ int ngx_http_write_filter(ngx_http_reque ctx = (ngx_http_write_filter_ctx_t *) ngx_http_get_module_ctx(r->main ? r->main : r, - ngx_http_write_filter_module_ctx); + ngx_http_write_filter_module); if (ctx == NULL) { - ngx_http_create_ctx(r, ctx, - ngx_http_write_filter_module_ctx, + ngx_http_create_ctx(r, ctx, ngx_http_write_filter_module, sizeof(ngx_http_write_filter_ctx_t)); } @@ -126,7 +125,7 @@ int ngx_http_write_filter(ngx_http_reque conf = (ngx_http_write_filter_conf_t *) ngx_http_get_module_loc_conf(r->main ? r->main : r, - ngx_http_write_filter_module_ctx); + ngx_http_write_filter_module); #if (NGX_DEBUG_WRITE_FILTER) ngx_log_debug(r->connection->log, "write filter: last:%d flush:%d" _ diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h --- a/src/os/unix/ngx_errno.h +++ b/src/os/unix/ngx_errno.h @@ -9,6 +9,7 @@ typedef int ngx_err_t; #define NGX_ENOENT ENOENT #define NGX_EINTR EINTR +#define NGX_ENOTDIR ENOTDIR #define NGX_EAGAIN EWOULDBLOCK #define NGX_EINPROGRESS EINPROGRESS #define NGX_EADDRINUSE EADDRINUSE diff --git a/src/os/win32/ngx_types.h b/src/os/win32/ngx_types.h --- a/src/os/win32/ngx_types.h +++ b/src/os/win32/ngx_types.h @@ -8,6 +8,9 @@ typedef int ssize_t; typedef long time_t; +typedef unsigned __int32 u_int32_t; + + #define QD_FMT "%I64d" #define QX_FMT "%I64x"