diff options
Diffstat (limited to '')
| -rw-r--r-- | src/http/modules/ngx_http_charset_filter.c | 31 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_chunked_filter.c | 17 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_gzip_filter.c | 18 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_headers_filter.c | 6 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_range_filter.c | 47 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_status_handler.c | 3 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_userid_filter.c | 2 | ||||
| -rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_handler.c | 13 | ||||
| -rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_handler.h | 1 | ||||
| -rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_header.c | 5 | ||||
| -rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_upstream.c | 8 | ||||
| -rw-r--r-- | src/http/ngx_http.c | 274 | ||||
| -rw-r--r-- | src/http/ngx_http_core_module.c | 48 | ||||
| -rw-r--r-- | src/http/ngx_http_core_module.h | 6 | ||||
| -rw-r--r-- | src/http/ngx_http_header_filter.c | 11 | ||||
| -rw-r--r-- | src/http/ngx_http_log_handler.c | 23 | ||||
| -rw-r--r-- | src/http/ngx_http_request.c | 87 | ||||
| -rw-r--r-- | src/http/ngx_http_request.h | 10 | ||||
| -rw-r--r-- | src/http/ngx_http_write_filter.c | 1 |
19 files changed, 433 insertions, 178 deletions
diff --git a/src/http/modules/ngx_http_charset_filter.c b/src/http/modules/ngx_http_charset_filter.c index d22a86b5b..f2e85e530 100644 --- a/src/http/modules/ngx_http_charset_filter.c +++ b/src/http/modules/ngx_http_charset_filter.c @@ -12,7 +12,7 @@ typedef struct { char **tables; ngx_str_t name; - unsigned server; + ngx_uint_t server; /* unsigned server:1; */ } ngx_http_charset_t; @@ -45,7 +45,7 @@ typedef struct { } ngx_http_charset_ctx_t; -static void ngx_charset_recode(ngx_buf_t *b, char *table); +static ngx_uint_t ngx_charset_recode(ngx_buf_t *b, char *table); static char *ngx_charset_map_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -232,14 +232,31 @@ static ngx_int_t ngx_http_charset_body_filter(ngx_http_request_t *r, } -static void ngx_charset_recode(ngx_buf_t *b, char *table) +static ngx_uint_t ngx_charset_recode(ngx_buf_t *b, char *table) { - u_char *p, c; + u_char *p; + ngx_uint_t change; + + change = 0; for (p = b->pos; p < b->last; p++) { - c = *p; - *p = table[c]; + if (*p != table[*p]) { + change = 1; + break; + } } + + if (change) { + + while (p < b->last) { + *p = table[*p]; + p++; + } + + b->in_file = 0; + } + + return change; } @@ -419,7 +436,9 @@ static ngx_int_t ngx_http_add_charset(ngx_array_t *charsets, ngx_str_t *name) return NGX_ERROR; } + c->tables = NULL; c->name = *name; + c->server = 0; return i; } diff --git a/src/http/modules/ngx_http_chunked_filter.c b/src/http/modules/ngx_http_chunked_filter.c index 211246149..7881248cc 100644 --- a/src/http/modules/ngx_http_chunked_filter.c +++ b/src/http/modules/ngx_http_chunked_filter.c @@ -63,7 +63,7 @@ static ngx_int_t ngx_http_chunked_body_filter(ngx_http_request_t *r, ngx_chain_t *in) { u_char *chunk; - size_t size, len; + size_t size; ngx_buf_t *b; ngx_chain_t out, tail, *cl, *tl, **ll; @@ -98,6 +98,20 @@ static ngx_int_t ngx_http_chunked_body_filter(ngx_http_request_t *r, } if (size) { + if (!(b = ngx_calloc_buf(r->pool))) { + return NGX_ERROR; + } + + if (!(chunk = ngx_palloc(r->pool, 11))) { + return NGX_ERROR; + } + + b->temporary = 1; + b->pos = chunk; + b->last = ngx_sprintf(chunk, "%uxS" CRLF, size); + + out.buf = b; +#if 0 ngx_test_null(chunk, ngx_palloc(r->pool, 11), NGX_ERROR); len = ngx_snprintf((char *) chunk, 11, SIZE_T_X_FMT CRLF, size); @@ -107,6 +121,7 @@ static ngx_int_t ngx_http_chunked_body_filter(ngx_http_request_t *r, b->last = chunk + len; out.buf = b; +#endif } if (cl->buf->last_buf) { diff --git a/src/http/modules/ngx_http_gzip_filter.c b/src/http/modules/ngx_http_gzip_filter.c index 4089ffbdc..bb3a1f0c6 100644 --- a/src/http/modules/ngx_http_gzip_filter.c +++ b/src/http/modules/ngx_http_gzip_filter.c @@ -837,26 +837,30 @@ static u_char *ngx_http_gzip_log_ratio(ngx_http_request_t *r, u_char *buf, return buf + 1; } -#if 0 - return buf + ngx_snprintf((char *) buf, NGX_INT32_LEN + 4, "%.2f", - (float) ctx->zin / ctx->zout); -#endif - /* we prefer do not use the FPU */ zint = (ngx_uint_t) (ctx->zin / ctx->zout); zfrac = (ngx_uint_t) ((ctx->zin * 100 / ctx->zout) % 100); - if ((ctx->zin * 1000 / ctx->zout) %10 > 4) { - if (++zfrac > 99) { + if ((ctx->zin * 1000 / ctx->zout) % 10 > 4) { + + /* the rounding, e.g., 2.125 to 2.13 */ + + zfrac++; + + if (zfrac > 99) { zint++; zfrac = 0; } } + return ngx_sprintf(buf, "%ui.%02ui", zint, zfrac); + +#if 0 return buf + ngx_snprintf((char *) buf, NGX_INT32_LEN + 4, "%" NGX_UINT_T_FMT ".%02" NGX_UINT_T_FMT, zint, zfrac); +#endif } diff --git a/src/http/modules/ngx_http_headers_filter.c b/src/http/modules/ngx_http_headers_filter.c index f7fe52c8e..faf81920a 100644 --- a/src/http/modules/ngx_http_headers_filter.c +++ b/src/http/modules/ngx_http_headers_filter.c @@ -134,10 +134,16 @@ static ngx_int_t ngx_http_headers_filter(ngx_http_request_t *r) return NGX_ERROR; } + cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T", + conf->expires) + - cc->value.data; + +#if 0 cc->value.len = ngx_snprintf((char *) cc->value.data, sizeof("max-age=") + TIME_T_LEN, "max-age=" TIME_T_FMT, conf->expires); +#endif } } } diff --git a/src/http/modules/ngx_http_range_filter.c b/src/http/modules/ngx_http_range_filter.c index a08e25f7a..082fd3c4a 100644 --- a/src/http/modules/ngx_http_range_filter.c +++ b/src/http/modules/ngx_http_range_filter.c @@ -264,9 +264,14 @@ static ngx_int_t ngx_http_range_header_filter(ngx_http_request_t *r) } r->headers_out.content_range->value.len = + ngx_sprintf(r->headers_out.content_range->value.data, + "bytes */%O", r->headers_out.content_length_n) + - r->headers_out.content_range->value.data; +#if 0 ngx_snprintf((char *) r->headers_out.content_range->value.data, 8 + 20 + 1, "bytes */" OFF_T_FMT, r->headers_out.content_length_n); +#endif r->headers_out.content_length_n = -1; if (r->headers_out.content_length) { @@ -297,12 +302,20 @@ static ngx_int_t ngx_http_range_header_filter(ngx_http_request_t *r) /* "Content-Range: bytes SSSS-EEEE/TTTT" header */ r->headers_out.content_range->value.len = + ngx_sprintf(r->headers_out.content_range->value.data, + "bytes %O-%O/%O", + range->start, range->end - 1, + r->headers_out.content_length_n) + - r->headers_out.content_range->value.data; + +#if 0 ngx_snprintf((char *) r->headers_out.content_range->value.data, 6 + 20 + 1 + 20 + 1 + 20 + 1, "bytes " OFF_T_FMT "-" OFF_T_FMT "/" OFF_T_FMT, range->start, range->end - 1, r->headers_out.content_length_n); +#endif r->headers_out.content_length_n = range->end - range->start; @@ -343,6 +356,15 @@ static ngx_int_t ngx_http_range_header_filter(ngx_http_request_t *r) if (r->headers_out.charset.len) { ctx->boundary_header.len = + ngx_sprintf(ctx->boundary_header.data, + CRLF "--%010ui" CRLF + "Content-Type: %s; charset=%s" CRLF + "Content-Range: bytes ", + boundary, + r->headers_out.content_type->value.data, + r->headers_out.charset.data) + - ctx->boundary_header.data; +#if 0 ngx_snprintf((char *) ctx->boundary_header.data, len, CRLF "--%010" NGX_UINT_T_FMT CRLF "Content-Type: %s; charset=%s" CRLF @@ -350,17 +372,29 @@ static ngx_int_t ngx_http_range_header_filter(ngx_http_request_t *r) boundary, r->headers_out.content_type->value.data, r->headers_out.charset.data); +#endif r->headers_out.charset.len = 0; } else { ctx->boundary_header.len = + ngx_sprintf(ctx->boundary_header.data, + CRLF "--%010ui" CRLF + "Content-Type: %s" CRLF + "Content-Range: bytes ", + boundary, + r->headers_out.content_type->value.data) + - ctx->boundary_header.data; + +#if 0 ngx_snprintf((char *) ctx->boundary_header.data, len, CRLF "--%010" NGX_UINT_T_FMT CRLF "Content-Type: %s" CRLF "Content-Range: bytes ", boundary, r->headers_out.content_type->value.data); + +#endif } ngx_test_null(r->headers_out.content_type->value.data, @@ -370,12 +404,18 @@ static ngx_int_t ngx_http_range_header_filter(ngx_http_request_t *r) /* "Content-Type: multipart/byteranges; boundary=0123456789" */ r->headers_out.content_type->value.len = + ngx_sprintf(r->headers_out.content_type->value.data, + "multipart/byteranges; boundary=%010ui", + boundary) + - r->headers_out.content_type->value.data; +#if 0 ngx_snprintf((char *) r->headers_out.content_type->value.data, 31 + 10 + 1, "multipart/byteranges; boundary=%010" NGX_UINT_T_FMT, boundary); +#endif /* the size of the last boundary CRLF "--0123456789--" CRLF */ len = 4 + 10 + 4; @@ -389,11 +429,18 @@ static ngx_int_t ngx_http_range_header_filter(ngx_http_request_t *r) /* the size of the range: "SSSS-EEEE/TTTT" CRLF CRLF */ range[i].content_range.len = + ngx_sprintf(range[i].content_range.data, + "%O-%O/%O" CRLF CRLF, + range[i].start, range[i].end - 1, + r->headers_out.content_length_n) + - range[i].content_range.data; +#if 0 ngx_snprintf((char *) range[i].content_range.data, 20 + 1 + 20 + 1 + 20 + 5, OFF_T_FMT "-" OFF_T_FMT "/" OFF_T_FMT CRLF CRLF, range[i].start, range[i].end - 1, r->headers_out.content_length_n); +#endif len += ctx->boundary_header.len + range[i].content_range.len + (size_t) (range[i].end - range[i].start); diff --git a/src/http/modules/ngx_http_status_handler.c b/src/http/modules/ngx_http_status_handler.c index 6206ac3ce..357affff4 100644 --- a/src/http/modules/ngx_http_status_handler.c +++ b/src/http/modules/ngx_http_status_handler.c @@ -159,6 +159,9 @@ static ngx_int_t ngx_http_status(ngx_http_status_ctx_t *ctx) + 1 + (r->server_name ? cmcf->max_server_name_len : 1) + 2; /* "\r\n" */ + /* BUG: cmcf->max_server_name_len and "*.domain.tld" */ + + if (r->request_line.len) { len += 1 + 1 + r->request_line.len + 1; } diff --git a/src/http/modules/ngx_http_userid_filter.c b/src/http/modules/ngx_http_userid_filter.c index 5f8e452ac..bafdea884 100644 --- a/src/http/modules/ngx_http_userid_filter.c +++ b/src/http/modules/ngx_http_userid_filter.c @@ -367,7 +367,7 @@ static ngx_int_t ngx_http_userid_set_uid(ngx_http_request_t *r, } else if (conf->expires) { p = ngx_cpymem(p, expires, sizeof("; expires=") - 1); - p += ngx_http_cookie_time(p, ngx_time() + conf->expires); + p = ngx_http_cookie_time(p, ngx_time() + conf->expires); } if (conf->domain.len > 1) { diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c index f0794f36e..5d61167e2 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -289,6 +289,8 @@ ngx_http_header_t ngx_http_proxy_headers_in[] = { offsetof(ngx_http_proxy_headers_in_t, content_type) }, { ngx_string("Content-Length"), offsetof(ngx_http_proxy_headers_in_t, content_length) }, + { ngx_string("Content-Encoding"), + offsetof(ngx_http_proxy_headers_in_t, content_encoding) }, { ngx_string("Last-Modified"), offsetof(ngx_http_proxy_headers_in_t, last_modified) }, { ngx_string("Location"), @@ -400,7 +402,7 @@ void ngx_http_proxy_check_broken_connection(ngx_event_t *ev) #if (HAVE_KQUEUE) - if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { + if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { if (!ev->pending_eof) { return; @@ -1310,10 +1312,10 @@ static char *ngx_http_proxy_parse_upstream(ngx_str_t *url, static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data) { -#if __FreeBSD__ - ssize_t *np = data; +#if (NGX_FREEBSD) + if (*np >= ngx_freebsd_net_inet_tcp_sendspace) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"proxy_send_lowat\" must be less than %d " @@ -1323,15 +1325,12 @@ static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data) return NGX_CONF_ERROR; } +#elif !(HAVE_SO_SNDLOWAT) -#else - -#if 0 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "\"proxy_send_lowat\" is not supported, ignored"); *np = 0; -#endif #endif diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h index 728259c45..3e721bae1 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.h +++ b/src/http/modules/proxy/ngx_http_proxy_handler.h @@ -130,6 +130,7 @@ typedef struct { ngx_table_elt_t *connection; ngx_table_elt_t *content_type; ngx_table_elt_t *content_length; + ngx_table_elt_t *content_encoding; ngx_table_elt_t *last_modified; ngx_table_elt_t *location; ngx_table_elt_t *accept_ranges; diff --git a/src/http/modules/proxy/ngx_http_proxy_header.c b/src/http/modules/proxy/ngx_http_proxy_header.c index 07722fc89..cd5deeb9e 100644 --- a/src/http/modules/proxy/ngx_http_proxy_header.c +++ b/src/http/modules/proxy/ngx_http_proxy_header.c @@ -113,6 +113,11 @@ int ngx_http_proxy_copy_header(ngx_http_proxy_ctx_t *p, continue; } + if (&h[i] == headers_in->content_encoding) { + r->headers_out.content_encoding = ho; + continue; + } + if (&h[i] == headers_in->last_modified) { r->headers_out.last_modified = ho; /* TODO: update r->headers_out.last_modified_time */ diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c index be5d69a22..88479daf5 100644 --- a/src/http/modules/proxy/ngx_http_proxy_upstream.c +++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c @@ -692,12 +692,14 @@ static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p) /* rc == NGX_OK */ -#if 1 /* test only, see below about "post aio operation" */ +#if 0 /* test only, see below about "post aio operation" */ if (c->read->ready) { /* post aio operation */ ngx_http_proxy_process_upstream_status_line(c->read); +#if 0 return; +#endif } #endif @@ -718,7 +720,7 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p) #if (HAVE_KQUEUE) - if ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) + if ((ngx_event_flags & NGX_USE_KQUEUE_EVENT) && !p->request_sent && c->write->pending_eof) { @@ -776,7 +778,7 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p) ngx_add_timer(c->read, p->lcf->read_timeout); -#if 0 +#if 1 if (c->read->ready) { /* post aio operation */ diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c index a37ffc6eb..90bbbe2f5 100644 --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -11,6 +11,14 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static ngx_int_t ngx_http_add_address(ngx_conf_t *cf, + ngx_http_in_port_t *in_port, + ngx_http_listen_t *lscf, + ngx_http_core_srv_conf_t *cscf); +static ngx_int_t ngx_http_add_names(ngx_conf_t *cf, + ngx_http_in_addr_t *in_addr, + ngx_http_core_srv_conf_t *cscf); + static char *ngx_http_merge_locations(ngx_conf_t *cf, ngx_array_t *locations, void **loc_conf, @@ -79,6 +87,11 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_iocp_conf_t *iocpcf; #endif +#if (NGX_SUPPRESS_WARN) + /* MSVC thinks 'in_ports' may be used without having been initialized */ + ngx_memzero(&in_ports, sizeof(ngx_array_t)); +#endif + /* the main http context */ ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), @@ -274,18 +287,23 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) /* - * create the lists of the ports, the addresses and the server names - * to allow quickly find the server core module configuration at run-time + * create the lists of ports, addresses and server names + * to quickly find the server core module configuration at run-time */ - ngx_init_array(in_ports, cf->pool, 10, sizeof(ngx_http_in_port_t), - NGX_CONF_ERROR); + if (ngx_array_init(&in_ports, cf->pool, 10, sizeof(ngx_http_in_port_t)) + == NGX_ERROR) + { + return NGX_CONF_ERROR; + } /* "server" directives */ + cscfp = cmcf->servers.elts; for (s = 0; s < cmcf->servers.nelts; s++) { /* "listen" directives */ + lscf = cscfp[s]->listen.elts; for (l = 0; l < cscfp[s]->listen.nelts; l++) { @@ -308,38 +326,26 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) if (lscf[l].addr == in_addr[a].addr) { - /* the address is already bound to this port */ - - /* "server_name" directives */ - s_name = cscfp[s]->server_names.elts; - for (n = 0; n < cscfp[s]->server_names.nelts; n++) { - - /* - * add the server name and server core module - * configuration to the address:port - */ - - /* TODO: duplicate names can be checked here */ + /* the address is already in the address list */ - ngx_test_null(name, - ngx_push_array(&in_addr[a].names), - NGX_CONF_ERROR); - - name->name = s_name[n].name; - name->core_srv_conf = s_name[n].core_srv_conf; + if (ngx_http_add_names(cf, &in_addr[a], cscfp[s]) + == NGX_ERROR) + { + return NGX_CONF_ERROR; } /* - * check duplicate "default" server that - * serves this address:port + * check the duplicate "default" server + * for this address:port */ if (lscf[l].default_server) { + if (in_addr[a].default_server) { ngx_log_error(NGX_LOG_ERR, cf->log, 0, - "duplicate default server in %s:%d", - lscf[l].file_name.data, - lscf[l].line); + "the duplicate default server in %s:%d", + lscf[l].file_name.data, + lscf[l].line); return NGX_CONF_ERROR; } @@ -354,31 +360,31 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } else if (in_addr[a].addr == INADDR_ANY) { + /* the INADDR_ANY is always the last address */ + + if (!(inaddr = ngx_array_push(&in_port[p].addrs))) { + return NGX_CONF_ERROR; + } + /* - * "*:port" must be the last resort so move it - * to the end of the address list and add - * the new address at its place + * the INADDR_ANY must be the last resort + * so we move it to the end of the address list + * and put the new address in its place */ - ngx_test_null(inaddr, - ngx_push_array(&in_port[p].addrs), - NGX_CONF_ERROR); - ngx_memcpy(inaddr, &in_addr[a], sizeof(ngx_http_in_addr_t)); in_addr[a].addr = lscf[l].addr; + in_addr[a].names.elts = NULL; in_addr[a].default_server = lscf[l].default_server; in_addr[a].core_srv_conf = cscfp[s]; - /* - * create the empty list of the server names that - * can be served on this address:port - */ - - ngx_init_array(inaddr->names, cf->pool, 10, - sizeof(ngx_http_server_name_t), - NGX_CONF_ERROR); + if (ngx_http_add_names(cf, &in_addr[a], cscfp[s]) + == NGX_ERROR) + { + return NGX_CONF_ERROR; + } addr_found = 1; @@ -393,22 +399,11 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) * bound to this port */ - ngx_test_null(inaddr, - ngx_push_array(&in_port[p].addrs), - NGX_CONF_ERROR); - - inaddr->addr = lscf[l].addr; - inaddr->default_server = lscf[l].default_server; - inaddr->core_srv_conf = cscfp[s]; - - /* - * create the empty list of the server names that - * can be served on this address:port - */ - - ngx_init_array(inaddr->names, cf->pool, 10, - sizeof(ngx_http_server_name_t), - NGX_CONF_ERROR); + if (ngx_http_add_address(cf, &in_port[p], &lscf[l], + cscfp[s]) == NGX_ERROR) + { + return NGX_CONF_ERROR; + } } } } @@ -417,54 +412,42 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) /* add the port to the in_port list */ - ngx_test_null(in_port, - ngx_push_array(&in_ports), - NGX_CONF_ERROR); + if (!(in_port = ngx_array_push(&in_ports))) { + return NGX_CONF_ERROR; + } in_port->port = lscf[l].port; + in_port->addrs.elts = NULL; - ngx_test_null(in_port->port_text.data, ngx_palloc(cf->pool, 7), - NGX_CONF_ERROR); - in_port->port_text.len = ngx_snprintf((char *) - in_port->port_text.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, - sizeof(ngx_http_in_addr_t), - NGX_CONF_ERROR); - - ngx_test_null(inaddr, ngx_push_array(&in_port->addrs), - NGX_CONF_ERROR); - - /* ... and add the address to this list */ - - inaddr->addr = lscf[l].addr; - inaddr->default_server = lscf[l].default_server; - inaddr->core_srv_conf = cscfp[s]; + if (!(in_port->port_text.data = ngx_palloc(cf->pool, 7))) { + return NGX_CONF_ERROR; + } - /* - * create the empty list of the server names that - * can be served on this address:port - */ + in_port->port_text.len = ngx_sprintf(in_port->port_text.data, + ":%d", in_port->port) + - in_port->port_text.data; - ngx_init_array(inaddr->names, cf->pool, 10, - sizeof(ngx_http_server_name_t), - NGX_CONF_ERROR); + if (ngx_http_add_address(cf, in_port, &lscf[l], cscfp[s]) + == NGX_ERROR) + { + return NGX_CONF_ERROR; + } } } } - /* optimize the lists of the ports, the addresses and the server names */ + + /* optimize the lists of ports, addresses and server names */ /* AF_INET only */ in_port = in_ports.elts; for (p = 0; p < in_ports.nelts; p++) { - /* check whether the all server names point to the same server */ + /* + * check whether all name-based servers have the same configuraiton + * as the default server, or some servers restrict the host names + */ in_addr = in_port[p].addrs.elts; for (a = 0; a < in_port[p].addrs.nelts; a++) { @@ -473,15 +456,19 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) name = in_addr[a].names.elts; for (n = 0; n < in_addr[a].names.nelts; n++) { - if (in_addr[a].core_srv_conf != name[n].core_srv_conf) { + if (in_addr[a].core_srv_conf != name[n].core_srv_conf + || name[n].core_srv_conf->restrict_host_names + != NGX_HTTP_RESTRICT_HOST_OFF) + { virtual_names = 1; break; } } /* - * if the all server names point to the same server - * then we do not need to check them at run-time + * if all name-based servers have the same configuration + * as the default server, and no servers restrict the host names + * then we do not need to check them at run-time at all */ if (!virtual_names) { @@ -588,30 +575,117 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } #if (NGX_DEBUG) + { + u_char address[20]; + ngx_uint_t p, a, n; + in_port = in_ports.elts; for (p = 0; p < in_ports.nelts; p++) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, "port: %d %08x", in_port[p].port, &in_port[p]); in_addr = in_port[p].addrs.elts; for (a = 0; a < in_port[p].addrs.nelts; a++) { - u_char ip[20]; - ngx_inet_ntop(AF_INET, &in_addr[a].addr, ip, 20); - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, - "%s %08x", ip, in_addr[a].core_srv_conf); + ngx_inet_ntop(AF_INET, &in_addr[a].addr, address, 20); + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, cf->log, 0, + "%s:%d %08x", + address, in_port[p].port, in_addr[a].core_srv_conf); s_name = in_addr[a].names.elts; for (n = 0; n < in_addr[a].names.nelts; n++) { - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, - "%s %08x", s_name[n].name.data, + ngx_log_debug4(NGX_LOG_DEBUG_HTTP, cf->log, 0, + "%s:%d %s %08x", + address, in_port[p].port, s_name[n].name.data, s_name[n].core_srv_conf); } } } + } #endif return NGX_CONF_OK; } +/* + * add the server address, the server names and the server core module + * configurations to the port (in_port) + */ + +static ngx_int_t ngx_http_add_address(ngx_conf_t *cf, + ngx_http_in_port_t *in_port, + ngx_http_listen_t *lscf, + ngx_http_core_srv_conf_t *cscf) +{ + ngx_http_in_addr_t *in_addr; + + if (in_port->addrs.elts == NULL) { + if (ngx_array_init(&in_port->addrs, cf->pool, 10, + sizeof(ngx_http_in_addr_t)) == NGX_ERROR) + { + return NGX_ERROR; + } + } + + if (!(in_addr = ngx_array_push(&in_port->addrs))) { + return NGX_ERROR; + } + + in_addr->addr = lscf->addr; + in_addr->names.elts = NULL; + in_addr->default_server = lscf->default_server; + in_addr->core_srv_conf = cscf; + +#if (NGX_DEBUG) + { + u_char text[20]; + ngx_inet_ntop(AF_INET, &in_addr->addr, text, 20); + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, "address: %s:%d", + text, in_port->port); + } +#endif + + return ngx_http_add_names(cf, in_addr, cscf); +} + + +/* + * add the server names and the server core module + * configurations to the address:port (in_addr) + */ + +static ngx_int_t ngx_http_add_names(ngx_conf_t *cf, + ngx_http_in_addr_t *in_addr, + ngx_http_core_srv_conf_t *cscf) +{ + ngx_uint_t i; + ngx_http_server_name_t *server_names, *name; + + if (in_addr->names.elts == NULL) { + if (ngx_array_init(&in_addr->names, cf->pool, 10, + sizeof(ngx_http_server_name_t)) == NGX_ERROR) + { + return NGX_ERROR; + } + } + + server_names = cscf->server_names.elts; + for (i = 0; i < cscf->server_names.nelts; i++) { + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, + "name: %s", server_names[i].name.data); + + /* TODO: duplicate names can be checked here */ + + if (!(name = ngx_array_push(&in_addr->names))) { + return NGX_ERROR; + } + + *name = server_names[i]; + } + + return NGX_OK; +} + + static char *ngx_http_merge_locations(ngx_conf_t *cf, ngx_array_t *locations, void **loc_conf, diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 58021e80a..8544e25c0 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -36,7 +36,7 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy); static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_set_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); -static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_set_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_set_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -126,9 +126,9 @@ static ngx_command_t ngx_http_core_commands[] = { #if 0 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, #else - NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12, #endif - ngx_set_listen, + ngx_http_listen, NGX_HTTP_SRV_CONF_OFFSET, 0, NULL }, @@ -576,7 +576,7 @@ static ngx_int_t ngx_http_find_location(ngx_http_request_t *r, clcfp = locations->elts; for (i = 0; i < locations->nelts; i++) { -#if (HAVE_PCRE) +#if (NGX_PCRE) if (clcfp[i]->regex) { break; } @@ -638,7 +638,7 @@ static ngx_int_t ngx_http_find_location(ngx_http_request_t *r, } } -#if (HAVE_PCRE) +#if (NGX_PCRE) /* regex matches */ @@ -673,7 +673,7 @@ static ngx_int_t ngx_http_find_location(ngx_http_request_t *r, return NGX_HTTP_LOCATION_REGEX; } -#endif /* HAVE_PCRE */ +#endif /* NGX_PCRE */ return NGX_OK; } @@ -991,7 +991,7 @@ static int ngx_cmp_locations(const void *one, const void *two) first = *(ngx_http_core_loc_conf_t **) one; second = *(ngx_http_core_loc_conf_t **) two; -#if (HAVE_PCRE) +#if (NGX_PCRE) if (first->regex && !second->regex) { /* shift the regex matches to the end */ @@ -1026,7 +1026,7 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) ngx_http_conf_ctx_t *ctx, *pctx; ngx_http_core_srv_conf_t *cscf; ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp; -#if (HAVE_PCRE) +#if (NGX_PCRE) ngx_str_t err; u_char errstr[NGX_MAX_CONF_ERRSTR]; #endif @@ -1076,7 +1076,7 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) && value[1].data[0] == '~' && value[1].data[1] == '*')) { -#if (HAVE_PCRE) +#if (NGX_PCRE) err.len = NGX_MAX_CONF_ERRSTR; err.data = errstr; @@ -1129,7 +1129,7 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) return NGX_CONF_ERROR; } -#if (HAVE_PCRE) +#if (NGX_PCRE) if (clcf->regex == NULL && ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len) != 0) @@ -1323,12 +1323,8 @@ static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf, n->name.len = ngx_strlen(n->name.data); n->core_srv_conf = conf; + n->wildcard = 0; -#if 0 - ctx = (ngx_http_conf_ctx_t *) - cf->cycle->conf_ctx[ngx_http_module.index]; - cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; -#endif cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); if (cmcf->max_server_name_len < n->name.len) { @@ -1512,7 +1508,7 @@ static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf, } -static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +static char *ngx_http_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_core_srv_conf_t *scf = conf; @@ -1607,13 +1603,8 @@ static char *ngx_set_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_http_server_name_t *sn; ngx_http_core_main_conf_t *cmcf; - /* TODO: several names */ /* TODO: warn about duplicate 'server_name' directives */ -#if 0 - ctx = (ngx_http_conf_ctx_t *) cf->cycle->conf_ctx[ngx_http_module.index]; - cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; -#endif cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); value = cf->args->elts; @@ -1627,12 +1618,23 @@ static char *ngx_set_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - ngx_test_null(sn, ngx_push_array(&scf->server_names), NGX_CONF_ERROR); + if (!(sn = ngx_array_push(&scf->server_names))) { + return NGX_CONF_ERROR; + } sn->name.len = value[i].len; sn->name.data = value[i].data; sn->core_srv_conf = scf; + if (sn->name.data[0] == '*') { + sn->name.len--; + sn->name.data++; + sn->wildcard = 1; + + } else { + sn->wildcard = 0; + } + if (cmcf->max_server_name_len < sn->name.len) { cmcf->max_server_name_len = sn->name.len; } @@ -1806,7 +1808,7 @@ static char *ngx_http_lowat_check(ngx_conf_t *cf, void *post, void *data) { ssize_t *np = data; -#if __FreeBSD__ +#if (NGX_FREEBSD) if (*np >= ngx_freebsd_net_inet_tcp_sendspace) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index 787f8b8fb..9a17130b8 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -96,13 +96,15 @@ typedef struct { ngx_http_core_srv_conf_t *core_srv_conf; /* default server conf for this address:port */ - unsigned default_server:1; + ngx_uint_t default_server; /* unsigned default_server:1; */ } ngx_http_in_addr_t; typedef struct { ngx_str_t name; ngx_http_core_srv_conf_t *core_srv_conf; /* virtual name server conf */ + + ngx_uint_t wildcard; /*unsigned wildcard:1; */ } ngx_http_server_name_t; @@ -135,7 +137,7 @@ typedef struct ngx_http_core_loc_conf_s ngx_http_core_loc_conf_t; struct ngx_http_core_loc_conf_s { ngx_str_t name; /* location name */ -#if (HAVE_PCRE) +#if (NGX_PCRE) ngx_regex_t *regex; #endif diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c index 5b7f3eb27..a083b45f8 100644 --- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -317,10 +317,15 @@ static ngx_int_t ngx_http_header_filter(ngx_http_request_t *r) if (r->headers_out.content_length == NULL) { if (r->headers_out.content_length_n >= 0) { + b->last = ngx_sprintf(b->last, "Content-Length: %O" CRLF, + r->headers_out.content_length_n); + +#if 0 b->last += ngx_snprintf((char *) b->last, sizeof("Content-Length: ") + NGX_OFF_T_LEN + 2, "Content-Length: " OFF_T_FMT CRLF, r->headers_out.content_length_n); +#endif } } @@ -372,7 +377,7 @@ static ngx_int_t ngx_http_header_filter(ngx_http_request_t *r) { b->last = ngx_cpymem(b->last, "Last-Modified: ", sizeof("Last-Modified: ") - 1); - b->last += ngx_http_time(b->last, r->headers_out.last_modified_time); + b->last = ngx_http_time(b->last, r->headers_out.last_modified_time); *(b->last++) = CR; *(b->last++) = LF; } @@ -389,10 +394,14 @@ static ngx_int_t ngx_http_header_filter(ngx_http_request_t *r) if (clcf->keepalive_header && (r->headers_in.gecko || r->headers_in.konqueror)) { + b->last = ngx_sprintf(b->last, "Keep-Alive: timeout=%T" CRLF, + clcf->keepalive_header); +#if 0 b->last += ngx_snprintf((char *) b->last, sizeof("Keep-Alive: timeout=") + TIME_T_LEN + 2, "Keep-Alive: timeout=" TIME_T_FMT CRLF, clcf->keepalive_header); +#endif } } else { diff --git a/src/http/ngx_http_log_handler.c b/src/http/ngx_http_log_handler.c index 51166cf0c..9a1389d13 100644 --- a/src/http/ngx_http_log_handler.c +++ b/src/http/ngx_http_log_handler.c @@ -210,9 +210,13 @@ static u_char *ngx_http_log_addr(ngx_http_request_t *r, u_char *buf, static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf, uintptr_t data) { + return ngx_sprintf(buf, "%ui", r->connection->number); + +#if 0 return buf + ngx_snprintf((char *) buf, NGX_INT_T_LEN + 1, "%" NGX_UINT_T_FMT, r->connection->number); +#endif } @@ -244,8 +248,12 @@ static u_char *ngx_http_log_msec(ngx_http_request_t *r, u_char *buf, ngx_gettimeofday(&tv); + return ngx_sprintf(buf, "%l.%03l", tv.tv_sec, tv.tv_usec / 1000); + +#if 0 return buf + ngx_snprintf((char *) buf, TIME_T_LEN + 5, "%ld.%03ld", tv.tv_sec, tv.tv_usec / 1000); +#endif } @@ -264,24 +272,36 @@ static u_char *ngx_http_log_request(ngx_http_request_t *r, u_char *buf, static u_char *ngx_http_log_status(ngx_http_request_t *r, u_char *buf, uintptr_t data) { + return ngx_sprintf(buf, "%ui", + r->err_status ? r->err_status : r->headers_out.status); + +#if 0 return buf + ngx_snprintf((char *) buf, 4, "%" NGX_UINT_T_FMT, r->err_status ? r->err_status : r->headers_out.status); +#endif } static u_char *ngx_http_log_length(ngx_http_request_t *r, u_char *buf, uintptr_t data) { + return ngx_sprintf(buf, "%O", r->connection->sent); + +#if 0 return buf + ngx_snprintf((char *) buf, NGX_OFF_T_LEN + 1, OFF_T_FMT, r->connection->sent); +#endif } static u_char *ngx_http_log_apache_length(ngx_http_request_t *r, u_char *buf, uintptr_t data) { + return ngx_sprintf(buf, "%O", r->connection->sent - r->header_size); +#if 0 return buf + ngx_snprintf((char *) buf, NGX_OFF_T_LEN + 1, OFF_T_FMT, r->connection->sent - r->header_size); +#endif } @@ -467,8 +487,7 @@ static u_char *ngx_http_log_header_out(ngx_http_request_t *r, u_char *buf, return (u_char *) sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1; } - return buf + ngx_http_time(buf, - r->headers_out.last_modified_time); + return ngx_http_time(buf, r->headers_out.last_modified_time); } if (buf) { diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 6069847f5..74173d873 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1091,27 +1091,47 @@ static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r) 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; - r->server_name = &name[i].name; + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "server name: %s", name[i].name.data); + + if (name[i].wildcard) { + if (r->headers_in.host_name_len <= name[i].name.len) { + continue; + } - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - r->connection->log->file = clcf->err_log->file; - if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) + if (ngx_rstrncasecmp(r->headers_in.host->value.data, + name[i].name.data, + name[i].name.len) == 0) { - r->connection->log->log_level = clcf->err_log->log_level; + continue; } - break; + } else { + 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, + name[i].name.len) != 0) + { + continue; + } } + + r->srv_conf = name[i].core_srv_conf->ctx->srv_conf; + r->loc_conf = name[i].core_srv_conf->ctx->loc_conf; + r->server_name = &name[i].name; + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + r->connection->log->file = clcf->err_log->file; + + if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { + r->connection->log->log_level = clcf->err_log->log_level; + } + + break; } if (i == r->virtual_names->nelts) { @@ -1562,7 +1582,13 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) if (b != c->buffer) { - /* move the large header buffers to the free list */ + /* + * If the large header buffers were allocated while the previous + * request processing then we do not use c->buffer for + * the pipelined request (see ngx_http_init_request()). + * + * Now we would move the large header buffers to the free list. + */ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); @@ -1614,6 +1640,14 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) hc->pipeline = 0; + /* + * To keep a memory footprint as small as possible for an idle + * keepalive connection we try to free the ngx_http_request_t and + * c->buffer's memory if they were allocated outside the c->pool. + * The large header buffers are always allocated outside the c->pool and + * are freed too. + */ + if (ngx_pfree(c->pool, r) == NGX_OK) { hc->request = NULL; } @@ -1621,6 +1655,12 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) b = c->buffer; if (ngx_pfree(c->pool, b->start) == NGX_OK) { + + /* + * the special note for ngx_http_keepalive_handler() that + * c->buffer's memory was freed + */ + b->pos = NULL; } else { @@ -1655,7 +1695,7 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) rev->event_handler = ngx_http_keepalive_handler; if (wev->active) { - if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { + if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_DISABLE_EVENT) == NGX_ERROR) { @@ -1702,7 +1742,7 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) } #if 0 - /* if "keepalive_buffers off" then we need some other place */ + /* if ngx_http_request_t was freed then we need some other place */ r->http_state = NGX_HTTP_KEEPALIVE_STATE; #endif @@ -1734,7 +1774,7 @@ static void ngx_http_keepalive_handler(ngx_event_t *rev) #if (HAVE_KQUEUE) - if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { + if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { if (rev->pending_eof) { ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno, "kevent() reported that client %s closed " @@ -1751,6 +1791,13 @@ static void ngx_http_keepalive_handler(ngx_event_t *rev) size = b->end - b->start; if (b->pos == NULL) { + + /* + * The c->buffer's memory was freed by ngx_http_set_keepalive(). + * However, the c->buffer->start and c->buffer->end were not changed + * to keep the buffer size. + */ + if (!(b->pos = ngx_palloc(c->pool, size))) { ngx_http_close_connection(c); return; @@ -1824,7 +1871,7 @@ static void ngx_http_set_lingering_close(ngx_http_request_t *r) wev->event_handler = ngx_http_empty_handler; if (wev->active) { - if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { + if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_DISABLE_EVENT) == NGX_ERROR) { diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h index 022b8a8cf..8a9c8f24f 100644 --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -38,11 +38,11 @@ #define NGX_HTTP_PARSE_HEADER_ERROR 14 #define NGX_HTTP_PARSE_INVALID_HEADER 14 #define NGX_HTTP_PARSE_TOO_LONG_HEADER 15 -#define NGX_HTTP_PARSE_NO_HOST_HEADER 17 -#define NGX_HTTP_PARSE_INVALID_CL_HEADER 18 -#define NGX_HTTP_PARSE_POST_WO_CL_HEADER 19 -#define NGX_HTTP_PARSE_HTTP_TO_HTTPS 20 -#define NGX_HTTP_PARSE_INVALID_HOST 21 +#define NGX_HTTP_PARSE_NO_HOST_HEADER 16 +#define NGX_HTTP_PARSE_INVALID_CL_HEADER 17 +#define NGX_HTTP_PARSE_POST_WO_CL_HEADER 18 +#define NGX_HTTP_PARSE_HTTP_TO_HTTPS 19 +#define NGX_HTTP_PARSE_INVALID_HOST 20 #define NGX_HTTP_OK 200 diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c index a8c68947f..37e0f3fab 100644 --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -125,6 +125,7 @@ ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) if (!last) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "the http output chain is empty"); + return NGX_ERROR; } return NGX_OK; } |
