diff options
author | Igor Sysoev <igor@sysoev.ru> | 2003-05-27 16:18:54 +0400 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2003-05-27 16:18:54 +0400 |
commit | 6253ca1b62c24bbac8c380d4ae64353b671ad7ef (patch) | |
tree | cccc0130b6fb065ff235750d23b817e890bd5e57 /src/http | |
parent | 187fcd82410e0f9022b0090a27b040eb1211c3f5 (diff) |
nginx-0.0.1-2003-05-27-16:18:54 import
Diffstat (limited to 'src/http')
-rw-r--r-- | src/http/modules/ngx_http_index_handler.c | 170 | ||||
-rw-r--r-- | src/http/modules/ngx_http_index_handler.h | 8 | ||||
-rw-r--r-- | src/http/modules/ngx_http_static_handler.c | 67 | ||||
-rw-r--r-- | src/http/ngx_http.c | 47 | ||||
-rw-r--r-- | src/http/ngx_http.h | 6 | ||||
-rw-r--r-- | src/http/ngx_http_config.h | 14 | ||||
-rw-r--r-- | src/http/ngx_http_core_module.c | 314 | ||||
-rw-r--r-- | src/http/ngx_http_core_module.h | 28 | ||||
-rw-r--r-- | src/http/ngx_http_event.c | 206 | ||||
-rw-r--r-- | src/http/ngx_http_header_filter.c | 166 | ||||
-rw-r--r-- | src/http/ngx_http_output_filter.c | 40 | ||||
-rw-r--r-- | src/http/ngx_http_request.h | 10 | ||||
-rw-r--r-- | src/http/ngx_http_special_response.c | 10 | ||||
-rw-r--r-- | src/http/ngx_http_write_filter.c | 15 |
14 files changed, 526 insertions, 575 deletions
diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c index 49a4e0ab3..494621420 100644 --- a/src/http/modules/ngx_http_index_handler.c +++ b/src/http/modules/ngx_http_index_handler.c @@ -1,25 +1,14 @@ -#include <ngx_config.h> - -#include <ngx_core.h> -#include <ngx_errno.h> -#include <ngx_string.h> -#include <ngx_files.h> -#include <ngx_conf_file.h> - -#include <ngx_http.h> -#include <ngx_http_config.h> -#include <ngx_http_core_module.h> #include <ngx_http_index_handler.h> static int ngx_http_index_test_dir(ngx_http_request_t *r); 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); +static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, + void *child); static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, - char *conf); + void *conf); static ngx_command_t ngx_http_index_commands[] = { @@ -31,13 +20,11 @@ static ngx_command_t ngx_http_index_commands[] = { 0, NULL}, - {ngx_string(""), 0, NULL, 0, 0, NULL} + ngx_null_command }; ngx_http_module_t ngx_http_index_module_ctx = { - NGX_HTTP_MODULE, - NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -50,10 +37,10 @@ ngx_http_module_t ngx_http_index_module_ctx = { ngx_module_t ngx_http_index_module = { + NGX_MODULE, &ngx_http_index_module_ctx, /* module context */ - 0, /* module index */ ngx_http_index_commands, /* module directives */ - NGX_HTTP_MODULE_TYPE, /* module type */ + NGX_HTTP_MODULE, /* module type */ ngx_http_index_init /* init module */ }; @@ -63,42 +50,39 @@ ngx_module_t ngx_http_index_module = { because the valid requests should be many more then invalid ones. If open() failed then stat() should be more quickly because some data is already cached in the kernel. - Besides Win32 has ERROR_PATH_NOT_FOUND (NGX_ENOTDIR) and - Unix has ENOTDIR error (although it less helpfull). + Besides Win32 has ERROR_PATH_NOT_FOUND (NGX_ENOTDIR). + Unix has ENOTDIR error, although it less helpfull - it shows only + that path contains the usual file in place of the directory. */ int ngx_http_index_handler(ngx_http_request_t *r) { - int i, rc, test_dir; - char *name, *file; - ngx_str_t loc, *index; - ngx_err_t err; - ngx_fd_t fd; - - ngx_http_index_conf_t *cf; - ngx_http_core_loc_conf_t *core_cf; - - cf = (ngx_http_index_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_index_module_ctx); + int i, rc, test_dir; + char *name, *file; + ngx_str_t loc, *index; + ngx_err_t err; + ngx_fd_t fd; + ngx_http_index_conf_t *icf; + ngx_http_core_loc_conf_t *clcf; - core_cf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + icf = ngx_http_get_module_loc_conf(r, ngx_http_index_module); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); ngx_test_null(r->path.data, ngx_palloc(r->pool, - core_cf->doc_root.len + r->uri.len - + cf->max_index_len), + clcf->doc_root.len + r->uri.len + + icf->max_index_len), NGX_HTTP_INTERNAL_SERVER_ERROR); - loc.data = ngx_cpystrn(r->path.data, core_cf->doc_root.data, - core_cf->doc_root.len + 1); + loc.data = ngx_cpystrn(r->path.data, clcf->doc_root.data, + clcf->doc_root.len + 1); file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1); r->path.len = file - r->path.data; test_dir = 1; - index = (ngx_str_t *) cf->indices->elts; - for (i = 0; i < cf->indices->nelts; i++) { + index = (ngx_str_t *) icf->indices.elts; + for (i = 0; i < icf->indices.nelts; i++) { if (index[i].data[0] != '/') { ngx_memcpy(file, index[i].data, index[i].len + 1); @@ -147,8 +131,8 @@ ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err, return NGX_HTTP_INTERNAL_SERVER_ERROR; } - r->file.name.data = name; - r->file.fd = fd; + r->file.name.data = name; + r->file.fd = fd; if (index[i].data[0] == '/') { r->file.name.len = index[i].len; @@ -157,7 +141,7 @@ ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err, } else { loc.len = r->uri.len + index[i].len; - r->file.name.len = core_cf->doc_root.len + r->uri.len + r->file.name.len = clcf->doc_root.len + r->uri.len + index[i].len; } @@ -178,9 +162,9 @@ static int ngx_http_index_test_dir(ngx_http_request_t *r) ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data); #if 0 - if (r->path_err == NGX_EACCES) { - return NGX_HTTP_FORBIDDEN; - } + if (r->path_err == NGX_EACCES) { + return NGX_HTTP_FORBIDDEN; + } #endif if (ngx_file_type(r->path.data, &r->file.info) == -1) { @@ -226,76 +210,88 @@ static void *ngx_http_index_create_conf(ngx_pool_t *pool) { ngx_http_index_conf_t *conf; - ngx_test_null(conf, ngx_pcalloc(pool, sizeof(ngx_http_index_conf_t)), + ngx_test_null(conf, ngx_palloc(pool, sizeof(ngx_http_index_conf_t)), NGX_CONF_ERROR); - ngx_test_null(conf->indices, - ngx_create_array(pool, 3, sizeof(ngx_str_t)), - NGX_CONF_ERROR); + ngx_init_array(conf->indices, pool, 3, sizeof(ngx_str_t), NGX_CONF_ERROR); + conf->max_index_len = 0; return conf; } -/* STUB */ +/* TODO: remove duplicate indices */ + static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) { -#if 0 - ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent; -#endif - ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child; - ngx_str_t *index; + ngx_http_index_conf_t *prev = parent; + ngx_http_index_conf_t *conf = child; - if (conf->max_index_len == 0) { - ngx_test_null(index, ngx_push_array(conf->indices), NGX_CONF_ERROR); - index->len = sizeof(NGX_HTTP_INDEX) - 1; - index->data = NGX_HTTP_INDEX; - conf->max_index_len = sizeof(NGX_HTTP_INDEX); - } + int i; + ngx_str_t *index, *prev_index; - /* FAIL: if first index is started with '/' */ + if (conf->max_index_len == 0) { + if (prev->max_index_len != 0) { + ngx_memcpy(conf, prev, sizeof(ngx_http_index_conf_t)); + return NGX_CONF_OK; + } - return NULL; -} + ngx_test_null(index, ngx_push_array(&conf->indices), NGX_CONF_ERROR); + index->len = sizeof(NGX_HTTP_DEFAULT_INDEX) - 1; + index->data = NGX_HTTP_DEFAULT_INDEX; + conf->max_index_len = sizeof(NGX_HTTP_DEFAULT_INDEX); + return NGX_CONF_OK; + } -#if 0 -static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child) -{ - ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent; - ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child; - ngx_str_t *index; + if (prev->max_index_len != 0) { - if (conf->max_index_len == 0) { - if (prev->max_index_len != 0) { - return prev; + prev_index = prev->indices.elts; + for (i = 0; i < prev->indices.nelts; i++) { + ngx_test_null(index, ngx_push_array(&conf->indices), + NGX_CONF_ERROR); + index->len = prev_index[i].len; + index->data = prev_index[i].data; } + } - ngx_test_null(index, ngx_push_array(conf->indices), NULL); - index->len = sizeof(NGX_HTTP_INDEX) - 1; - index->data = NGX_HTTP_INDEX; - conf->max_index_len = sizeof(NGX_HTTP_INDEX); + if (conf->max_index_len < prev->max_index_len) { + conf->max_index_len = prev->max_index_len; } - return conf; + return NGX_CONF_OK; } -#endif + + +/* TODO: check duplicate indices */ static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, - char *conf) + void *conf) { - ngx_http_index_conf_t *lcf = (ngx_http_index_conf_t *) conf; - int i; + ngx_http_index_conf_t *icf = conf; + + int i; ngx_str_t *index, *value; - value = (ngx_str_t *) cf->args->elts; + value = cf->args->elts; + + if (value[1].data[0] == '/' && icf->indices.nelts == 0) { + ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1, + "first index \"%s\" must not be absolute", value[1].data); + return ngx_conf_errstr; + } + for (i = 1; i < cf->args->nelts; i++) { - ngx_test_null(index, ngx_push_array(lcf->indices), NGX_CONF_ERROR); + if (value[i].len == 0) { + return "is invalid"; + } + + ngx_test_null(index, ngx_push_array(&icf->indices), NGX_CONF_ERROR); index->len = value[i].len; index->data = value[i].data; - if (lcf->max_index_len < index->len) { - lcf->max_index_len = index->len; + if (icf->max_index_len < index->len + 1) { + icf->max_index_len = index->len + 1; } } diff --git a/src/http/modules/ngx_http_index_handler.h b/src/http/modules/ngx_http_index_handler.h index 3dd6bd82c..3d2f6f00d 100644 --- a/src/http/modules/ngx_http_index_handler.h +++ b/src/http/modules/ngx_http_index_handler.h @@ -3,16 +3,16 @@ #include <ngx_config.h> -#include <ngx_array.h> +#include <ngx_core.h> #include <ngx_http.h> -#define NGX_HTTP_INDEX "index.html" +#define NGX_HTTP_DEFAULT_INDEX "index.html" typedef struct { - ngx_array_t *indices; - size_t max_index_len; + ngx_array_t indices; + size_t max_index_len; } ngx_http_index_conf_t; diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c index 41f134286..bc88fc920 100644 --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -1,38 +1,22 @@ #include <ngx_config.h> #include <ngx_core.h> -#include <ngx_string.h> -#include <ngx_file.h> -#include <ngx_hunk.h> #include <ngx_http.h> #include <ngx_http_config.h> #include <ngx_http_core_module.h> #include <ngx_http_output_filter.h> -ngx_http_module_t ngx_http_static_module; - 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_http_type_t *type; - ngx_http_log_ctx_t *ctx; - ngx_http_core_loc_conf_t *core_lcf; - - core_lcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); - -#if 0 - ngx_http_event_static_handler_loc_conf_t *lcf; - - lcf = (ngx_http_event_static_handler_loc_conf_t *) - ngx_get_module_loc_conf(r, &ngx_http_event_static_handler_module_ctx); - -#endif + int rc, key, i; + ngx_log_e level; + ngx_err_t err; + ngx_hunk_t *h; + ngx_http_type_t *type; + ngx_http_log_ctx_t *ctx; + ngx_http_core_loc_conf_t *clcf; rc = ngx_http_discard_body(r); @@ -40,6 +24,10 @@ int ngx_http_static_handler(ngx_http_request_t *r) return rc; } + if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) { + return NGX_HTTP_NOT_ALLOWED; + } + ctx = r->connection->log->data; ctx->action = "sending response"; @@ -102,14 +90,18 @@ int ngx_http_static_handler(ngx_http_request_t *r) 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"; + 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 *) core_lcf->types[key].elts; - for (i = 0; i < core_lcf->types[key].nelts; i++) { + 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; } @@ -117,14 +109,15 @@ int ngx_http_static_handler(ngx_http_request_t *r) 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) { - /* STUB: default type */ - r->headers_out.content_type->value.len = 25; - r->headers_out.content_type->value.data = "text/html; charset=koi8-r"; + 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 */ @@ -134,9 +127,19 @@ int ngx_http_static_handler(ngx_http_request_t *r) ngx_test_null(h->file, ngx_pcalloc(r->pool, sizeof(ngx_file_t)), NGX_HTTP_INTERNAL_SERVER_ERROR); - ngx_http_send_header(r); - if (r->header_only) + + rc = ngx_http_send_header(r); + + if (r->header_only) { + if (rc == NGX_AGAIN) { + ngx_http_set_write_handler(r); + + } else { + ngx_http_finalize_request(r, 0); + } + return NGX_OK; + } h->type = NGX_HUNK_FILE|NGX_HUNK_LAST; diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c index 4b182d43f..efa2bec68 100644 --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -11,7 +11,7 @@ static void ngx_http_init_filters(ngx_pool_t *pool, ngx_module_t **modules); -static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); +static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); int ngx_http_max_module; @@ -37,20 +37,20 @@ static ngx_command_t ngx_http_commands[] = { 0, NULL}, - {ngx_string(""), 0, NULL, 0, 0, NULL} + ngx_null_command }; ngx_module_t ngx_http_module = { + NGX_MODULE, &http_name, /* module context */ - 0, /* module index */ ngx_http_commands, /* module directives */ - NGX_CORE_MODULE_TYPE, /* module type */ + NGX_CORE_MODULE, /* module type */ NULL /* init module */ }; -static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { int mi, m, s, l, p, a, n; int port_found, addr_found, virtual_names; @@ -81,12 +81,11 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) ngx_http_max_module = 0; for (m = 0; ngx_modules[m]; m++) { - if (ngx_modules[m]->type != NGX_HTTP_MODULE_TYPE) { + if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } - module = (ngx_http_module_t *) ngx_modules[m]->ctx; - module->index = ngx_http_max_module++; + ngx_modules[m]->ctx_index = ngx_http_max_module++; } /* the main http main_conf, it's the same in the all http contexts */ @@ -108,26 +107,27 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) /* create the main_conf, srv_conf and loc_conf in all http modules */ for (m = 0; ngx_modules[m]; m++) { - if (ngx_modules[m]->type != NGX_HTTP_MODULE_TYPE) { + if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } - module = (ngx_http_module_t *) ngx_modules[m]->ctx; + module = ngx_modules[m]->ctx; + mi = ngx_modules[m]->ctx_index; if (module->create_main_conf) { - ngx_test_null(ctx->main_conf[module->index], + ngx_test_null(ctx->main_conf[mi], module->create_main_conf(cf->pool), NGX_CONF_ERROR); } if (module->create_srv_conf) { - ngx_test_null(ctx->srv_conf[module->index], + ngx_test_null(ctx->srv_conf[mi], module->create_srv_conf(cf->pool), NGX_CONF_ERROR); } if (module->create_loc_conf) { - ngx_test_null(ctx->loc_conf[module->index], + ngx_test_null(ctx->loc_conf[mi], module->create_loc_conf(cf->pool), NGX_CONF_ERROR); } @@ -138,7 +138,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) pcf = *cf; cf->ctx = ctx; - cf->module_type = NGX_HTTP_MODULE_TYPE; + cf->module_type = NGX_HTTP_MODULE; cf->cmd_type = NGX_HTTP_MAIN_CONF; rv = ngx_conf_parse(cf, NULL); *cf = pcf; @@ -150,16 +150,16 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) /* init http{} main_conf's, merge the server{}s' srv_conf's and its location{}s' loc_conf's */ - cmcf = ctx->main_conf[ngx_http_core_module_ctx.index]; + cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; cscfp = (ngx_http_core_srv_conf_t **)cmcf->servers.elts; for (m = 0; ngx_modules[m]; m++) { - if (ngx_modules[m]->type != NGX_HTTP_MODULE_TYPE) { + if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } module = (ngx_http_module_t *) ngx_modules[m]->ctx; - mi = module->index; + mi = ngx_modules[m]->ctx_index; /* init http{} main_conf's */ @@ -310,7 +310,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) sizeof(ngx_http_in_addr_t)); in_addr[a].addr = lscf[l].addr; - in_addr[a].flags = lscf[l].flags; + in_addr[a].flags = lscf[l].flags; in_addr[a].core_srv_conf = cscfp[s]; /* create the empty list of the server names that @@ -336,7 +336,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) NGX_CONF_ERROR); inaddr->addr = lscf[l].addr; - inaddr->flags = lscf[l].flags; + inaddr->flags = lscf[l].flags; inaddr->core_srv_conf = cscfp[s]; /* create the empty list of the server names that @@ -359,6 +359,12 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) in_port->port = lscf[l].port; + ngx_test_null(in_port->port_name.data, ngx_palloc(cf->pool, 7), + NGX_CONF_ERROR); + in_port->port_name.len = ngx_snprintf(in_port->port_name.data, + 7, ":%d", + in_port->port); + /* create list of the addresses that bound to this port ... */ ngx_init_array(in_port->addrs, cf->pool, 10, @@ -371,7 +377,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) /* ... and add the address to this list */ inaddr->addr = lscf[l].addr; - inaddr->flags = lscf[l].flags; + inaddr->flags = lscf[l].flags; inaddr->core_srv_conf = cscfp[s]; /* create the empty list of the server names that @@ -484,6 +490,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) NGX_CONF_ERROR); inport->port = in_port[p].port; + inport->port_name = in_port[p].port_name; /* init list of the addresses ... */ diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h index 2a695c776..81a859d40 100644 --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -13,6 +13,8 @@ #include <ngx_conf_file.h> #include <ngx_http_request.h> +#include <ngx_http_config.h> +#include <ngx_http_core_module.h> typedef struct { @@ -30,12 +32,12 @@ typedef int (*ngx_http_output_body_filter_p) (ngx_http_request_t *r, ngx_chain_t *chain); -#define ngx_http_get_module_ctx(r, module) r->ctx[module.index] +#define ngx_http_get_module_ctx(r, module) r->ctx[module.ctx_index] #define ngx_http_create_ctx(r, cx, module, size, error) \ do { \ ngx_test_null(cx, ngx_pcalloc(r->pool, size), error); \ - r->ctx[module.index] = cx; \ + r->ctx[module.ctx_index] = cx; \ } while (0) diff --git a/src/http/ngx_http_config.h b/src/http/ngx_http_config.h index abd3bdb26..50804c3a6 100644 --- a/src/http/ngx_http_config.h +++ b/src/http/ngx_http_config.h @@ -20,8 +20,6 @@ typedef struct { typedef struct { - int index; - void *(*create_main_conf)(ngx_pool_t *p); char *(*init_main_conf)(ngx_pool_t *p, void *conf); @@ -33,9 +31,7 @@ typedef struct { } ngx_http_module_t; -#define NGX_HTTP_MODULE_TYPE 0x50545448 /* "HTTP" */ - -#define NGX_HTTP_MODULE 0 +#define NGX_HTTP_MODULE 0x50545448 /* "HTTP" */ #define NGX_HTTP_MAIN_CONF 0x2000000 #define NGX_HTTP_SRV_CONF 0x4000000 @@ -47,12 +43,10 @@ typedef struct { #define NGX_HTTP_LOC_CONF_OFFSET offsetof(ngx_http_conf_ctx_t, loc_conf) -#define ngx_http_get_module_main_conf(r, ctx) r->main_conf[ctx.index] -#define ngx_http_get_module_srv_conf(r, ctx) r->srv_conf[ctx.index] -#define ngx_http_get_module_loc_conf(r, ctx) r->loc_conf[ctx.index] - +#define ngx_http_get_module_main_conf(r, module) r->main_conf[module.ctx_index] +#define ngx_http_get_module_srv_conf(r, module) r->srv_conf[module.ctx_index] +#define ngx_http_get_module_loc_conf(r, module) r->loc_conf[module.ctx_index] -int ngx_http_config_modules(ngx_pool_t *pool, ngx_module_t **modules); extern int (*ngx_http_top_header_filter) (ngx_http_request_t *r); diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 00dc0729d..ba07718d3 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1,28 +1,21 @@ #include <ngx_config.h> - -#include <ngx_listen.h> #include <ngx_core.h> -#include <ngx_string.h> -#include <ngx_conf_file.h> -#include <nginx.h> +/* ???? */ +#include <ngx_listen.h> #include <ngx_http.h> -#include <ngx_http_config.h> -#include <ngx_http_core_module.h> +#include <ngx_http_output_filter.h> +#include <nginx.h> -/* STUB for r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; */ -#include <ngx_http_output_filter.h> +/* STUB */ int ngx_http_static_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 int ngx_http_core_init(ngx_pool_t *pool); +static int ngx_http_core_index_handler(ngx_http_request_t *r); static void *ngx_http_core_create_main_conf(ngx_pool_t *pool); static char *ngx_http_core_init_main_conf(ngx_pool_t *pool, void *conf); @@ -33,11 +26,12 @@ static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool); static char *ngx_http_core_merge_loc_conf(ngx_pool_t *pool, void *parent, void *child); -static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); +static int ngx_http_core_init(ngx_pool_t *pool); +static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy); static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, - char *dummy); -static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy); -static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, char *conf); + void *dummy); +static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static ngx_command_t ngx_http_core_commands[] = { @@ -113,6 +107,13 @@ static ngx_command_t ngx_http_core_commands[] = { 0, NULL}, + {ngx_string("default_type"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_str_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_core_loc_conf_t, default_type), + NULL}, + {ngx_string("root"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -155,13 +156,11 @@ static ngx_command_t ngx_http_core_commands[] = { offsetof(ngx_http_core_loc_conf_t, lingering_timeout), NULL}, - {ngx_null_string, 0, NULL, 0, 0, NULL} + ngx_null_command }; ngx_http_module_t ngx_http_core_module_ctx = { - NGX_HTTP_MODULE, - ngx_http_core_create_main_conf, /* create main configuration */ ngx_http_core_init_main_conf, /* init main configuration */ @@ -174,108 +173,20 @@ ngx_http_module_t ngx_http_core_module_ctx = { ngx_module_t ngx_http_core_module = { + NGX_MODULE, &ngx_http_core_module_ctx, /* module context */ - 0, /* module index */ ngx_http_core_commands, /* module directives */ - NGX_HTTP_MODULE_TYPE, /* module type */ + NGX_HTTP_MODULE, /* module type */ ngx_http_core_init /* init module */ }; -int ngx_http_find_server_conf(ngx_http_request_t *r) -{ - int a, n; - socklen_t len; - struct sockaddr_in addr_in; - ngx_http_in_port_t *in_port; - ngx_http_in_addr_t *in_addr; - ngx_http_conf_ctx_t *ctx; - ngx_http_server_name_t *name; - - /* AF_INET only */ - - in_port = (ngx_http_in_port_t *) r->connection->servers; - in_addr = (ngx_http_in_addr_t *) in_port->addrs.elts; - - r->port = in_port->port; - - a = 0; - - if (in_port->addrs.nelts > 1) { - - /* there're the several addresses on this port and one of them - is "*:port" so getsockname() is needed to determine - the server address */ - - len = sizeof(struct sockaddr_in); - if (getsockname(r->connection->fd, (struct sockaddr *) &addr_in, &len) - == -1) { - ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_socket_errno, - "getsockname() failed"); - return NGX_ERROR; - } - - r->in_addr = addr_in.sin_addr.s_addr; - - for ( /* void */ ; a < in_port->addrs.nelts; a++) { - if (in_addr[a].addr == r->in_addr) { -ngx_log_debug(r->connection->log, "FOUND"); - break; - } - } - -/* DEBUG */ -if (a == in_port->addrs.nelts) { - ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - "addr not found"); - exit(1); -} - - } else { - r->in_addr = in_addr[0].addr; - } - - /* the default server configuration for this address:port */ - ctx = in_addr[a].core_srv_conf->ctx; - - if (r->headers_in.host_name_len > 0) { - - /* find the name based server configuration */ - - name = (ngx_http_server_name_t *) in_addr[a].names.elts; - for (n = 0; n < in_addr[a].names.nelts; n++) { - if (r->headers_in.host_name_len != name[n].name.len) { - continue; - } - - if (ngx_strncasecmp(r->headers_in.host->value.data, - name[n].name.data, - r->headers_in.host_name_len) == 0) { - ctx = name->core_srv_conf->ctx; - break; - } - } - } - - r->srv_conf = ctx->srv_conf; - r->loc_conf = ctx->loc_conf; - -#if 0 -ngx_log_debug(r->connection->log, "cxt: %08x" _ ctx); -ngx_log_debug(r->connection->log, "srv_conf: %0x" _ r->srv_conf); -ngx_log_debug(r->connection->log, "loc_conf: %0x" _ r->loc_conf); -#endif - - return NGX_OK; -} - - void ngx_http_handler(ngx_http_request_t *r) { int rc, i; ngx_http_handler_pt *h; - ngx_http_core_loc_conf_t *lcf, **lcfp; - ngx_http_core_srv_conf_t *scf; + ngx_http_core_loc_conf_t *clcf, **clcfp; + ngx_http_core_srv_conf_t *cscf; r->connection->unexpected_eof = 0; @@ -293,33 +204,32 @@ void ngx_http_handler(ngx_http_request_t *r) /* find location config */ - scf = (ngx_http_core_srv_conf_t *) - ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); - lcfp = (ngx_http_core_loc_conf_t **) scf->locations.elts; - for (i = 0; i < scf->locations.nelts; i++) { + clcfp = cscf->locations.elts; + for (i = 0; i < cscf->locations.nelts; i++) { #if 0 -ngx_log_debug(r->connection->log, "trans: %s" _ lcfp[i]->name.data); +ngx_log_debug(r->connection->log, "trans: %s" _ clcfp[i]->name.data); #endif - if (r->uri.len < lcfp[i]->name.len) { + if (r->uri.len < clcfp[i]->name.len) { continue; } - rc = ngx_rstrncmp(r->uri.data, lcfp[i]->name.data, lcfp[i]->name.len); + rc = ngx_rstrncmp(r->uri.data, clcfp[i]->name.data, + clcfp[i]->name.len); if (rc < 0) { break; } if (rc == 0) { - r->loc_conf = lcfp[i]->loc_conf; + r->loc_conf = clcfp[i]->loc_conf; } } - lcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - if ((ngx_io.flags & NGX_IO_SENDFILE) == 0 || lcf->sendfile == 0) { + if ((ngx_io.flags & NGX_IO_SENDFILE) == 0 || clcf->sendfile == 0) { r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; } @@ -355,80 +265,37 @@ ngx_log_debug(r->connection->log, "trans: %s" _ lcfp[i]->name.data); int ngx_http_core_translate_handler(ngx_http_request_t *r) { - int len, port_len, f_offset, l_offset; - char *buf, *location, *last; + char *location, *last; ngx_err_t err; ngx_table_elt_t *h; + ngx_http_in_port_t *in_port; ngx_http_server_name_t *s_name; - ngx_http_core_srv_conf_t *scf; - ngx_http_core_loc_conf_t *lcf; + ngx_http_core_srv_conf_t *cscf; + ngx_http_core_loc_conf_t *clcf; - lcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - if (lcf->handler) { - r->handler = lcf->handler; + if (clcf->handler) { + r->handler = clcf->handler; return NGX_OK; } - scf = (ngx_http_core_srv_conf_t *) - ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); if (r->uri.data[r->uri.len - 1] == '/') { r->handler = ngx_http_core_index_handler; return NGX_OK; } -ngx_log_debug(r->connection->log, "doc_root: %08x" _ &lcf->doc_root); - - s_name = (ngx_http_server_name_t *) scf->server_names.elts; - - if (r->port == 0) { -#if 0 - struct sockaddr_in *addr_in; - addr_in = (struct sockaddr_in *) r->connection->sockaddr; - r->port = ntohs(addr_in->sin_port); -#else - ngx_http_in_port_t *in_port; - in_port = (ngx_http_in_port_t *) r->connection->servers; - r->port = in_port->port; -#endif - if (r->port != 80) { - ngx_test_null(r->port_name.data, ngx_palloc(r->pool, 7), - NGX_HTTP_INTERNAL_SERVER_ERROR); - r->port_name.len = ngx_snprintf(r->port_name.data, 7, ":%d", - r->port); - } - } - - port_len = (r->port != 80) ? r->port_name.len : 0; - - /* "+ 7" is "http://" */ - if (lcf->doc_root.len > 7 + s_name[0].name.len + port_len) { - len = lcf->doc_root.len; - f_offset = 0; - l_offset = len - (7 + s_name[0].name.len + port_len); - - } else { - len = 7 + s_name[0].name.len + port_len; - f_offset = len - lcf->doc_root.len; - l_offset = 0; - } - /* "+ 2" is for trailing '/' in redirect and '\0' */ - len += r->uri.len + 2; - - ngx_test_null(buf, ngx_palloc(r->pool, len), + ngx_test_null(r->file.name.data, + ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len + 2), NGX_HTTP_INTERNAL_SERVER_ERROR); - r->file.name.data = buf + f_offset; - location = buf + l_offset; - - last = ngx_cpystrn(ngx_cpystrn(r->file.name.data, lcf->doc_root.data, - lcf->doc_root.len + 1), - r->uri.data, r->uri.len + 1); + location = ngx_cpymem(r->file.name.data, clcf->doc_root.data, + clcf->doc_root.len), - r->file.name.len = last - r->file.name.data; + last = ngx_cpystrn(location, r->uri.data, r->uri.len + 1); ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data); @@ -510,13 +377,6 @@ ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->file.name.data); ngx_test_null(h, ngx_push_table(r->headers_out.headers), NGX_HTTP_INTERNAL_SERVER_ERROR); - ngx_memcpy(location, "http://", 7); - ngx_memcpy(location + 7, s_name[0].name.data, s_name[0].name.len); - if (port_len) { - ngx_memcpy(location + 7 + s_name[0].name.len, r->port_name.data, - port_len); - } - *last++ = '/'; *last = '\0'; h->key.len = 8; @@ -584,7 +444,7 @@ int ngx_http_redirect(ngx_http_request_t *r, int redirect) } -int ngx_http_error(ngx_http_request_t *r, int error) +int ngx_http_error(ngx_http_request_t *r, int error) { /* STUB */ ngx_log_debug(r->connection->log, "http error: %d" _ error); @@ -627,7 +487,7 @@ static int ngx_http_core_init(ngx_pool_t *pool) } -static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) +static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) { int m; char *rv; @@ -657,20 +517,20 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) NGX_CONF_ERROR); for (m = 0; ngx_modules[m]; m++) { - if (ngx_modules[m]->type != NGX_HTTP_MODULE_TYPE) { + if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } - module = (ngx_http_module_t *) ngx_modules[m]->ctx; + module = ngx_modules[m]->ctx; if (module->create_srv_conf) { - ngx_test_null(ctx->srv_conf[module->index], + ngx_test_null(ctx->srv_conf[ngx_modules[m]->ctx_index], module->create_srv_conf(cf->pool), NGX_CONF_ERROR); } if (module->create_loc_conf) { - ngx_test_null(ctx->loc_conf[module->index], + ngx_test_null(ctx->loc_conf[ngx_modules[m]->ctx_index], module->create_loc_conf(cf->pool), NGX_CONF_ERROR); } @@ -678,10 +538,10 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) /* create links of the srv_conf's */ - cscf = ctx->srv_conf[ngx_http_core_module_ctx.index]; + cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; cscf->ctx = ctx; - cmcf = ctx->main_conf[ngx_http_core_module_ctx.index]; + cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; ngx_test_null(cscfp, ngx_push_array(&cmcf->servers), NGX_CONF_ERROR); *cscfp = cscf; @@ -698,9 +558,9 @@ 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, char *dummy) +static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) { - int i; + int m; char *rv; ngx_str_t *location; ngx_http_module_t *module; @@ -721,27 +581,27 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy) ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), NGX_CONF_ERROR); - for (i = 0; ngx_modules[i]; i++) { - if (ngx_modules[i]->type != NGX_HTTP_MODULE_TYPE) { + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_HTTP_MODULE) { continue; } - module = (ngx_http_module_t *) ngx_modules[i]->ctx; + module = ngx_modules[m]->ctx; if (module->create_loc_conf) { - ngx_test_null(ctx->loc_conf[module->index], + ngx_test_null(ctx->loc_conf[ngx_modules[m]->ctx_index], module->create_loc_conf(cf->pool), NGX_CONF_ERROR); } } - clcf = ctx->loc_conf[ngx_http_core_module_ctx.index]; + clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; location = (ngx_str_t *) cf->args->elts; clcf->name.len = location[1].len; clcf->name.data = location[1].data; clcf->loc_conf = ctx->loc_conf; - cscf = ctx->srv_conf[ngx_http_core_module_ctx.index]; + cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; ngx_test_null(clcfp, ngx_push_array(&cscf->locations), NGX_CONF_ERROR); *clcfp = clcf; @@ -791,7 +651,7 @@ static char *ngx_set_type(ngx_conf_t *cf, ngx_command_t *dummy, char *conf) } -static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *rv; ngx_conf_t pcf; @@ -811,7 +671,7 @@ static void *ngx_http_core_create_main_conf(ngx_pool_t *pool) ngx_http_core_main_conf_t *cmcf; ngx_test_null(cmcf, - ngx_palloc(pool, sizeof(ngx_http_core_main_conf_t)), + ngx_palloc(pool, sizeof(ngx_http_core_main_conf_t)), NGX_CONF_ERROR); cmcf->connection_pool_size = NGX_CONF_UNSET; @@ -826,7 +686,7 @@ static void *ngx_http_core_create_main_conf(ngx_pool_t *pool) static char *ngx_http_core_init_main_conf(ngx_pool_t *pool, void *conf) { - ngx_http_core_main_conf_t *cmcf = (ngx_http_core_main_conf_t *) conf; + ngx_http_core_main_conf_t *cmcf = conf; ngx_conf_init_size_value(cmcf->connection_pool_size, 16384); ngx_conf_init_msec_value(cmcf->post_accept_timeout, 30000); @@ -840,7 +700,7 @@ static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool) ngx_http_core_srv_conf_t *cscf; ngx_test_null(cscf, - ngx_pcalloc(pool, sizeof(ngx_http_core_srv_conf_t)), + ngx_pcalloc(pool, sizeof(ngx_http_core_srv_conf_t)), NGX_CONF_ERROR); ngx_init_array(cscf->locations, pool, 5, sizeof(void *), NGX_CONF_ERROR); @@ -881,12 +741,8 @@ static char *ngx_http_core_merge_srv_conf(ngx_pool_t *pool, ngx_test_null(n->name.data, ngx_palloc(pool, NGX_MAXHOSTNAMELEN), NGX_CONF_ERROR); if (gethostname(n->name.data, NGX_MAXHOSTNAMELEN) == -1) { -/* STUB: no log here */ -#if 0 - ngx_log_error(NGX_LOG_EMERG, scf->log, ngx_errno, - "gethostname() failed"); -#endif - return NGX_CONF_ERROR; + /* TODO: need ngx_errno here */ + return "gethostname() failed"; } n->name.len = ngx_strlen(n->name.data); n->core_srv_conf = conf; @@ -910,7 +766,7 @@ static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool) ngx_http_core_loc_conf_t *lcf; ngx_test_null(lcf, - ngx_pcalloc(pool, sizeof(ngx_http_core_loc_conf_t)), + ngx_pcalloc(pool, sizeof(ngx_http_core_loc_conf_t)), NGX_CONF_ERROR); /* set by ngx_pcalloc(): @@ -918,6 +774,8 @@ static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool) lcf->doc_root.len = 0; lcf->doc_root.data = NULL; lcf->types = NULL; + lcf->default_type.len = 0; + lcf->default_type.data = NULL; */ @@ -950,16 +808,8 @@ static char *ngx_http_core_merge_loc_conf(ngx_pool_t *pool, int i, key; ngx_http_type_t *t; - if (conf->doc_root.len == 0) { - if (prev->doc_root.len) { - conf->doc_root.len = prev->doc_root.len; - conf->doc_root.data = prev->doc_root.data; - - } else { - conf->doc_root.len = 4; - conf->doc_root.data = "html"; - } - } + ngx_conf_merge_str_value(conf->doc_root, + prev->doc_root, "html"); if (conf->types == NULL) { if (prev->types) { @@ -989,6 +839,9 @@ static char *ngx_http_core_merge_loc_conf(ngx_pool_t *pool, } } + ngx_conf_merge_str_value(conf->default_type, + prev->default_type, "text/plain"); + ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0); ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 10000); ngx_conf_merge_size_value(conf->discarded_buffer_size, @@ -1004,16 +857,18 @@ static char *ngx_http_core_merge_loc_conf(ngx_pool_t *pool, } -static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) +static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf; char *addr; u_int p; + struct hostent *h; ngx_str_t *args; ngx_http_listen_t *ls; - /* TODO: check duplicate 'listen' directives */ + /* TODO: check duplicate 'listen' directives, + add resolved name to server names */ ngx_test_null(ls, ngx_push_array(&scf->listen), NGX_CONF_ERROR); @@ -1033,8 +888,13 @@ static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, char *conf) ls->addr = inet_addr(addr); if (ls->addr == INADDR_NONE) { - /* TODO: gethostbyname() */ - return "can not resolve host name"; + h = gethostbyname(addr); + + if (h == NULL || h->h_addr_list[0] == NULL) { + return "can not resolve host name"; + } + + ls->addr = *(u_int32_t *)(h->h_addr_list[0]); } break; diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index ad566178e..6d4acff15 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -47,6 +47,7 @@ typedef struct { typedef struct { int port; + ngx_str_t port_name; ngx_array_t addrs; /* array of ngx_http_in_addr_t */ } ngx_http_in_port_t; @@ -56,7 +57,7 @@ typedef struct { ngx_array_t names; /* array of ngx_http_server_name_t */ ngx_http_core_srv_conf_t *core_srv_conf; /* default server conf for this address:port */ - int flags; + int flags; } ngx_http_in_addr_t; /* ngx_http_in_addr_t's flags */ @@ -87,22 +88,23 @@ typedef struct { typedef struct { - ngx_str_t name; /* location name */ - void **loc_conf ; /* pointer to the modules' loc_conf */ + ngx_str_t name; /* location name */ + void **loc_conf ; /* pointer to the modules' loc_conf */ - int (*handler) (ngx_http_request_t *r); + int (*handler) (ngx_http_request_t *r); - ngx_str_t doc_root; /* root */ + ngx_str_t doc_root; /* root */ ngx_array_t *types; - - int sendfile; /* sendfile */ - ngx_msec_t send_timeout; /* send_timeout */ - size_t send_lowat; /* send_lowa */ - size_t discarded_buffer_size; /* discarded_buffer_size */ - ngx_msec_t keepalive_timeout; /* keepalive_timeout */ - ngx_msec_t lingering_time; /* lingering_time */ - ngx_msec_t lingering_timeout; /* lingering_timeout */ + ngx_str_t default_type; + + int sendfile; /* sendfile */ + ngx_msec_t send_timeout; /* send_timeout */ + size_t send_lowat; /* send_lowat */ + size_t discarded_buffer_size; /* discarded_buffer_size */ + ngx_msec_t keepalive_timeout; /* keepalive_timeout */ + ngx_msec_t lingering_time; /* lingering_time */ + ngx_msec_t lingering_timeout; /* lingering_timeout */ } ngx_http_core_loc_conf_t; diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c index bd733a33e..9d41584d3 100644 --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -75,10 +75,9 @@ static ngx_http_header_t headers_in[] = { void ngx_http_init_connection(ngx_connection_t *c) { - int event; - ngx_event_t *rev; - ngx_http_log_ctx_t *lcx; - ngx_http_conf_ctx_t *ctx; + int event; + ngx_event_t *rev; + ngx_http_log_ctx_t *lcx; c->addr_text.data = ngx_palloc(c->pool, c->addr_text_max_len); if (c->addr_text.data == NULL) { @@ -139,16 +138,77 @@ void ngx_http_init_connection(ngx_connection_t *c) static void ngx_http_init_request(ngx_event_t *rev) { + int i; + socklen_t len; + struct sockaddr_in addr_in; ngx_connection_t *c; ngx_http_request_t *r; - ngx_http_conf_ctx_t *ctx; + ngx_http_in_port_t *in_port; + ngx_http_in_addr_t *in_addr; + ngx_http_server_name_t *server_name; ngx_http_core_srv_conf_t *cscf; c = rev->data; - ctx = c->ctx; - cscf = ngx_http_get_module_srv_conf(ctx, ngx_http_core_module_ctx); - cscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_core_module_ctx); + r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)); + if (r == NULL) { + ngx_http_close_connection(c); + return; + } + + /* find the server configuration for the address:port */ + + /* AF_INET only */ + + in_port = c->servers; + in_addr = in_port->addrs.elts; + + r->port = in_port->port; + r->port_name = &in_port->port_name; + + i = 0; + + if (in_port->addrs.nelts > 1) { + + /* there're the several addresses on this port and one of them + is "*:port" so getsockname() is needed to determine + the server address */ + + /* TODO: AcceptEx() already gave this sockaddr_in */ + + len = sizeof(struct sockaddr_in); + if (getsockname(c->fd, (struct sockaddr *) &addr_in, &len) == -1) { + ngx_log_error(NGX_LOG_CRIT, rev->log, ngx_socket_errno, + "getsockname() failed"); + ngx_http_close_connection(c); + return; + } + + r->in_addr = addr_in.sin_addr.s_addr; + + /* the last in_port->addrs address is "*" */ + + for ( /* void */ ; i < in_port->addrs.nelts - 1; i++) { + if (in_addr[i].addr == r->in_addr) { + break; + } + } + + } else { + r->in_addr = in_addr[0].addr; + } + + r->virtual_names = &in_addr[i].names; + + /* the default server configuration for the address:port */ + cscf = in_addr[i].core_srv_conf; + + r->main_conf = cscf->ctx->main_conf; + r->srv_conf = cscf->ctx->srv_conf; + r->loc_conf = cscf->ctx->loc_conf; + + server_name = cscf->server_names.elts; + r->server_name = &server_name->name; if (c->buffer == NULL) { c->buffer = ngx_create_temp_hunk(c->pool, @@ -160,12 +220,6 @@ static void ngx_http_init_request(ngx_event_t *rev) } } - r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)); - if (r == NULL) { - ngx_http_close_connection(c); - return; - } - r->pool = ngx_create_pool(cscf->request_pool_size, c->log); if (r->pool == NULL) { ngx_http_close_connection(c); @@ -186,10 +240,6 @@ static void ngx_http_init_request(ngx_event_t *rev) return; } - r->main_conf = ctx->main_conf; - r->srv_conf = ctx->srv_conf; - r->loc_conf = ctx->loc_conf; - c->sent = 0; c->data = r; r->connection = c; @@ -239,7 +289,7 @@ static void ngx_http_process_request_line(ngx_event_t *rev) /* the request line has been parsed successfully */ - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); if (r->http_version >= NGX_HTTP_VERSION_10 && cscf->large_client_header == 0 @@ -269,7 +319,7 @@ static void ngx_http_process_request_line(ngx_event_t *rev) ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1); -#if 1 /* needed to log url on errors in proxy only ? */ +#if 1 /* THINK: needed to log url on errors in proxy only ? */ /* copy unparsed URI */ @@ -353,12 +403,6 @@ static void ngx_http_process_request_line(ngx_event_t *rev) #endif if (r->http_version == NGX_HTTP_VERSION_9) { - if (ngx_http_find_server_conf(r) == NGX_ERROR) { - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); - ngx_http_close_connection(c); - return; - } - rev->event_handler = ngx_http_block_read; ngx_http_handler(r); return; @@ -400,7 +444,7 @@ static void ngx_http_process_request_line(ngx_event_t *rev) are enabled otherwise a request line had been already copied to the start of the r->header_in hunk in ngx_http_set_keepalive() */ - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); if (cscf->large_client_header) { offset = r->request_start - r->header_in->start; @@ -446,7 +490,7 @@ static void ngx_http_process_request_headers(ngx_event_t *rev) ngx_table_elt_t *h; ngx_connection_t *c; ngx_http_request_t *r; - ngx_http_log_ctx_t *ctx; + ngx_http_server_name_t *name; ngx_http_core_srv_conf_t *cscf; c = rev->data; @@ -460,6 +504,8 @@ static void ngx_http_process_request_headers(ngx_event_t *rev) return; } + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); + rc = NGX_AGAIN; for ( ;; ) { @@ -490,8 +536,6 @@ static void ngx_http_process_request_headers(ngx_event_t *rev) /* if the large client headers are enabled then we need to copy the header name and value */ - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); - if (cscf->large_client_header) { h->key.data = ngx_palloc(r->pool, h->key.len + 1 + h->value.len + 1); @@ -532,6 +576,8 @@ static void ngx_http_process_request_headers(ngx_event_t *rev) r->header_in->pos = r->header_in->last = r->header_in->start; } + continue; + } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { /* a whole header has been parsed successfully */ @@ -546,6 +592,24 @@ static void ngx_http_process_request_headers(ngx_event_t *rev) } r->headers_in.host_name_len = len; + /* find the name based server configuration */ + + name = r->virtual_names->elts; + for (i = 0; i < r->virtual_names->nelts; i++) { + if (r->headers_in.host_name_len != name[i].name.len) { + continue; + } + + if (ngx_strncasecmp(r->headers_in.host->value.data, + name[i].name.data, + r->headers_in.host_name_len) == 0) + { + r->srv_conf = name[i].core_srv_conf->ctx->srv_conf; + r->loc_conf = name[i].core_srv_conf->ctx->loc_conf; + break; + } + } + } else { if (r->http_version > NGX_HTTP_VERSION_10) { ngx_http_header_parse_error(r, @@ -568,12 +632,6 @@ static void ngx_http_process_request_headers(ngx_event_t *rev) } } - if (ngx_http_find_server_conf(r) == NGX_ERROR) { - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); - ngx_http_close_connection(c); - return; - } - rev->event_handler = ngx_http_block_read; ngx_http_handler(r); return; @@ -595,8 +653,6 @@ static void ngx_http_process_request_headers(ngx_event_t *rev) /* if the large client headers are enabled then we need to compact r->header_in hunk */ - cscf = ngx_http_get_module_main_conf(r, ngx_http_core_module_ctx); - if (cscf->large_client_header) { offset = r->header_name_start - r->header_in->start; @@ -653,7 +709,7 @@ static ssize_t ngx_http_read_request_header(ngx_http_request_t *r) rev->timer_set = 1; } - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); ngx_add_timer(rev, cscf->client_header_timeout); r->header_timeout_set = 1; @@ -758,9 +814,8 @@ void ngx_http_set_write_handler(ngx_http_request_t *r) return; } - clcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r->main ? r->main : r, - ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r, + ngx_http_core_module); ngx_add_timer(wev, clcf->send_timeout); wev->timer_set = 1; @@ -799,10 +854,10 @@ static void ngx_http_writer(ngx_event_t *wev) ngx_event_t *rev; ngx_connection_t *c; ngx_http_request_t *r; - ngx_http_core_loc_conf_t *lcf; + ngx_http_core_loc_conf_t *clcf; - c = (ngx_connection_t *) wev->data; - r = (ngx_http_request_t *) c->data; + c = wev->data; + r = c->data; rc = ngx_http_output_filter(r, NULL); @@ -810,16 +865,15 @@ static void ngx_http_writer(ngx_event_t *wev) if (rc == NGX_AGAIN) { - lcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r->main ? r->main : r, - ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r, + ngx_http_core_module); if (wev->timer_set) { ngx_del_timer(wev); } else { wev->timer_set = 1; } - ngx_add_timer(wev, lcf->send_timeout); + ngx_add_timer(wev, clcf->send_timeout); return; } @@ -941,8 +995,8 @@ static void ngx_http_read_discarded_body_event(ngx_event_t *rev) ngx_connection_t *c; ngx_http_request_t *r; - c = (ngx_connection_t *) rev->data; - r = (ngx_http_request_t *) c->data; + c = rev->data; + r = c->data; rc = ngx_http_read_discarded_body(r); @@ -957,23 +1011,22 @@ static int ngx_http_read_discarded_body(ngx_http_request_t *r) { size_t size; ssize_t n; - ngx_http_core_loc_conf_t *lcf; + ngx_http_core_loc_conf_t *clcf; ngx_log_debug(r->connection->log, "http read discarded body"); - lcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (r->discarded_buffer == NULL) { - r->discarded_buffer = ngx_palloc(r->pool, lcf->discarded_buffer_size); + r->discarded_buffer = ngx_palloc(r->pool, clcf->discarded_buffer_size); if (r->discarded_buffer == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } } size = r->headers_in.content_length_n; - if (size > lcf->discarded_buffer_size) { - size = lcf->discarded_buffer_size; + if (size > clcf->discarded_buffer_size) { + size = clcf->discarded_buffer_size; } n = ngx_event_recv(r->connection, r->discarded_buffer, size); @@ -1001,7 +1054,7 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) ngx_http_core_srv_conf_t *cscf; ngx_http_core_loc_conf_t *clcf; - c = (ngx_connection_t *) r->connection; + c = r->connection; rev = c->read; ngx_log_debug(c->log, "set http keepalive handler"); @@ -1016,8 +1069,7 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) rev->timer_set = 1; } - clcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); ngx_add_timer(rev, clcf->keepalive_timeout); @@ -1045,7 +1097,7 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) This copy should be rare because clients that support pipelined requests (Mozilla 1.x, Opera 6.x) are still rare */ - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module_ctx); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); if (!cscf->large_client_header) { len = h->last - h->pos; @@ -1054,6 +1106,8 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) h->last = h->start + len; } + ngx_log_debug(c->log, "pipelined request"); + c->pipeline = 1; ctx->action = "reading client pipelined request line"; ngx_http_init_request(rev); @@ -1140,15 +1194,14 @@ static void ngx_http_set_lingering_close(ngx_http_request_t *r) { ngx_event_t *rev; ngx_connection_t *c; - ngx_http_core_loc_conf_t *lcf; + ngx_http_core_loc_conf_t *clcf; c = r->connection; rev = c->read; - lcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - r->lingering_time = ngx_time() + lcf->lingering_time / 1000; + r->lingering_time = ngx_time() + clcf->lingering_time / 1000; rev->event_handler = ngx_http_lingering_close_handler; if (rev->timer_set) { @@ -1157,7 +1210,7 @@ static void ngx_http_set_lingering_close(ngx_http_request_t *r) rev->timer_set = 1; } - ngx_add_timer(rev, lcf->lingering_timeout); + ngx_add_timer(rev, clcf->lingering_timeout); if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) { if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) { @@ -1201,10 +1254,10 @@ static void ngx_http_lingering_close_handler(ngx_event_t *rev) ngx_msec_t timer; ngx_connection_t *c; ngx_http_request_t *r; - ngx_http_core_loc_conf_t *lcf; + ngx_http_core_loc_conf_t *clcf; - c = (ngx_connection_t *) rev->data; - r = (ngx_http_request_t *) c->data; + c = rev->data; + r = c->data; ngx_log_debug(c->log, "http lingering close handler"); @@ -1221,8 +1274,7 @@ static void ngx_http_lingering_close_handler(ngx_event_t *rev) return; } - lcf = (ngx_http_core_loc_conf_t *) - ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (r->discarded_buffer == NULL) { @@ -1231,12 +1283,12 @@ static void ngx_http_lingering_close_handler(ngx_event_t *rev) instead of r->header_in->last */ if ((size_t)(r->header_in->end - r->header_in->last) - >= lcf->discarded_buffer_size) { + >= clcf->discarded_buffer_size) { r->discarded_buffer = r->header_in->last; } else { r->discarded_buffer = ngx_palloc(c->pool, - lcf->discarded_buffer_size); + clcf->discarded_buffer_size); if (r->discarded_buffer) { ngx_http_close_request(r, 0); ngx_http_close_connection(c); @@ -1246,7 +1298,7 @@ static void ngx_http_lingering_close_handler(ngx_event_t *rev) } do { - n = ngx_event_recv(c, r->discarded_buffer, lcf->discarded_buffer_size); + n = ngx_event_recv(c, r->discarded_buffer, clcf->discarded_buffer_size); ngx_log_debug(c->log, "lingering read: %d" _ n); @@ -1259,8 +1311,8 @@ static void ngx_http_lingering_close_handler(ngx_event_t *rev) } while (rev->ready); timer *= 1000; - if (timer > lcf->lingering_timeout) { - timer = lcf->lingering_timeout; + if (timer > clcf->lingering_timeout) { + timer = clcf->lingering_timeout; } if (rev->timer_set) { @@ -1334,7 +1386,7 @@ void ngx_http_close_connection(ngx_connection_t *c) c->write->timer_set = 0; } - if (1) { + if (ngx_del_conn) { ngx_del_conn(c); } else { diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c index 3ad260eab..fd26fedde 100644 --- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -19,8 +19,6 @@ static int ngx_http_header_filter(ngx_http_request_t *r); static ngx_http_module_t ngx_http_header_filter_module_ctx = { - NGX_HTTP_MODULE, - NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -33,10 +31,10 @@ static ngx_http_module_t ngx_http_header_filter_module_ctx = { ngx_module_t ngx_http_header_filter_module = { + NGX_MODULE, &ngx_http_header_filter_module_ctx, /* module context */ - 0, /* module index */ NULL, /* module directives */ - NGX_HTTP_MODULE_TYPE, /* module type */ + NGX_HTTP_MODULE, /* module type */ ngx_http_header_filter_init /* init module */ }; @@ -47,30 +45,41 @@ static char server_string[] = "Server: " NGINX_VER CRLF; static ngx_str_t http_codes[] = { ngx_string("200 OK"), + ngx_null_string, /* "201 Created" */ + ngx_null_string, /* "202 Accepted" */ + ngx_null_string, /* "203 Non-Authoritative Information" */ + ngx_null_string, /* "204 No Content" */ + ngx_null_string, /* "205 Reset Content" */ + ngx_string("206 Partial Content"), + ngx_null_string, /* "207 Multi-Status" */ + +#if 0 + ngx_null_string, /* "300 Multiple Choices" */ +#endif ngx_string("301 Moved Permanently"), ngx_string("302 Moved Temporarily"), - ngx_null_string, /* 303 */ + ngx_null_string, /* "303 See Other" */ ngx_string("304 Not Modified"), ngx_string("400 Bad Request"), - ngx_null_string, /* 401 */ - ngx_null_string, /* 402 */ + ngx_string("401 Unauthorized"), + ngx_null_string, /* "402 Payment Required" */ ngx_string("403 Forbidden"), ngx_string("404 Not Found"), - ngx_null_string, /* 405 */ - ngx_null_string, /* 406 */ - ngx_null_string, /* 407 */ + ngx_string("405 Not Allowed"), + ngx_null_string, /* "406 Not Acceptable" */ + ngx_null_string, /* "407 Proxy Authentication Required" */ ngx_string("408 Request Time-out"), - ngx_null_string, /* 409 */ - ngx_null_string, /* 410 */ + ngx_null_string, /* "409 Conflict" */ + ngx_null_string, /* "410 Gone" */ ngx_string("411 Length Required"), - ngx_null_string, /* 412 */ + ngx_null_string, /* "412 Precondition Failed" */ ngx_string("413 Request Entity Too Large"), ngx_null_string, /* "414 Request-URI Too Large" but we never send it because we treat such requests as the HTTP/0.9 requests and send only the body without the header */ - ngx_null_string, /* 415 */ + ngx_null_string, /* "415 Unsupported Media Type" */ ngx_string("416 Requested Range Not Satisfiable"), ngx_string("500 Internal Server Error"), @@ -84,7 +93,7 @@ static ngx_str_t http_codes[] = { static int ngx_http_header_filter(ngx_http_request_t *r) { - int len, status, i; + int len, status, text, i; time_t ims; ngx_hunk_t *h; ngx_chain_t *ch; @@ -94,6 +103,10 @@ static int ngx_http_header_filter(ngx_http_request_t *r) return NGX_OK; } + if (r->method == NGX_HTTP_HEAD) { + r->header_only = 1; + } + /* 9 is for "HTTP/1.x ", 2 is for trailing "\r\n" and 2 is for end of header */ len = 9 + 2 + 2; @@ -132,17 +145,17 @@ static int ngx_http_header_filter(ngx_http_request_t *r) } else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST) { /* 3XX */ - status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY + 1; + status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY + 8; r->header_only = 1; } else if (r->headers_out.status < NGX_HTTP_INTERNAL_SERVER_ERROR) { /* 4XX */ - status = r->headers_out.status - NGX_HTTP_BAD_REQUEST + 1 + 4; + status = r->headers_out.status - NGX_HTTP_BAD_REQUEST + 8 + 4; } else { /* 5XX */ status = r->headers_out.status - - NGX_HTTP_INTERNAL_SERVER_ERROR + 1 + 4 + 17; + - NGX_HTTP_INTERNAL_SERVER_ERROR + 8 + 4 + 17; } len += http_codes[status].len; @@ -159,31 +172,55 @@ static int ngx_http_header_filter(ngx_http_request_t *r) len += r->headers_out.date->key.len + r->headers_out.date->value.len + 2; } else { - /* "Date: ... \r\n"; */ + /* "Date: ... \r\n" */ len += 37; } - /* 2^64 is 20 characters */ if (r->headers_out.content_length >= 0) { + /* "Content-Length: ... \r\n", 2^64 is 20 characters */ len += 48; } -#if 0 - if (r->headers_out.content_type.len) - len += r->headers_out.content_type.len + 16; -#endif + text = 0; + if (r->headers_out.content_type && r->headers_out.content_type->value.len) { + r->headers_out.content_type->key.len = 0; + len += 16 + r->headers_out.content_type->value.len; + if (ngx_strncasecmp(r->headers_out.content_type->value.data, + "text/", 5) == 0) { + text = 1; + /* "; charset=koi8-r" */ + len += 16; + } + } + + if (r->headers_out.location + && r->headers_out.location->value.len + && r->headers_out.location->value.data[0] == '/') + { + r->headers_out.location->key.len = 0; + /* "Location: http:// ... \r\n" */ + len += 17 + r->server_name->len + + r->headers_out.location->value.len + 2; + + if (r->port != 80) { + len += r->port_name->len; + } + } if (r->headers_out.last_modified && r->headers_out.last_modified->key.len) { len += r->headers_out.last_modified->key.len + r->headers_out.last_modified->value.len + 2; + } else if (r->headers_out.last_modified_time != -1) { - /* "Last-Modified: ... \r\n"; */ + /* "Last-Modified: ... \r\n" */ len += 46; } if (r->keepalive == 0) { + /* "Connection: close\r\n" */ len += 19; } else { + /* "Connection: keep-alive\r\n" */ len += 24; } @@ -199,30 +236,25 @@ static int ngx_http_header_filter(ngx_http_request_t *r) ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 64), NGX_ERROR); /* "HTTP/1.x " */ - ngx_memcpy(h->last, "HTTP/1.1 ", 9); - h->last += 9; + h->last = ngx_cpymem(h->last, "HTTP/1.1 ", 9); /* status line */ if (r->headers_out.status_line.len) { - ngx_memcpy(h->last, r->headers_out.status_line.data, - r->headers_out.status_line.len); - h->last += r->headers_out.status_line.len; + h->last = ngx_cpymem(h->last, r->headers_out.status_line.data, + r->headers_out.status_line.len); } else { - ngx_memcpy(h->last, http_codes[status].data, - http_codes[status].len); - h->last += http_codes[status].len; + h->last = ngx_cpymem(h->last, http_codes[status].data, + http_codes[status].len); } *(h->last++) = CR; *(h->last++) = LF; if (!(r->headers_out.server && r->headers_out.server->key.len)) { - ngx_memcpy(h->last, server_string, sizeof(server_string) - 1); - h->last += sizeof(server_string) - 1; + h->last = ngx_cpymem(h->last, server_string, sizeof(server_string) - 1); } if (!(r->headers_out.date && r->headers_out.date->key.len)) { - ngx_memcpy(h->last, "Date: ", 6); - h->last += 6; + h->last = ngx_cpymem(h->last, "Date: ", 6); h->last += ngx_http_get_time(h->last, time(NULL)); *(h->last++) = CR; *(h->last++) = LF; } @@ -230,39 +262,54 @@ static int ngx_http_header_filter(ngx_http_request_t *r) /* 2^64 is 20 characters */ if (r->headers_out.content_length >= 0) { h->last += ngx_snprintf(h->last, 49, - "Content-Length: " OFF_FMT CRLF, - r->headers_out.content_length); + "Content-Length: " OFF_FMT CRLF, + r->headers_out.content_length); } -#if 0 - if (r->headers_out.content_type.len) { - ngx_memcpy(h->last, "Content-Type: ", 14); - h->last += 14; - ngx_memcpy(h->last, r->headers_out.content_type.data, - r->headers_out.content_type.len); - h->last += r->headers_out.content_type.len; + if (r->headers_out.content_type && r->headers_out.content_type->value.len) { + h->last = ngx_cpymem(h->last, "Content-Type: ", 14); + h->last = ngx_cpymem(h->last, r->headers_out.content_type->value.data, + r->headers_out.content_type->value.len); + + if (text) { + h->last = ngx_cpymem(h->last, "; charset=koi8-r", 16); + } + + *(h->last++) = CR; *(h->last++) = LF; + } + + if (r->headers_out.location + && r->headers_out.location->value.len + && r->headers_out.location->value.data[0] == '/') + { + h->last = ngx_cpymem(h->last, "Location: http://", 17); + h->last = ngx_cpymem(h->last, r->server_name->data, + r->server_name->len); + if (r->port != 80) { + h->last = ngx_cpymem(h->last, r->port_name->data, + r->port_name->len); + } + + h->last = ngx_cpymem(h->last, r->headers_out.location->value.data, + r->headers_out.location->value.len); + *(h->last++) = CR; *(h->last++) = LF; } -#endif - if (!(r->headers_out.last_modified - && r->headers_out.last_modified->key.len) + if (!(r->headers_out.last_modified && r->headers_out.last_modified->key.len) && r->headers_out.last_modified_time != -1) { - ngx_memcpy(h->last, "Last-Modified: ", 15); - h->last += 15; + h->last = ngx_cpymem(h->last, "Last-Modified: ", 15); h->last += ngx_http_get_time(h->last, r->headers_out.last_modified_time); *(h->last++) = CR; *(h->last++) = LF; } if (r->keepalive == 0) { - ngx_memcpy(h->last, "Connection: close" CRLF, 19); - h->last += 19; + h->last = ngx_cpymem(h->last, "Connection: close" CRLF, 19); } else { - ngx_memcpy(h->last, "Connection: keep-alive" CRLF, 24); - h->last += 24; + h->last = ngx_cpymem(h->last, "Connection: keep-alive" CRLF, 24); } for (i = 0; i < r->headers_out.headers->nelts; i++) { @@ -270,12 +317,11 @@ static int ngx_http_header_filter(ngx_http_request_t *r) continue; } - ngx_memcpy(h->last, header[i].key.data, header[i].key.len); - h->last += header[i].key.len; + h->last = ngx_cpymem(h->last, header[i].key.data, header[i].key.len); *(h->last++) = ':' ; *(h->last++) = ' ' ; - ngx_memcpy(h->last, header[i].value.data, header[i].value.len); - h->last += header[i].value.len; + h->last = ngx_cpymem(h->last, header[i].value.data, + header[i].value.len); *(h->last++) = CR; *(h->last++) = LF; } @@ -284,7 +330,7 @@ static int ngx_http_header_filter(ngx_http_request_t *r) ngx_log_debug(r->connection->log, "%s\n" _ h->pos); /**/ - /* end of HTTP header */ + /* the end of HTTP header */ *(h->last++) = CR; *(h->last++) = LF; if (r->header_only) { diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c index d85a124f8..0d91e1bf3 100644 --- a/src/http/ngx_http_output_filter.c +++ b/src/http/ngx_http_output_filter.c @@ -16,8 +16,6 @@ static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src); static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool); static char *ngx_http_output_filter_merge_conf(ngx_pool_t *pool, void *parent, void *child); -static void ngx_http_output_filter_init(ngx_pool_t *pool, - ngx_http_conf_filter_t *cf); static ngx_command_t ngx_http_output_filter_commands[] = { @@ -29,13 +27,11 @@ static ngx_command_t ngx_http_output_filter_commands[] = { offsetof(ngx_http_output_filter_conf_t, hunk_size), NULL}, - {ngx_null_string, 0, NULL, 0, 0, NULL} + ngx_null_command }; static ngx_http_module_t ngx_http_output_filter_module_ctx = { - NGX_HTTP_MODULE, - NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -48,10 +44,10 @@ static ngx_http_module_t ngx_http_output_filter_module_ctx = { ngx_module_t ngx_http_output_filter_module = { + NGX_MODULE, &ngx_http_output_filter_module_ctx, /* module context */ - 0, /* module index */ ngx_http_output_filter_commands, /* module directives */ - NGX_HTTP_MODULE_TYPE, /* module type */ + NGX_HTTP_MODULE, /* module type */ NULL /* init module */ }; @@ -73,12 +69,11 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk) ngx_http_output_filter_ctx_t *ctx; ngx_http_output_filter_conf_t *conf; - ctx = (ngx_http_output_filter_ctx_t *) - ngx_http_get_module_ctx(r->main ? r->main : r, - ngx_http_output_filter_module_ctx); + ctx = ngx_http_get_module_ctx(r->main ? r->main : r, + 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), NGX_ERROR); } @@ -117,9 +112,8 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk) /* allocate our hunk if it's needed */ if (ctx->hunk == NULL) { - conf = (ngx_http_output_filter_conf_t *) - ngx_http_get_module_loc_conf(r->main ? r->main : r, - ngx_http_output_filter_module_ctx); + conf = ngx_http_get_module_loc_conf(r->main ? r->main : r, + ngx_http_output_filter_module); if (hunk->type & NGX_HUNK_LAST) { if (hunk->type & NGX_HUNK_IN_MEMORY) { @@ -307,22 +301,12 @@ ngx_log_debug(src->file->log, "READ: %qd:%qd %X:%X %X:%X" _ } -static void ngx_http_output_filter_init(ngx_pool_t *pool, - ngx_http_conf_filter_t *cf) -{ -#if 0 - next_filter = cf->output_body_filter; - cf->output_body_filter = NULL; -#endif -} - - static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool) { ngx_http_output_filter_conf_t *conf; ngx_test_null(conf, - ngx_pcalloc(pool, sizeof(ngx_http_output_filter_conf_t)), + ngx_palloc(pool, sizeof(ngx_http_output_filter_conf_t)), NULL); conf->hunk_size = NGX_CONF_UNSET; @@ -334,10 +318,8 @@ static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool) static char *ngx_http_output_filter_merge_conf(ngx_pool_t *pool, void *parent, void *child) { - ngx_http_output_filter_conf_t *prev = - (ngx_http_output_filter_conf_t *) parent; - ngx_http_output_filter_conf_t *conf = - (ngx_http_output_filter_conf_t *) child; + ngx_http_output_filter_conf_t *prev = parent; + ngx_http_output_filter_conf_t *conf = child; ngx_conf_merge_size_value(conf->hunk_size, prev->hunk_size, 32768); diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h index c77fa288e..15898e868 100644 --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -49,6 +49,7 @@ #define NGX_HTTP_BAD_REQUEST 400 #define NGX_HTTP_FORBIDDEN 403 #define NGX_HTTP_NOT_FOUND 404 +#define NGX_HTTP_NOT_ALLOWED 405 #define NGX_HTTP_REQUEST_TIME_OUT 408 #define NGX_HTTP_REQUEST_URI_TOO_LARGE 414 @@ -154,10 +155,11 @@ struct ngx_http_request_s { ngx_http_request_t *main; - u_int in_addr; - - int port; - ngx_str_t port_name; + u_int in_addr; + int port; + ngx_str_t *port_name; /* ":80" */ + ngx_str_t *server_name; + ngx_array_t *virtual_names; int filter; diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c index 8c86b2437..4d9bba99f 100644 --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -39,6 +39,14 @@ static char error_404_page[] = ; +static char error_405_page[] = +"<html>" CRLF +"<head><title>405 Not Allowed</title></head>" CRLF +"<body bgcolor=\"white\">" CRLF +"<center><h1>405 Not Allowed</h1></center>" CRLF +; + + static char error_408_page[] = "<html>" CRLF "<head><title>408 Request Time-out</title></head>" CRLF @@ -89,7 +97,7 @@ static ngx_str_t error_pages[] = { ngx_null_string, /* 402 */ ngx_string(error_403_page), ngx_string(error_404_page), - ngx_null_string, /* 405 */ + ngx_string(error_405_page), ngx_null_string, /* 406 */ ngx_null_string, /* 407 */ ngx_string(error_408_page), diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c index 81cf19cf8..184443887 100644 --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -28,13 +28,11 @@ static ngx_command_t ngx_http_write_filter_commands[] = { offsetof(ngx_http_write_filter_conf_t, buffer_output), NULL}, - {ngx_null_string, 0, NULL, 0, 0, NULL} + ngx_null_command }; ngx_http_module_t ngx_http_write_filter_module_ctx = { - NGX_HTTP_MODULE, - NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -47,10 +45,10 @@ ngx_http_module_t ngx_http_write_filter_module_ctx = { ngx_module_t ngx_http_write_filter_module = { + NGX_MODULE, &ngx_http_write_filter_module_ctx, /* module context */ - 0, /* module index */ ngx_http_write_filter_commands, /* module directives */ - NGX_HTTP_MODULE_TYPE, /* module type */ + NGX_HTTP_MODULE, /* module type */ ngx_http_write_filter_init /* init module */ }; @@ -63,12 +61,11 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) ngx_http_write_filter_ctx_t *ctx; ngx_http_write_filter_conf_t *conf; - ctx = 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), NGX_ERROR); } @@ -122,7 +119,7 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) } conf = 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, |