# HG changeset patch # User Igor Sysoev # Date 1090177880 0 # Node ID 6f3b20c1ac50edb0c330174ac5c511c8215a8659 # Parent f8f0f1834266481d63a9ed047474ab83c12b630a nginx-0.0.7-2004-07-18-23:11:20 import 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 @@ -68,58 +68,66 @@ typedef enum { struct ngx_connection_s { - void *data; - ngx_event_t *read; - ngx_event_t *write; + void *data; + ngx_event_t *read; + ngx_event_t *write; - ngx_socket_t fd; + ngx_socket_t fd; - ngx_listening_t *listening; + ngx_recv_pt recv; + ngx_send_chain_pt send_chain; + + ngx_listening_t *listening; - off_t sent; + off_t sent; - void *ctx; - void *servers; + void *ctx; + void *servers; - ngx_log_t *log; + ngx_log_t *log; - ngx_pool_t *pool; + ngx_pool_t *pool; - struct sockaddr *sockaddr; - socklen_t socklen; - ngx_str_t addr_text; + struct sockaddr *sockaddr; + socklen_t socklen; + ngx_str_t addr_text; #if (NGX_OPENSSL) - ngx_ssl_t *ssl; + ngx_ssl_t *ssl; #endif #if (HAVE_IOCP) - struct sockaddr *local_sockaddr; - socklen_t local_socklen; + struct sockaddr *local_sockaddr; + socklen_t local_socklen; #endif - ngx_buf_t *buffer; + ngx_buf_t *buffer; - ngx_uint_t number; + ngx_uint_t number; - unsigned log_error:2; /* ngx_connection_log_error_e */ + unsigned log_error:2; /* ngx_connection_log_error_e */ - unsigned single_connection:1; - unsigned pipeline:1; - unsigned unexpected_eof:1; - unsigned timedout:1; - signed tcp_nopush:2; + unsigned single_connection:1; + unsigned pipeline:1; + unsigned unexpected_eof:1; + unsigned timedout:1; + signed tcp_nopush:2; #if (HAVE_IOCP) - unsigned accept_context_updated:1; + unsigned accept_context_updated:1; #endif #if (NGX_THREADS) - ngx_atomic_t lock; + ngx_atomic_t lock; #endif }; +#ifndef ngx_ssl_set_nosendshut +#define ngx_ssl_set_nosendshut(ssl) +#endif + + ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle); ngx_int_t ngx_open_listening_sockets(ngx_cycle_t *cycle); void ngx_close_listening_sockets(ngx_cycle_t *cycle); diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -258,6 +258,9 @@ void ngx_event_accept(ngx_event_t *ev) c->ctx = ls->ctx; c->servers = ls->servers; + c->recv = ngx_recv; + c->send_chain = ngx_send_chain; + c->log = log; rev->log = log; wev->log = log; diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -64,9 +64,9 @@ ngx_int_t ngx_ssl_recv(ngx_connection_t sslerr = SSL_get_error(c->ssl->ssl, n); - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr); + err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; - err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr); if (sslerr == SSL_ERROR_WANT_READ) { return NGX_AGAIN; @@ -85,20 +85,18 @@ ngx_int_t ngx_ssl_recv(ngx_connection_t handshake = ""; } + c->ssl->no_rcv_shut = 1; + if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { ngx_log_error(NGX_LOG_INFO, c->log, err, "client closed connection%s", handshake); - SSL_set_shutdown(c->ssl->ssl, SSL_RECEIVED_SHUTDOWN); - return NGX_ERROR; } ngx_ssl_error(NGX_LOG_ALERT, c->log, err, "SSL_read() failed%s", handshake); - SSL_set_shutdown(c->ssl->ssl, SSL_RECEIVED_SHUTDOWN); - return NGX_ERROR; } @@ -106,7 +104,8 @@ ngx_int_t ngx_ssl_recv(ngx_connection_t ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) { - int n; + int n, sslerr; + ngx_err_t err; ssize_t send, size; ngx_buf_t *buf; @@ -157,6 +156,7 @@ ngx_chain_t *ngx_ssl_send_chain(ngx_conn if (n > 0) { buf->pos += n; send += n; + c->sent += n; if (n < size) { break; @@ -233,6 +233,7 @@ ngx_chain_t *ngx_ssl_send_chain(ngx_conn if (n > 0) { in->buf->pos += n; send += n; + c->sent += n; if (n == size) { if (send < limit) { @@ -246,21 +247,26 @@ ngx_chain_t *ngx_ssl_send_chain(ngx_conn return in; } - n = SSL_get_error(c->ssl->ssl, n); + sslerr = SSL_get_error(c->ssl->ssl, n); + + err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", n); + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "SSL_get_error: %d", sslerr); - if (n == SSL_ERROR_WANT_WRITE) { + if (sslerr == SSL_ERROR_WANT_WRITE) { c->write->ready = 0; return in; } #if 0 - if (n == SSL_ERROR_WANT_READ) { + if (sslerr == SSL_ERROR_WANT_READ) { return NGX_AGAIN; } #endif + c->ssl->no_rcv_shut = 1; + ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_write() failed"); return NGX_CHAIN_ERROR; @@ -272,19 +278,21 @@ ngx_chain_t *ngx_ssl_send_chain(ngx_conn ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c) { - int n; + int n, sslerr; ngx_uint_t again; -#if 0 - if (c->read->timedout || c->write->timedout) { - SSL_set_shutdown(c->ssl, SSL_RECEIVED_SHUTDOWN); - SSL_set_shutdown(c->ssl, SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN); + if (c->timedout) { + SSL_set_shutdown(c->ssl->ssl, SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN); + + } else { + if (c->ssl->no_rcv_shut) { + SSL_set_shutdown(c->ssl->ssl, SSL_RECEIVED_SHUTDOWN); + } + + if (c->ssl->no_send_shut) { + SSL_set_shutdown(c->ssl->ssl, SSL_SENT_SHUTDOWN); + } } -#endif - -#if 0 - SSL_set_shutdown(c->ssl->ssl, SSL_RECEIVED_SHUTDOWN); -#endif again = 0; @@ -308,12 +316,13 @@ ngx_int_t ngx_ssl_shutdown(ngx_connectio } if (!again) { - n = SSL_get_error(c->ssl->ssl, n); + sslerr = SSL_get_error(c->ssl->ssl, n); - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", n); + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "SSL_get_error: %d", sslerr); } - if (again || n == SSL_ERROR_WANT_READ) { + if (again || sslerr == SSL_ERROR_WANT_READ) { ngx_add_timer(c->read, 10000); @@ -324,7 +333,7 @@ ngx_int_t ngx_ssl_shutdown(ngx_connectio return NGX_AGAIN; } - if (n == SSL_ERROR_WANT_WRITE) { + if (sslerr == SSL_ERROR_WANT_WRITE) { if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { return NGX_ERROR; diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -13,6 +13,9 @@ typedef struct { SSL *ssl; ngx_buf_t *buf; ngx_event_handler_pt saved_handler; + + unsigned no_rcv_shut:1; + unsigned no_send_shut:1; } ngx_ssl_t; @@ -28,6 +31,9 @@ typedef SSL_CTX ngx_ssl_ctx_t; ngx_int_t ngx_ssl_init(ngx_log_t *log); ngx_int_t ngx_ssl_create_session(ngx_ssl_ctx_t *ctx, ngx_connection_t *c, ngx_uint_t flags); + +#define ngx_ssl_handshake(c) NGX_OK + ngx_int_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size); ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); @@ -35,5 +41,10 @@ ngx_int_t ngx_ssl_shutdown(ngx_connectio void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...); +#define ngx_ssl_set_nosendshut(ssl) \ + if (ssl) { \ + ssl->no_send_shut = 1; \ + } + #endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */ diff --git a/src/http/modules/ngx_http_access_handler.c b/src/http/modules/ngx_http_access_handler.c --- a/src/http/modules/ngx_http_access_handler.c +++ b/src/http/modules/ngx_http_access_handler.c @@ -190,13 +190,8 @@ static char *ngx_http_access_merge_loc_c static ngx_int_t ngx_http_access_init(ngx_cycle_t *cycle) { ngx_http_handler_pt *h; - ngx_http_conf_ctx_t *ctx; ngx_http_core_main_conf_t *cmcf; -#if 0 - ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]; - cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; -#endif cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); h = ngx_push_array(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers); diff --git a/src/http/modules/ngx_http_charset_filter.c b/src/http/modules/ngx_http_charset_filter.c --- a/src/http/modules/ngx_http_charset_filter.c +++ b/src/http/modules/ngx_http_charset_filter.c @@ -363,7 +363,6 @@ static char *ngx_http_set_charset_slot(n ngx_int_t *cp; ngx_str_t *value; ngx_http_charset_t *charset; - ngx_http_conf_ctx_t *ctx; ngx_http_charset_main_conf_t *mcf; cp = (ngx_int_t *) (p + cmd->offset); @@ -372,8 +371,9 @@ static char *ngx_http_set_charset_slot(n return "is duplicate"; } - ctx = cf->ctx; - mcf = ctx->main_conf[ngx_http_charset_filter_module.ctx_index]; + mcf = ngx_http_conf_get_module_main_conf(cf, + ngx_http_charset_filter_module); + value = cf->args->elts; *cp = ngx_http_add_charset(&mcf->charsets, &value[1]); diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c --- a/src/http/modules/ngx_http_index_handler.c +++ b/src/http/modules/ngx_http_index_handler.c @@ -98,6 +98,7 @@ ngx_module_t ngx_http_index_module = { ngx_int_t ngx_http_index_handler(ngx_http_request_t *r) { u_char *name; + size_t len; ngx_fd_t fd; ngx_int_t rc; ngx_str_t *index; @@ -160,6 +161,7 @@ ngx_int_t ngx_http_index_handler(ngx_htt #endif +#if 0 ctx->path.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + ilcf->max_index_len - clcf->alias * clcf->name.len); @@ -169,9 +171,35 @@ ngx_int_t ngx_http_index_handler(ngx_htt ctx->redirect.data = ngx_cpymem(ctx->path.data, clcf->root.data, clcf->root.len); +#endif if (clcf->alias) { - ctx->last = ngx_cpystrn(ctx->redirect.data, + if (clcf->root.len > clcf->name.len) { + ctx->path.data = ngx_palloc(r->pool, clcf->root.len + + r->uri.len + - clcf->name.len + + ilcf->max_index_len); + if (ctx->path.data == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + ctx->redirect.data = ctx->path.data + clcf->root.len + 1 + - clcf->name.len; + + } else { + ctx->redirect.data = ngx_palloc(r->pool, r->uri.len + + ilcf->max_index_len); + if (ctx->redirect.data == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + ctx->path.data = ctx->redirect.data + clcf->name.len + - clcf->root.len; + } + + ngx_memcpy(ctx->path.data, clcf->root.data, clcf->root.len); + + ctx->last = ngx_cpystrn(ctx->path.data + clcf->root.len, r->uri.data + clcf->name.len, r->uri.len + 1 - clcf->name.len); @@ -185,6 +213,15 @@ ngx_int_t ngx_http_index_handler(ngx_htt } } else { + ctx->path.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + + ilcf->max_index_len); + if (ctx->path.data == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + ctx->redirect.data = ngx_cpymem(ctx->path.data, clcf->root.data, + clcf->root.len); + ctx->last = ngx_cpystrn(ctx->redirect.data, r->uri.data, r->uri.len + 1); } @@ -255,8 +292,14 @@ ngx_int_t ngx_http_index_handler(ngx_htt ctx->redirect.data = index[ctx->index].data; } else { - ctx->redirect.len = r->uri.len + index[ctx->index].len; + if (clcf->alias) { + ngx_memcpy(ctx->redirect.data, clcf->name.data, clcf->name.len); + } + + ctx->redirect.len = r->uri.len + index[ctx->index].len + - clcf->alias * clcf->name.len; r->file.name.len = clcf->root.len + r->uri.len + - clcf->alias * clcf->name.len + index[ctx->index].len; } @@ -364,11 +407,9 @@ static ngx_int_t ngx_http_index_error(ng static ngx_int_t ngx_http_index_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]; + cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); h = ngx_push_array(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers); if (h == NULL) { diff --git a/src/http/modules/ngx_http_rewrite_handler.c b/src/http/modules/ngx_http_rewrite_handler.c --- a/src/http/modules/ngx_http_rewrite_handler.c +++ b/src/http/modules/ngx_http_rewrite_handler.c @@ -369,11 +369,9 @@ static char *ngx_http_rewrite_rule(ngx_c 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]; + cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); h = ngx_push_array(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers); if (h == NULL) { diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -105,7 +105,8 @@ static char *ngx_http_ssl_merge_srv_conf return NGX_CONF_ERROR; } - if (SSL_CTX_use_certificate_file(conf->ssl_ctx, conf->certificate.data, + if (SSL_CTX_use_certificate_file(conf->ssl_ctx, + (char *) conf->certificate.data, SSL_FILETYPE_PEM) == 0) { ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, "SSL_CTX_use_certificate_file(\"%s\") failed", @@ -113,7 +114,8 @@ static char *ngx_http_ssl_merge_srv_conf return NGX_CONF_ERROR; } - if (SSL_CTX_use_PrivateKey_file(conf->ssl_ctx, conf->certificate_key.data, + if (SSL_CTX_use_PrivateKey_file(conf->ssl_ctx, + (char *) conf->certificate_key.data, SSL_FILETYPE_PEM) == 0) { ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, "SSL_CTX_use_PrivateKey_file(\"%s\") failed", diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -537,11 +537,9 @@ static char *ngx_http_static_merge_loc_c static ngx_int_t ngx_http_static_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]; + + cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); h = ngx_push_array(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers); if (h == NULL) { diff --git a/src/http/modules/ngx_http_status_handler.c b/src/http/modules/ngx_http_status_handler.c --- a/src/http/modules/ngx_http_status_handler.c +++ b/src/http/modules/ngx_http_status_handler.c @@ -299,11 +299,9 @@ static ngx_int_t ngx_http_status(ngx_htt static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_http_conf_ctx_t *ctx; ngx_http_core_loc_conf_t *clcf; - ctx = cf->ctx; - clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; + clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); clcf->handler = ngx_http_status_handler; return NGX_CONF_OK; diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -1062,7 +1062,6 @@ static char *ngx_http_proxy_set_pass(ngx in_addr_t addr; ngx_str_t *value; struct hostent *h; - ngx_http_conf_ctx_t *ctx; ngx_http_core_loc_conf_t *clcf; @@ -1177,10 +1176,11 @@ static char *ngx_http_proxy_set_pass(ngx lcf->upstream->port_text.len + 1); } - ctx = cf->ctx; - clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; + clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); + lcf->upstream->location = &clcf->name; clcf->handler = ngx_http_proxy_handler; + if (clcf->name.data[clcf->name.len - 1] == '/') { clcf->auto_redirect = 1; } 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 @@ -6,7 +6,11 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); - +static char *ngx_http_merge_locations(ngx_conf_t *cf, + ngx_array_t *locations, + void **loc_conf, + ngx_http_module_t *module, + ngx_uint_t ctx_index); int ngx_http_max_module; @@ -204,7 +208,16 @@ static char *ngx_http_block(ngx_conf_t * /* merge the locations{}' loc_conf's */ - clcfp = (ngx_http_core_loc_conf_t **)cscfp[s]->locations.elts; + rv = ngx_http_merge_locations(cf, &cscfp[s]->locations, + cscfp[s]->ctx->loc_conf, + module, mi); + if (rv != NGX_CONF_OK) { + *cf = pcf; + return rv; + } + +#if 0 + clcfp = (ngx_http_core_loc_conf_t **) cscfp[s]->locations.elts; for (l = 0; l < cscfp[s]->locations.nelts; l++) { rv = module->merge_loc_conf(cf, @@ -215,6 +228,7 @@ static char *ngx_http_block(ngx_conf_t * return rv; } } +#endif } } } @@ -623,3 +637,33 @@ static char *ngx_http_block(ngx_conf_t * return NGX_CONF_OK; } + + +static char *ngx_http_merge_locations(ngx_conf_t *cf, + ngx_array_t *locations, + void **loc_conf, + ngx_http_module_t *module, + ngx_uint_t ctx_index) +{ + char *rv; + ngx_uint_t i; + ngx_http_core_loc_conf_t **clcfp; + + clcfp = /* (ngx_http_core_loc_conf_t **) */ locations->elts; + + for (i = 0; i < locations->nelts; i++) { + rv = module->merge_loc_conf(cf, loc_conf[ctx_index], + clcfp[i]->loc_conf[ctx_index]); + if (rv != NGX_CONF_OK) { + return rv; + } + + rv = ngx_http_merge_locations(cf, &clcfp[i]->locations, + clcfp[i]->loc_conf, module, ctx_index); + if (rv != NGX_CONF_OK) { + return rv; + } + } + + return NGX_CONF_OK; +} diff --git a/src/http/ngx_http_config.h b/src/http/ngx_http_config.h --- a/src/http/ngx_http_config.h +++ b/src/http/ngx_http_config.h @@ -43,14 +43,18 @@ typedef struct { #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] -#define ngx_http_conf_get_module_main_conf(cf, module) \ - ((ngx_http_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index] /* * ngx_http_conf_get_module_srv_conf() and ngx_http_conf_get_module_loc_conf() - * could not be correctly implemented because at the merge phase cf->ctx - * points to http{}'s ctx + * msut not be used because at the merge phase cf->ctx points to http{}'s ctx */ +#define ngx_http_conf_get_module_main_conf(cf, module) \ + ((ngx_http_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index] +#define ngx_http_conf_get_module_srv_conf(cf, module) \ + ((ngx_http_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index] +#define ngx_http_conf_get_module_loc_conf(cf, module) \ + ((ngx_http_conf_ctx_t *) cf->ctx)->loc_conf[module.ctx_index] + #define ngx_http_cycle_get_module_main_conf(cycle, module) \ ((ngx_http_conf_ctx_t *) \ cycle->conf_ctx[ngx_http_module.index])->main_conf[module.ctx_index] 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 @@ -5,9 +5,16 @@ #include #include +/* STUB */ +#define NGX_HTTP_LOCATION_EXACT 1 +#define NGX_HTTP_LOCATION_AUTO_REDIRECT 2 +#define NGX_HTTP_LOCATION_REGEX 3 + static void ngx_http_phase_event_handler(ngx_event_t *rev); static void ngx_http_run_phases(ngx_http_request_t *r); +static ngx_int_t ngx_http_find_location(ngx_http_request_t *r, + ngx_array_t *locations); static void *ngx_http_core_create_main_conf(ngx_conf_t *cf); static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf); @@ -103,7 +110,7 @@ static ngx_command_t ngx_http_core_comm &ngx_http_restrict_host_names }, { ngx_string("location"), - NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, + NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, ngx_location_block, NGX_HTTP_SRV_CONF_OFFSET, 0, @@ -463,121 +470,25 @@ static void ngx_http_run_phases(ngx_http ngx_int_t ngx_http_find_location_config(ngx_http_request_t *r) { - int rc; - ngx_uint_t i; - ngx_str_t *auto_redirect; - ngx_http_core_loc_conf_t *clcf, **clcfp; - ngx_http_core_srv_conf_t *cscf; -#if (HAVE_PCRE) - ngx_uint_t exact; -#endif + ngx_int_t rc; + ngx_http_core_loc_conf_t *clcf; + ngx_http_core_srv_conf_t *cscf; cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); - auto_redirect = NULL; -#if (HAVE_PCRE) - exact = 0; -#endif - clcfp = cscf->locations.elts; - for (i = 0; i < cscf->locations.nelts; i++) { - -#if (HAVE_PCRE) - - if (clcfp[i]->regex) { - break; - } -#endif - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "find location: %s\"%s\"", - clcfp[i]->exact_match ? "= " : "", - clcfp[i]->name.data); + rc = ngx_http_find_location(r, &cscf->locations); - if (clcfp[i]->auto_redirect - && r->uri.len == clcfp[i]->name.len - 1 - && ngx_strncmp(r->uri.data, clcfp[i]->name.data, - clcfp[i]->name.len - 1) == 0) - { - auto_redirect = &clcfp[i]->name; - continue; - } - - if (r->uri.len < clcfp[i]->name.len) { - continue; - } - - rc = ngx_strncmp(r->uri.data, clcfp[i]->name.data, clcfp[i]->name.len); - - if (rc < 0) { - /* locations are lexicographically sorted */ - break; - } - - if (rc == 0) { - r->loc_conf = clcfp[i]->loc_conf; - 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; - } - - if (clcfp[i]->exact_match && r->uri.len == clcfp[i]->name.len) { -#if (HAVE_PCRE) - exact = 1; -#endif - break; - } - } + if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { + return rc; } -#if (HAVE_PCRE) - - if (!exact && !auto_redirect) { - /* regex matches */ - - for (/* void */; i < cscf->locations.nelts; i++) { - - if (!clcfp[i]->regex) { - continue; - } - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "find location: %s\"%s\"", - clcfp[i]->exact_match ? "= " : - clcfp[i]->regex ? "~ " : "", - clcfp[i]->name.data); - - rc = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0); - - if (rc == NGX_DECLINED) { - continue; - } + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - 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, clcfp[i]->name.data); - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - /* match */ - - r->loc_conf = clcfp[i]->loc_conf; - 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; - } + 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; } -#endif /* HAVE_PCRE */ - - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - if (!(ngx_io.flags & NGX_IO_SENDFILE) || !clcf->sendfile) { r->sendfile = 0; @@ -609,14 +520,14 @@ ngx_int_t ngx_http_find_location_config( } - if (auto_redirect) { + if (rc == NGX_HTTP_LOCATION_AUTO_REDIRECT) { if (!(r->headers_out.location = ngx_http_add_header(&r->headers_out, ngx_http_headers_out))) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } - r->headers_out.location->value = *auto_redirect; + r->headers_out.location->value = clcf->name; return NGX_HTTP_MOVED_PERMANENTLY; } @@ -629,6 +540,125 @@ ngx_int_t ngx_http_find_location_config( } +static ngx_int_t ngx_http_find_location(ngx_http_request_t *r, + ngx_array_t *locations) +{ + ngx_int_t n, rc; + ngx_uint_t i, found; + ngx_http_core_loc_conf_t *clcf, **clcfp; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "find location"); + + found = 0; + + clcfp = locations->elts; + for (i = 0; i < locations->nelts; i++) { + +#if (HAVE_PCRE) + if (clcfp[i]->regex) { + break; + } +#endif + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "find location: %s\"%s\"", + clcfp[i]->exact_match ? "= " : "", + clcfp[i]->name.data); + + if (clcfp[i]->auto_redirect + && r->uri.len == clcfp[i]->name.len - 1 + && ngx_strncmp(r->uri.data, clcfp[i]->name.data, + clcfp[i]->name.len - 1) == 0) + { + /* the locations are lexicographically sorted */ + + r->loc_conf = clcfp[i]->loc_conf; + + return NGX_HTTP_LOCATION_AUTO_REDIRECT; + } + + if (r->uri.len < clcfp[i]->name.len) { + continue; + } + + n = ngx_strncmp(r->uri.data, clcfp[i]->name.data, clcfp[i]->name.len); + + if (n < 0) { + /* the locations are lexicographically sorted */ + break; + } + + if (n == 0) { + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->name.len >= clcfp[i]->name.len) { + /* the previous match is longer */ + break; + } + + r->loc_conf = clcfp[i]->loc_conf; + + if (clcfp[i]->exact_match && r->uri.len == clcfp[i]->name.len) { + return NGX_HTTP_LOCATION_EXACT; + } + + found = 1; + } + } + + if (found) { + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->locations.nelts) { + rc = ngx_http_find_location(r, &clcf->locations); + + if (rc != NGX_OK) { + return rc; + } + } + } + +#if (HAVE_PCRE) + + /* regex matches */ + + for (/* void */; i < locations->nelts; i++) { + + if (!clcfp[i]->regex) { + continue; + } + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "find location: ~ \"%s\"", + clcfp[i]->name.data); + + n = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0); + + if (n == NGX_DECLINED) { + continue; + } + + if (n < 0) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + ngx_regex_exec_n + " failed: %d on \"%s\" using \"%s\"", + n, r->uri.data, clcfp[i]->name.data); + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + /* match */ + + r->loc_conf = clcfp[i]->loc_conf; + + return NGX_HTTP_LOCATION_REGEX; + } + +#endif /* HAVE_PCRE */ + + return NGX_OK; +} + + ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r) { uint32_t key; @@ -799,7 +829,7 @@ ngx_int_t ngx_http_internal_redirect(ngx } -#if 1 /* STUB: test the delay http handler */ +#if 0 /* STUB: test the delay http handler */ int ngx_http_delay_handler(ngx_http_request_t *r) { @@ -863,7 +893,7 @@ static char *ngx_server_block(ngx_conf_t char *rv; ngx_http_module_t *module; ngx_conf_t pvcf; - ngx_http_conf_ctx_t *ctx, *hctx; + ngx_http_conf_ctx_t *ctx, *http_ctx; ngx_http_core_main_conf_t *cmcf; ngx_http_core_srv_conf_t *cscf, **cscfp; @@ -871,8 +901,8 @@ static char *ngx_server_block(ngx_conf_t ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), NGX_CONF_ERROR); - hctx = (ngx_http_conf_ctx_t *) cf->ctx; - ctx->main_conf = hctx->main_conf; + http_ctx = cf->ctx; + ctx->main_conf = http_ctx->main_conf; /* the server{}'s srv_conf */ @@ -928,7 +958,7 @@ static char *ngx_server_block(ngx_conf_t } ngx_qsort(cscf->locations.elts, (size_t) cscf->locations.nelts, - sizeof(void *), ngx_cmp_locations); + sizeof(ngx_http_core_loc_conf_t *), ngx_cmp_locations); return rv; } @@ -936,20 +966,21 @@ static char *ngx_server_block(ngx_conf_t static int ngx_cmp_locations(const void *one, const void *two) { - ngx_http_core_loc_conf_t *first = *(ngx_http_core_loc_conf_t **) one; - ngx_http_core_loc_conf_t *second = *(ngx_http_core_loc_conf_t **) two; + ngx_int_t rc; + ngx_http_core_loc_conf_t *first, *second; - ngx_int_t rc; + first = *(ngx_http_core_loc_conf_t **) one; + second = *(ngx_http_core_loc_conf_t **) two; #if (HAVE_PCRE) if (first->regex && !second->regex) { - /* shift regex matches to the end */ + /* shift the regex matches to the end */ return 1; } if (first->regex || second->regex) { - /* do not sort regex matches */ + /* do not sort the regex matches */ return 0; } @@ -971,11 +1002,11 @@ static char *ngx_location_block(ngx_conf char *rv; ngx_int_t m; ngx_str_t *value; + ngx_conf_t pcf; ngx_http_module_t *module; - ngx_conf_t pvcf; - ngx_http_conf_ctx_t *ctx, *pvctx; + ngx_http_conf_ctx_t *ctx, *pctx; ngx_http_core_srv_conf_t *cscf; - ngx_http_core_loc_conf_t *clcf, **clcfp; + ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp; #if (HAVE_PCRE) ngx_str_t err; u_char errstr[NGX_MAX_CONF_ERRSTR]; @@ -985,9 +1016,9 @@ static char *ngx_location_block(ngx_conf return NGX_CONF_ERROR; } - pvctx = (ngx_http_conf_ctx_t *) cf->ctx; - ctx->main_conf = pvctx->main_conf; - ctx->srv_conf = pvctx->srv_conf; + pctx = cf->ctx; + ctx->main_conf = pctx->main_conf; + ctx->srv_conf = pctx->srv_conf; ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); if (ctx->loc_conf == NULL) { @@ -1060,17 +1091,52 @@ static char *ngx_location_block(ngx_conf clcf->name.data = value[1].data; } - cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; - if (!(clcfp = ngx_push_array(&cscf->locations))) { - return NGX_CONF_ERROR; + pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index]; + + if (pclcf->name.len == 0) { + cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; + if (!(clcfp = ngx_push_array(&cscf->locations))) { + return NGX_CONF_ERROR; + } + + } else { + clcf->prev_location = pclcf; + + if (pclcf->exact_match) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "location \"%s\" could not be inside " + "the exact location \"%s\"", + clcf->name.data, pclcf->name.data); + return NGX_CONF_ERROR; + } + + if (clcf->regex == NULL + && ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len) + != 0) + { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "location \"%s\" is outside location \"%s\"", + clcf->name.data, pclcf->name.data); + return NGX_CONF_ERROR; + } + + if (pclcf->locations.elts == NULL) { + ngx_init_array(pclcf->locations, cf->pool, 5, sizeof(void *), + NGX_CONF_ERROR); + } + + if (!(clcfp = ngx_push_array(&pclcf->locations))) { + return NGX_CONF_ERROR; + } } + *clcfp = clcf; - pvcf = *cf; + pcf = *cf; cf->ctx = ctx; cf->cmd_type = NGX_HTTP_LOC_CONF; rv = ngx_conf_parse(cf, NULL); - *cf = pvcf; + *cf = pcf; return rv; } @@ -1220,9 +1286,12 @@ static char *ngx_http_core_merge_srv_con n->name.len = ngx_strlen(n->name.data); n->core_srv_conf = conf; +#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) { cmcf->max_server_name_len = n->name.len; @@ -1478,8 +1547,11 @@ static char *ngx_set_server_name(ngx_con /* 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; 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 @@ -124,9 +124,24 @@ typedef struct { } ngx_http_err_page_t; -typedef struct { +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 */ - void **loc_conf ; /* pointer to the modules' loc_conf */ + +#if (HAVE_PCRE) + ngx_regex_t *regex; +#endif + + unsigned exact_match:1; + unsigned auto_redirect:1; + unsigned alias:1; + + /* array of inclusive ngx_http_core_loc_conf_t */ + ngx_array_t locations; + + /* pointer to the modules' loc_conf */ + void **loc_conf ; ngx_http_handler_pt handler; @@ -157,16 +172,10 @@ typedef struct { ngx_http_cache_hash_t *open_files; -#if (HAVE_PCRE) - ngx_regex_t *regex; -#endif + ngx_log_t *err_log; - unsigned exact_match:1; - unsigned auto_redirect:1; - unsigned alias:1; - - ngx_log_t *err_log; -} ngx_http_core_loc_conf_t; + ngx_http_core_loc_conf_t *prev_location; +}; extern ngx_http_module_t ngx_http_core_module_ctx; 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 @@ -7,7 +7,7 @@ static void ngx_http_init_request(ngx_event_t *ev); #if (NGX_HTTP_SSL) -static void ngx_http_check_ssl_handshake(ngx_event_t *rev); +static void ngx_http_ssl_handshake(ngx_event_t *rev); #endif static void ngx_http_process_request_line(ngx_event_t *rev); static void ngx_http_process_request_headers(ngx_event_t *rev); @@ -238,22 +238,32 @@ static void ngx_http_init_request(ngx_ev rev->event_handler = ngx_http_process_request_line; - r->recv = ngx_recv; - r->send_chain = ngx_send_chain; - #if (NGX_HTTP_SSL) sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); if (sscf->enable) { - if (ngx_ssl_create_session(sscf->ssl_ctx, c, NGX_SSL_BUFFER) + + if (c->ssl == NULL) { + if (ngx_ssl_create_session(sscf->ssl_ctx, c, NGX_SSL_BUFFER) == NGX_ERROR) - { - ngx_http_close_connection(c); - return; + { + ngx_http_close_connection(c); + return; + } + + /* + * The majority of browsers do not send the "close notify" alert. + * Among them are MSIE, Mozilla, Netscape 4, Konqueror, and Links. + * And what is more MSIE ignores the server's alert. + * + * Opera always sends the alert. + */ + + c->ssl->no_rcv_shut = 1; + rev->event_handler = ngx_http_ssl_handshake; } r->filter_need_in_memory = 1; - rev->event_handler = ngx_http_check_ssl_handshake; } #endif @@ -339,9 +349,10 @@ static void ngx_http_init_request(ngx_ev #if (NGX_HTTP_SSL) -static void ngx_http_check_ssl_handshake(ngx_event_t *rev) +static void ngx_http_ssl_handshake(ngx_event_t *rev) { int n; + ngx_int_t rc; u_char buf[1]; ngx_connection_t *c; ngx_http_request_t *r; @@ -368,8 +379,20 @@ static void ngx_http_check_ssl_handshake ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "https ssl handshake: 0x%X", buf[0]); - r->recv = ngx_ssl_recv; - r->send_chain = ngx_ssl_send_chain; + c->recv = ngx_ssl_recv; + c->send_chain = ngx_ssl_send_chain; + + rc = ngx_ssl_handshake(c); + + if (rc == NGX_ERROR) { + ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST); + ngx_http_close_connection(r->connection); + return; + } + + if (rc != NGX_OK) { + return; + } } else { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, @@ -892,8 +915,8 @@ static ssize_t ngx_http_read_request_hea return NGX_AGAIN; } - n = r->recv(r->connection, r->header_in->last, - r->header_in->end - r->header_in->last); + n = r->connection->recv(r->connection, r->header_in->last, + r->header_in->end - r->header_in->last); if (n == NGX_AGAIN) { if (!r->header_timeout_set) { @@ -963,7 +986,10 @@ static ngx_int_t ngx_http_process_reques clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); r->connection->log->file = clcf->err_log->file; - r->connection->log->log_level = clcf->err_log->log_level; + if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) + { + r->connection->log->log_level = clcf->err_log->log_level; + } break; } @@ -1040,6 +1066,12 @@ static ngx_int_t ngx_http_process_reques if (ua[4] == ' ' && ua[5] == '4' && ua[6] == '.') { r->headers_in.msie4 = 1; } + +#if 0 + /* MSIE ignores the SSL "close notify" alert */ + + ngx_ssl_set_nosendshut(r->connection->ssl); +#endif } } @@ -1355,7 +1387,8 @@ static ngx_int_t ngx_http_read_discarded size = (ssize_t) clcf->discarded_buffer_size; } - n = ngx_recv(r->connection, r->discarded_buffer, size); + n = r->connection->recv(r->connection, r->discarded_buffer, size); + if (n == NGX_ERROR) { r->closed = 1; @@ -1502,7 +1535,8 @@ static void ngx_http_keepalive_handler(n c->log_error = NGX_ERROR_IGNORE_ECONNRESET; ngx_set_socket_errno(0); - n = ngx_recv(c, c->buffer->last, c->buffer->end - c->buffer->last); + + n = c->recv(c, c->buffer->last, c->buffer->end - c->buffer->last); c->log_error = NGX_ERROR_INFO; if (n == NGX_AGAIN) { @@ -1533,7 +1567,7 @@ static void ngx_http_keepalive_handler(n static void ngx_http_set_lingering_close(ngx_http_request_t *r) -{ +{ ngx_event_t *rev, *wev; ngx_connection_t *c; ngx_http_core_loc_conf_t *clcf; @@ -1640,7 +1674,7 @@ static void ngx_http_lingering_close_han } do { - n = ngx_recv(c, r->discarded_buffer, clcf->discarded_buffer_size); + n = c->recv(c, r->discarded_buffer, clcf->discarded_buffer_size); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %d", n); 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 @@ -218,9 +218,6 @@ struct ngx_http_request_s { ngx_connection_t *connection; - ngx_recv_pt recv; - ngx_send_chain_pt send_chain; - void **ctx; void **main_conf; void **srv_conf; diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c +++ b/src/http/ngx_http_request_body.c @@ -140,7 +140,7 @@ static ngx_int_t ngx_http_do_read_client size = r->request_body->rest; } - n = ngx_recv(c, r->request_body->buf->last, size); + n = c->recv(c, r->request_body->buf->last, size); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http client request body recv " SIZE_T_FMT, n); diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -104,9 +104,11 @@ static char error_416_page[] = static char error_497_page[] = "" CRLF -"The plain HTTP request was sent to HTTPS port" CRLF +"400 The plain HTTP request was sent to HTTPS port" +CRLF "" CRLF -"

