# HG changeset patch # User Igor Sysoev # Date 1072384018 0 # Node ID f1d0e5f09c1e42833838ca535423694e497082b7 # Parent 5adc2b75f8a5d7a01c58e3fb0e6e10688ee49c26 nginx-0.0.1-2003-12-25-23:26:58 import diff --git a/auto/lib/md5/makefile.msvc b/auto/lib/md5/makefile.msvc --- a/auto/lib/md5/makefile.msvc +++ b/auto/lib/md5/makefile.msvc @@ -1,4 +1,5 @@ all: - cl -nologo -c -MT -O2 -D MD5_ASM -D L_ENDIAN md5_dgst.c md5_one.c + cl -nologo -c -MT -O2 -Ob1 -Oi -Gs -D MD5_ASM -D L_ENDIAN \ + md5_dgst.c md5_one.c link -lib -out:md5.lib md5_dgst.obj md5_one.obj asm/m-win32.obj diff --git a/auto/make b/auto/make --- a/auto/make +++ b/auto/make @@ -11,6 +11,11 @@ HTTP_FILTER_MODULES="$HTTP_FILTER_MODULE HTTP_MODULES="$HTTP_MODULES $HTTP_STATIC_MODULE $HTTP_INDEX_MODULE" +if [ $HTTP_REWRITE = YES ]; then + HTTP_MODULES="$HTTP_MODULES $HTTP_REWRITE_MODULE" + HTTP_SRCS="$HTTP_SRCS $HTTP_REWRITE_SRCS" +fi + if [ $HTTP_GZIP = YES ]; then HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_GZIP_FILTER_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_GZIP_SRCS" diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -6,6 +6,7 @@ OBJS=objs TEST_BUILD_DEVPOLL=NO +HTTP_REWRITE=YES HTTP_GZIP=YES HTTP_PROXY=YES @@ -34,6 +35,7 @@ do --builddir=*) OBJS="$value" ;; + --without-http_rewrite_module) HTTP_REWRITE=NO ;; --without-http_gzip_module) HTTP_GZIP=NO ;; --without-http_proxy_module) HTTP_PROXY=NO ;; diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -193,6 +193,10 @@ HTTP_SRCS="src/http/ngx_http.c \ src/http/modules/ngx_http_not_modified_filter.c" +HTTP_REWRITE_MODULE=ngx_http_rewrite_module +HTTP_REWRITE_SRCS=src/http/modules/ngx_http_rewrite_handler.c + + HTTP_GZIP_FILTER_MODULE=ngx_http_gzip_filter_module HTTP_GZIP_SRCS=src/http/modules/ngx_http_gzip_filter.c HTTP_GZIP_UNIX_LIBS=-lz diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -204,11 +204,13 @@ int main(int argc, char *const *argv) ngx_process_events(cycle->log); if (done) { +#if !(WIN32) if (ngx_delete_file(pidfile.name.data) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_delete_file_n " \"%s\" failed", pidfile.name.data); } +#endif ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting"); @@ -291,11 +293,11 @@ ngx_log_debug(log, "REOPEN: %d:%d:%s" _ static ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle, ngx_log_t *log) { int i, n, failed; - ngx_fd_t fd; ngx_str_t conf_file; ngx_conf_t conf; ngx_pool_t *pool; ngx_cycle_t *cycle, **old; + ngx_socket_t fd; ngx_core_conf_t *ccf; ngx_open_file_t *file; ngx_listening_t *ls, *nls; @@ -457,7 +459,7 @@ ngx_log_debug(log, "OPEN: %d:%s" _ file[ fd /= 4; #endif - if (fd >= cycle->connection_n) { + if (fd >= (ngx_socket_t) cycle->connection_n) { ngx_log_error(NGX_LOG_EMERG, log, 0, "%d connections is not enough to hold " "an open listening socket on %s, " 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 @@ -24,8 +24,9 @@ #define NGX_CONF_TAKE9 0x00000200 #define NGX_CONF_TAKE12 (NGX_CONF_TAKE1|NGX_CONF_TAKE2) +#define NGX_CONF_TAKE13 (NGX_CONF_TAKE1|NGX_CONF_TAKE3) -#define NGX_CONF_TAKE13 (NGX_CONF_TAKE1|NGX_CONF_TAKE3) +#define NGX_CONF_TAKE23 (NGX_CONF_TAKE2|NGX_CONF_TAKE3) #define NGX_CONF_TAKE1234 (NGX_CONF_TAKE1|NGX_CONF_TAKE2|NGX_CONF_TAKE3 \ |NGX_CONF_TAKE4) diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -81,7 +81,7 @@ struct ngx_connection_s { ngx_hunk_t *buffer; - int number; + ngx_int_t number; unsigned pipeline:1; unsigned unexpected_eof:1; diff --git a/src/core/ngx_regex.c b/src/core/ngx_regex.c --- a/src/core/ngx_regex.c +++ b/src/core/ngx_regex.c @@ -45,11 +45,12 @@ ngx_regex_t *ngx_regex_compile(ngx_str_t } -ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s) +ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, + int *matches, ngx_int_t size) { int rc; - rc = pcre_exec(re, NULL, s->data, s->len, 0, 0, NULL, 0); + rc = pcre_exec(re, NULL, s->data, s->len, 0, 0, matches, size); if (rc == -1) { return NGX_DECLINED; diff --git a/src/core/ngx_regex.h b/src/core/ngx_regex.h --- a/src/core/ngx_regex.h +++ b/src/core/ngx_regex.h @@ -15,7 +15,8 @@ typedef pcre ngx_regex_t; void ngx_regex_init(); ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, ngx_pool_t *pool, ngx_str_t *err); -ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s); +ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, + int *matches, ngx_int_t size); #define ngx_regex_exec_n "pcre_exec()" diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -8,6 +8,7 @@ extern ngx_module_t ngx_select_module; +extern ngx_event_module_t ngx_select_module_ctx; #if (HAVE_KQUEUE) #include diff --git a/src/http/modules/ngx_http_rewrite_handler.c b/src/http/modules/ngx_http_rewrite_handler.c new file mode 100644 --- /dev/null +++ b/src/http/modules/ngx_http_rewrite_handler.c @@ -0,0 +1,340 @@ + +#include +#include +#include + + +#define NGX_HTTP_REWRITE_COPY_MATCH 0 +#define NGX_HTTP_REWRITE_COPY_SHORT 1 +#define NGX_HTTP_REWRITE_COPY_LONG 2 + + +typedef struct { + ngx_int_t op; + size_t len; + uintptr_t data; +} ngx_http_rewrite_op_t; + + +typedef struct { + ngx_regex_t *regex; + ngx_uint_t msize; + + ngx_array_t ops; + ngx_uint_t size; + + ngx_str_t re_name; + ngx_str_t s_name; + + unsigned last:1; +} ngx_http_rewrite_rule_t; + + +typedef struct { + ngx_array_t rules; + unsigned log:1; +} ngx_http_rewrite_srv_conf_t; + + +static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf); +static char *ngx_http_rewrite_rule(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle); + + +static ngx_command_t ngx_http_rewrite_commands[] = { + + { ngx_string("rewrite"), + NGX_HTTP_SRV_CONF|NGX_CONF_TAKE23, + ngx_http_rewrite_rule, + NGX_HTTP_SRV_CONF_OFFSET, + 0, + NULL }, + + ngx_null_command +}; + + +ngx_http_module_t ngx_http_rewrite_module_ctx = { + NULL, /* pre conf */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + ngx_http_rewrite_create_loc_conf, /* create server configuration */ + NULL, /* merge server configuration */ + + NULL, /* create location configration */ + NULL, /* merge location configration */ +}; + + +ngx_module_t ngx_http_rewrite_module = { + NGX_MODULE, + &ngx_http_rewrite_module_ctx, /* module context */ + ngx_http_rewrite_commands, /* module directives */ + NGX_HTTP_MODULE, /* module type */ + ngx_http_rewrite_init, /* init module */ + NULL /* init child */ +}; + + +static ngx_int_t ngx_http_rewrite_handler(ngx_http_request_t *r) +{ + int *matches; + char *p; + size_t len; + uintptr_t data; + ngx_int_t rc, i, n, m; + ngx_str_t uri; + ngx_http_rewrite_op_t *op; + ngx_http_rewrite_rule_t *rule; + ngx_http_rewrite_srv_conf_t *scf; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http rewrite handler"); + + scf = ngx_http_get_module_srv_conf(r, ngx_http_rewrite_module); + + rule = scf->rules.elts; + for (i = 0; i < scf->rules.nelts; i++) { + + if (rule[i].msize) { + if (!(matches = ngx_palloc(r->pool, rule[i].msize * sizeof(int)))) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + } else { + matches = NULL; + } + + rc = ngx_regex_exec(rule[i].regex, &r->uri, matches, rule[i].msize); + + if (rc == NGX_DECLINED) { + if (scf->log) { + ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, + "\"%s\" is not matched", rule[i].re_name.data); + } + + continue; + } + + if (rc < 0) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + ngx_regex_exec_n + " failed: %d on \"%s\" using \"%s\"", + rc, r->uri.data, rule[i].re_name.data); + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + if (scf->log) { + ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, + "\"%s\" matched", rule[i].re_name.data); + } + + uri.len = rule[i].size; + + for (n = 1; n < rc; n++) { + uri.len += matches[2 * n + 1] - matches[2 * n]; + } + + if (!(uri.data = ngx_palloc(r->pool, uri.len + 1))) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + p = uri.data; + + op = rule[i].ops.elts; + for (n = 0; n < rule[i].ops.nelts; n++) { + if (op[n].op == NGX_HTTP_REWRITE_COPY_SHORT) { + len = op[n].len; + data = op[n].data; + while (len--) { + *p++ = data & 0xff; + data >>= 8; + } + + } else if (op[n].op == NGX_HTTP_REWRITE_COPY_LONG) { + p = ngx_cpymem(p, (void *) op[n].data, op[n].len); + + } else { /* NGX_HTTP_REWRITE_COPY_MATCH */ + m = 2 * op[n].data; + p = ngx_cpymem(p, &r->uri.data[matches[m]], + matches[m + 1] - matches[m]); + } + } + + *p = '\0'; + + if (scf->log) { + ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, + "rewritten uri: \"%s\"", uri.data); + } + + r->uri = uri; + + if (ngx_http_set_exten(r) != NGX_OK) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + if (rule[i].last) { + return NGX_DECLINED; + } + } + + return NGX_DECLINED; +} + + +static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf) +{ + ngx_http_rewrite_srv_conf_t *conf; + + if (!(conf = ngx_palloc(cf->pool, sizeof(ngx_http_rewrite_srv_conf_t)))) { + return NGX_CONF_ERROR; + } + + ngx_init_array(conf->rules, cf->pool, 5, sizeof(ngx_http_rewrite_rule_t), + NGX_CONF_ERROR); + + conf->log = 1; + + return conf; +} + + +static char *ngx_http_rewrite_rule(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf) +{ + ngx_http_rewrite_srv_conf_t *scf = conf; + + char *data, *p; + size_t len; + ngx_str_t *value, err; + ngx_uint_t i; + ngx_http_rewrite_op_t *op; + ngx_http_rewrite_rule_t *rule; + char errstr[NGX_MAX_CONF_ERRSTR]; + + if (!(rule = ngx_push_array(&scf->rules))) { + return NGX_CONF_ERROR; + } + + ngx_init_array(rule->ops, cf->pool, 5, sizeof(ngx_http_rewrite_op_t), + NGX_CONF_ERROR); + + rule->msize = 0; + rule->size = 0; + + value = cf->args->elts; + + /* STUB */ { + err.len = NGX_MAX_CONF_ERRSTR; + err.data = errstr; + + rule->regex = ngx_regex_compile(&value[1], 0, cf->pool, &err); + + if (rule->regex == NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); + return NGX_CONF_ERROR; + } + + rule->re_name = value[1]; + rule->s_name = value[2]; + + for (i = 0; i < value[2].len; /* void */) { + + if (!(op = ngx_push_array(&rule->ops))) { + return NGX_CONF_ERROR; + } + + data = &value[2].data[i]; + + if (value[2].data[i] == '$' + && i < value[2].len + && value[2].data[i + 1] >= '1' + && value[2].data[i + 1] <= '9') + { + op->op = NGX_HTTP_REWRITE_COPY_MATCH; + op->data = value[2].data[++i] - '0'; + + if (rule->msize < op->data) { + rule->msize = op->data; + } + + i++; + + } else { + i++; + + while (i < value[2].len && value[2].data[i] != '$') { + i++; + } + + len = &value[2].data[i] - data; + rule->size += len; + + if (len) { + + op->len = len; + + if (len <= sizeof(uintptr_t)) { + op->op = NGX_HTTP_REWRITE_COPY_SHORT; + op->data = 0; + + while (len--) { + op->data <<= 8; + op->data |= data[len]; + } + + } else { + op->op = NGX_HTTP_REWRITE_COPY_LONG; + + if (!(p = ngx_palloc(cf->pool, len))) { + return NGX_CONF_ERROR; + } + + ngx_memcpy(p, data, len); + op->data = (uintptr_t) p; + } + } + } + } + + rule->msize++; + rule->msize *= 3; + + if (cf->args->nelts > 3) { + if (ngx_strcmp(value[3].data, "last") == 0) { + rule->last = 1; + + } else { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter \"%s\"", value[3].data); + return NGX_CONF_ERROR; + } + } + } + + return NGX_CONF_OK; +} + + +static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle) +{ + ngx_http_handler_pt *h; + ngx_http_conf_ctx_t *ctx; + ngx_http_core_main_conf_t *cmcf; + + ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]; + cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; + + h = ngx_push_array(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers); + if (h == NULL) { + return NGX_ERROR; + } + + *h = ngx_http_rewrite_handler; + + return NGX_OK; +} diff --git a/src/http/modules/ngx_http_status.c b/src/http/modules/ngx_http_status.c new file mode 100644 --- /dev/null +++ b/src/http/modules/ngx_http_status.c @@ -0,0 +1,61 @@ + +#include +#include +#include + + +static ngx_command_t ngx_http_status_commands[] = { + + ngx_null_command +}; + + +ngx_http_module_t ngx_http_status_module_ctx = { + NULL, /* pre conf */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + ngx_http_status_create_loc_conf, /* create location configration */ + ngx_http_status_merge_loc_conf /* merge location configration */ +}; + + +ngx_module_t ngx_http_status_module = { + NGX_MODULE, + &ngx_http_status_module_ctx, /* module context */ + ngx_http_status_commands, /* module directives */ + NGX_HTTP_MODULE, /* module type */ + ngx_http_status_init, /* init module */ + NULL /* init child */ +}; + + +static char http_states = "IRPCUWLK"; + + +int ngx_http_status_handler(ngx_http_request_t *r) +{ + ngx_int_t i, http; + ngx_connection_t *c; + ngx_http_request_t *sr; + + c = ngx_cycle->connections; + + for (i = 0; i < ngx_cycle->connection_n; i++) { + if (c[i].module != http || c[i].data == NULL) { + continue; + } + + if (c[i].data == NULL && c[i].fd != -1) { + 'A' + } + + sr = c[i].data; + } + + return NGX_OK; +} 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 @@ -50,19 +50,19 @@ static char *ngx_http_block(ngx_conf_t * int port_found, addr_found, virtual_names; char *rv; struct sockaddr_in *addr_in; + ngx_conf_t pcf; ngx_array_t in_ports; ngx_listening_t *ls; + ngx_http_listen_t *lscf; ngx_http_module_t *module; - ngx_conf_t pcf; ngx_http_handler_pt *h; ngx_http_conf_ctx_t *ctx; ngx_http_in_port_t *in_port, *inport; ngx_http_in_addr_t *in_addr, *inaddr; - ngx_http_core_main_conf_t *cmcf; + ngx_http_server_name_t *s_name, *name; ngx_http_core_srv_conf_t **cscfp, *cscf; ngx_http_core_loc_conf_t **clcfp, *clcf; - ngx_http_listen_t *lscf; - ngx_http_server_name_t *s_name, *name; + ngx_http_core_main_conf_t *cmcf; #if (WIN32) ngx_iocp_conf_t *iocpcf; #endif 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 @@ -469,7 +469,7 @@ int ngx_http_find_location_config(ngx_ht clcfp[i]->regex ? "~ " : "", clcfp[i]->name.data); - rc = ngx_regex_exec(clcfp[i]->regex, &r->uri); + rc = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0); if (rc == NGX_DECLINED) { continue; @@ -613,11 +613,40 @@ int ngx_http_error(ngx_http_request_t *r } +ngx_int_t ngx_http_set_exten(ngx_http_request_t *r) +{ + ngx_int_t i; + + r->exten.len = 0; + r->exten.data = NULL; + + for (i = r->uri.len - 1; i > 1; i--) { + if (r->uri.data[i] == '.' && r->uri.data[i - 1] != '/') { + r->exten.len = r->uri.len - i - 1; + + if (r->exten.len > 0) { + if (!(r->exten.data = ngx_palloc(r->pool, r->exten.len + 1))) { + return NGX_ERROR; + } + + ngx_cpystrn(r->exten.data, &r->uri.data[i + 1], + r->exten.len + 1); + } + + break; + + } else if (r->uri.data[i] == '/') { + break; + } + } + + return NGX_OK; +} + + int ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args) { - int i; - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "internal redirect: \"%s\"", uri->data); @@ -629,26 +658,8 @@ int ngx_http_internal_redirect(ngx_http_ r->args.data = args->data; } - r->exten.len = 0; - r->exten.data = NULL; - - for (i = uri->len - 1; i > 1; i--) { - if (uri->data[i] == '.' && uri->data[i - 1] != '/') { - r->exten.len = uri->len - i - 1; - - if (r->exten.len > 0) { - ngx_test_null(r->exten.data, - ngx_palloc(r->pool, r->exten.len + 1), - NGX_HTTP_INTERNAL_SERVER_ERROR); - - ngx_cpystrn(r->exten.data, &uri->data[i + 1], r->exten.len + 1); - } - - break; - - } else if (uri->data[i] == '/') { - break; - } + if (ngx_http_set_exten(r) != NGX_OK) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (r->err_ctx) { @@ -872,7 +883,7 @@ static char *ngx_location_block(ngx_conf clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; clcf->loc_conf = ctx->loc_conf; - value = (ngx_str_t *) cf->args->elts; + value = cf->args->elts; if (cf->args->nelts == 3) { if (value[1].len == 1 && value[1].data[0] == '=') { @@ -898,8 +909,7 @@ static char *ngx_location_block(ngx_conf return NGX_CONF_ERROR; } - clcf->name.len = value[2].len; - clcf->name.data = value[2].data; + clcf->name = value[2]; #else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the using of the regex \"%s\" " diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -156,6 +156,7 @@ int ngx_http_find_location_config(ngx_ht int ngx_http_core_translate_handler(ngx_http_request_t *r); ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r); +ngx_int_t ngx_http_set_exten(ngx_http_request_t *r); int ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args); diff --git a/src/http/ngx_http_log_handler.c b/src/http/ngx_http_log_handler.c --- a/src/http/ngx_http_log_handler.c +++ b/src/http/ngx_http_log_handler.c @@ -470,14 +470,14 @@ static char *ngx_http_log_header_out(ngx && ngx_strncasecmp(s->data, "Connection", s->len) == 0) { op->op = ngx_http_log_connection_header_out; - op->data = NULL; + op->data = (uintptr_t) NULL; return NULL; } if (s->len == sizeof("Transfer-Encoding") - 1 && ngx_strncasecmp(s->data, "Transfer-Encoding", s->len) == 0) { op->op = ngx_http_log_transfer_encoding_header_out; - op->data = NULL; + op->data = (uintptr_t) NULL; return NULL; } diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -463,7 +463,7 @@ ngx_int_t ngx_http_parse_header_line(ngx break; } - if (ch == '-') { + if (ch == '-' || ch == '_' || ch == '~') { break; } @@ -489,7 +489,7 @@ ngx_int_t ngx_http_parse_header_line(ngx break; } - if (ch == '-') { + if (ch == '-' || ch == '_' || ch == '~') { break; } diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -142,6 +142,8 @@ static void ngx_http_init_request(ngx_ev } } + r->http_state = NGX_HTTP_INITING_REQUEST_STATE; + /* find the server configuration for the address:port */ /* AF_INET only */ @@ -1519,6 +1521,7 @@ void ngx_http_close_connection(ngx_conne } c->fd = -1; + c->data = NULL; ngx_destroy_pool(c->pool); @@ -1545,13 +1548,13 @@ static void ngx_http_client_error(ngx_ht if (ctx->url) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR], - ctx->client, ctx->url); + client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR], + ctx->client, ctx->url); } else { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR], - ctx->client); + client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR], + ctx->client); } r->connection->log->handler = ngx_http_log_error; diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -64,9 +64,19 @@ #define NGX_HTTP_GATEWAY_TIME_OUT 504 +typedef enum { + NGX_HTTP_INITING_REQUEST_STATE = 0, + NGX_HTTP_READING_REQUEST_STATE, + NGX_HTTP_PROCESS_REQUEST_STATE, -#define NGX_HTTP_STATIC_HANDLER 0 -#define NGX_HTTP_DIRECTORY_HANDLER 1 + NGX_HTTP_CONNECT_UPSTREAM_STATE, + NGX_HTTP_WRITING_UPSTREAM_STATE, + NGX_HTTP_READING_UPSTREAM_STATE, + + NGX_HTTP_WRITING_REQUEST_STATE, + NGX_HTTP_LINGERING_CLOSE_STATE, + NGX_HTTP_KEEPALIVE_STATE +} ngx_http_state_e; typedef struct { @@ -223,6 +233,8 @@ struct ngx_http_request_s { void **err_ctx; int err_status; + unsigned http_state:4; + /* URI is not started with '/' - "GET http://" */ unsigned unusual_uri:1; /* URI with "/.", "%" and on Win32 with "//" */ 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 @@ -10,16 +10,18 @@ typedef int ngx_err_t; #define NGX_ENOENT ENOENT #define NGX_EINTR EINTR +#define NGX_ECHILD ECHILD #define NGX_EACCES EACCES +#define NGX_EBUSY EBUSY #define NGX_EEXIST EEXIST #define NGX_ENOTDIR ENOTDIR +#define NGX_EPIPE EPIPE #define NGX_EAGAIN EWOULDBLOCK #define NGX_EINPROGRESS EINPROGRESS #define NGX_EADDRINUSE EADDRINUSE #define NGX_ECONNRESET ECONNRESET #define NGX_ETIMEDOUT ETIMEDOUT #define NGX_ECANCELED ECANCELED -#define NGX_ECHILD ECHILD #define NGX_ENOMOREFILES 0 diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c --- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c @@ -26,7 +26,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( char *prev; off_t sent, fprev; size_t hsize, fsize, size; - ngx_int_t eintr, eagain; + ngx_int_t eintr, eagain, level; struct iovec *iov; struct sf_hdtr hdtr; ngx_err_t err; @@ -59,6 +59,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( hsize = 0; eintr = 0; eagain = 0; + level = NGX_LOG_CRIT; ngx_init_array(header, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR); @@ -186,10 +187,12 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( if (err == NGX_EINTR) { eintr = 1; - } - if (err == NGX_EAGAIN) { + } else if (err == NGX_EAGAIN) { eagain = 1; + + } else if (err == NGX_EPIPE) { + level = NGX_LOG_INFO; } if (err == NGX_EAGAIN || err == NGX_EINTR) { @@ -199,7 +202,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( } else { wev->error = 1; - ngx_log_error(NGX_LOG_CRIT, c->log, err, + ngx_log_error(level, c->log, err, "sendfile() failed"); return NGX_CHAIN_ERROR; } @@ -217,6 +220,9 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( if (err == NGX_EINTR) { eintr = 1; + + } else if (err == NGX_EPIPE) { + level = NGX_LOG_INFO; } if (err == NGX_EAGAIN || err == NGX_EINTR) { @@ -225,7 +231,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain( } else { wev->error = 1; - ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed"); + ngx_log_error(level, c->log, err, "writev() failed"); return NGX_CHAIN_ERROR; } }