The plain HTTP request was sent to HTTPS por

" CRLF +"

400 Bad Request

" CRLF +"
The plain HTTP request was sent to HTTPS port
" CRLF ; @@ -174,7 +176,7 @@ static ngx_str_t error_pages[] = { ngx_null_string, /* 415 */ ngx_string(error_416_page), - ngx_string(error_400_page), /* 497, http to https */ + ngx_string(error_497_page), /* 497, http to https */ ngx_string(error_404_page), /* 498, invalid host name */ ngx_null_string, /* 499, client closed connection */ diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -45,6 +45,7 @@ ngx_int_t ngx_http_write_filter(ngx_http int last; off_t size, flush, sent; ngx_chain_t *cl, *ln, **ll, *chain; + ngx_connection_t *c; ngx_http_core_loc_conf_t *clcf; ngx_http_write_filter_ctx_t *ctx; @@ -95,7 +96,9 @@ ngx_int_t ngx_http_write_filter(ngx_http } } - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + c = r->connection; + + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, "http write filter: l:%d f:" OFF_T_FMT " s:" OFF_T_FMT, last, flush, size); @@ -112,7 +115,7 @@ ngx_int_t ngx_http_write_filter(ngx_http return NGX_OK; } - if (r->connection->write->delayed) { + if (c->write->delayed) { return NGX_AGAIN; } @@ -124,17 +127,17 @@ ngx_int_t ngx_http_write_filter(ngx_http return NGX_OK; } - sent = r->connection->sent; + sent = c->sent; - chain = r->send_chain(r->connection, ctx->out, + chain = c->send_chain(c, ctx->out, clcf->limit_rate ? clcf->limit_rate: OFF_T_MAX_VALUE); - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http write filter %X", chain); if (clcf->limit_rate) { - sent = r->connection->sent - sent; - r->connection->write->delayed = 1; + sent = c->sent - sent; + c->write->delayed = 1; ngx_add_timer(r->connection->write, (ngx_msec_t) (sent * 1000 / clcf->limit_rate)); }