diff options
author | Igor Sysoev <igor@sysoev.ru> | 2004-10-11 19:07:03 +0400 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2004-10-11 19:07:03 +0400 |
commit | 924bd79e317e9a137c0d1b9d349185758a628ec4 (patch) | |
tree | f877c8b19e53e7d0a7683e3dd9aeb713146c4a8f /src/http/modules/proxy | |
parent | aef13d7f6660f4f8d2c50c95b8e182e62c115f88 (diff) |
nginx-0.1.1-RELEASE importrelease-0.1.1
*) Feature: the gzip_types directive.
*) Feature: the tcp_nodelay directive.
*) Feature: the send_lowat directive is working not only on OSes that
support kqueue NOTE_LOWAT, but also on OSes that support SO_SNDLOWAT.
*) Feature: the setproctitle() emulation for Linux and Solaris.
*) Bugfix: the "Location" header rewrite bug fixed while the proxying.
*) Bugfix: the ngx_http_chunked_module module may get caught in an
endless loop.
*) Bugfix: the /dev/poll module bugs fixed.
*) Bugfix: the responses were corrupted when the temporary files were
used while the proxying.
*) Bugfix: the unescaped requests were passed to the backend.
*) Bugfix: while the build configuration on Linux 2.4 the
--with-poll_module parameter was required.
Diffstat (limited to 'src/http/modules/proxy')
-rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_handler.c | 99 | ||||
-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 | 20 | ||||
-rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_parse.c | 3 | ||||
-rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_upstream.c | 33 |
5 files changed, 117 insertions, 39 deletions
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c index 3fa2e0bf3..f0794f36e 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -29,6 +29,11 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, static char *ngx_http_proxy_parse_upstream(ngx_str_t *url, ngx_http_proxy_upstream_conf_t *u); +static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data); + +static ngx_conf_post_t ngx_http_proxy_lowat_post = + { ngx_http_proxy_lowat_check } ; + static ngx_conf_bitmask_t next_upstream_masks[] = { { ngx_string("error"), NGX_HTTP_PROXY_FT_ERROR }, @@ -79,6 +84,13 @@ static ngx_command_t ngx_http_proxy_commands[] = { offsetof(ngx_http_proxy_loc_conf_t, send_timeout), NULL }, + { ngx_string("proxy_send_lowat"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_size_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, send_lowat), + &ngx_http_proxy_lowat_post }, + { ngx_string("proxy_preserve_host"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot, @@ -877,6 +889,7 @@ static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf) conf->connect_timeout = NGX_CONF_UNSET_MSEC; conf->send_timeout = NGX_CONF_UNSET_MSEC; + conf->send_lowat = NGX_CONF_UNSET_SIZE; conf->preserve_host = NGX_CONF_UNSET; conf->set_x_real_ip = NGX_CONF_UNSET; @@ -920,6 +933,7 @@ static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, ngx_conf_merge_msec_value(conf->connect_timeout, prev->connect_timeout, 60000); ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000); + ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0); ngx_conf_merge_value(conf->preserve_host, prev->preserve_host, 0); ngx_conf_merge_value(conf->set_x_real_ip, prev->set_x_real_ip, 0); @@ -1073,17 +1087,21 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, value = cf->args->elts; if (ngx_strncasecmp(value[1].data, "http://", 7) != 0) { - return "invalid URL prefix"; + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid URL prefix"); + return NGX_CONF_ERROR; } - ngx_test_null(lcf->upstream, - ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_upstream_conf_t)), - NGX_CONF_ERROR); + lcf->upstream = ngx_pcalloc(cf->pool, + sizeof(ngx_http_proxy_upstream_conf_t)); + if (lcf->upstream == NULL) { + return NGX_CONF_ERROR; + } lcf->upstream->url.len = value[1].len; if (!(lcf->upstream->url.data = ngx_palloc(cf->pool, value[1].len + 1))) { return NGX_CONF_ERROR; } + ngx_cpystrn(lcf->upstream->url.data, value[1].data, value[1].len + 1); value[1].data += 7; @@ -1092,11 +1110,14 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, err = ngx_http_proxy_parse_upstream(&value[1], lcf->upstream); if (err) { - return err; + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, err); + return NGX_CONF_ERROR; + } + + if (!(host = ngx_palloc(cf->pool, lcf->upstream->host.len + 1))) { + return NGX_CONF_ERROR; } - ngx_test_null(host, ngx_palloc(cf->pool, lcf->upstream->host.len + 1), - NGX_CONF_ERROR); ngx_cpystrn(host, lcf->upstream->host.data, lcf->upstream->host.len + 1); /* AF_INET only */ @@ -1115,11 +1136,12 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, /* MP: ngx_shared_palloc() */ - ngx_test_null(lcf->peers, - ngx_pcalloc(cf->pool, - sizeof(ngx_peers_t) - + sizeof(ngx_peer_t) * (i - 1)), - NGX_CONF_ERROR); + lcf->peers = ngx_pcalloc(cf->pool, + sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (i - 1)); + + if (lcf->peers == NULL) { + return NGX_CONF_ERROR; + } lcf->peers->number = i; @@ -1130,9 +1152,12 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, lcf->peers->peers[i].port = lcf->upstream->port; len = INET_ADDRSTRLEN + lcf->upstream->port_text.len + 1; - ngx_test_null(lcf->peers->peers[i].addr_port_text.data, - ngx_palloc(cf->pool, len), - NGX_CONF_ERROR); + + lcf->peers->peers[i].addr_port_text.data = + ngx_palloc(cf->pool, len); + if (lcf->peers->peers[i].addr_port_text.data == NULL) { + return NGX_CONF_ERROR; + } len = ngx_inet_ntop(AF_INET, &lcf->peers->peers[i].addr, @@ -1153,8 +1178,9 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, /* MP: ngx_shared_palloc() */ - ngx_test_null(lcf->peers, ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)), - NGX_CONF_ERROR); + if (!(lcf->peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t)))) { + return NGX_CONF_ERROR; + } lcf->peers->number = 1; @@ -1165,9 +1191,11 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, len = lcf->upstream->host.len + lcf->upstream->port_text.len + 1; - ngx_test_null(lcf->peers->peers[0].addr_port_text.data, - ngx_palloc(cf->pool, len + 1), - NGX_CONF_ERROR); + lcf->peers->peers[0].addr_port_text.data = + ngx_palloc(cf->pool, len + 1); + if (lcf->peers->peers[0].addr_port_text.data == NULL) { + return NGX_CONF_ERROR; + } len = lcf->upstream->host.len; @@ -1278,3 +1306,34 @@ static char *ngx_http_proxy_parse_upstream(ngx_str_t *url, return "invalid port in upstream URL"; } + + +static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data) +{ +#if __FreeBSD__ + + ssize_t *np = data; + + 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 " + "(sysctl net.inet.tcp.sendspace)", + ngx_freebsd_net_inet_tcp_sendspace); + + return NGX_CONF_ERROR; + } + + +#else + +#if 0 + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "\"proxy_send_lowat\" is not supported, ignored"); + + *np = 0; +#endif + +#endif + + return NGX_CONF_OK; +} diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h index 4dcc65387..728259c45 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.h +++ b/src/http/modules/proxy/ngx_http_proxy_handler.h @@ -54,6 +54,7 @@ typedef struct { typedef struct { + size_t send_lowat; size_t header_buffer_size; size_t busy_buffers_size; size_t max_temp_file_size; diff --git a/src/http/modules/proxy/ngx_http_proxy_header.c b/src/http/modules/proxy/ngx_http_proxy_header.c index 038001240..07722fc89 100644 --- a/src/http/modules/proxy/ngx_http_proxy_header.c +++ b/src/http/modules/proxy/ngx_http_proxy_header.c @@ -164,24 +164,26 @@ static int ngx_http_proxy_rewrite_location_header(ngx_http_proxy_ctx_t *p, return NGX_ERROR; } - /* - * we do not set r->headers_out.location to avoid the handling - * the local redirects without a host name by ngx_http_header_filter() - */ - -#if 0 - r->headers_out.location = location; -#endif - if (uc->url.len > loc->value.len || ngx_rstrncmp(loc->value.data, uc->url.data, uc->url.len) != 0) { + + /* + * we do not set r->headers_out.location here to avoid the handling + * the local redirects without a host name by ngx_http_header_filter() + */ + *location = *loc; return NGX_OK; } /* TODO: proxy_reverse */ + r->headers_out.location = location; + + location->key.len = 0; + location->key.data = NULL; + location->value.len = uc->location->len + (loc->value.len - uc->url.len) + 1; if (!(location->value.data = ngx_palloc(r->pool, location->value.len))) { diff --git a/src/http/modules/proxy/ngx_http_proxy_parse.c b/src/http/modules/proxy/ngx_http_proxy_parse.c index 3718ab050..c10cf4924 100644 --- a/src/http/modules/proxy/ngx_http_proxy_parse.c +++ b/src/http/modules/proxy/ngx_http_proxy_parse.c @@ -155,6 +155,9 @@ int ngx_http_proxy_parse_status_line(ngx_http_proxy_ctx_t *p) case ' ': state = sw_status_text; break; + case '.': /* IIS may send 403.1, 403.2, etc */ + state = sw_status_text; + break; case CR: state = sw_almost_done; break; diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c index c1a8fb621..be5d69a22 100644 --- a/src/http/modules/proxy/ngx_http_proxy_upstream.c +++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c @@ -115,6 +115,7 @@ int ngx_http_proxy_request_upstream(ngx_http_proxy_ctx_t *p) static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p) { size_t len; + ngx_int_t escape; ngx_uint_t i; ngx_buf_t *b; ngx_chain_t *chain; @@ -133,14 +134,20 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p) len = r->method_name.len; } + if (r->quoted_uri) { + escape = 2 * ngx_escape_uri(NULL, r->uri.data + uc->location->len, + r->uri.len - uc->location->len); + } else { + escape = 0; + } + len += uc->uri.len - + r->uri.len - uc->location->len + + r->uri.len - uc->location->len + escape + 1 + r->args.len /* 1 is for "?" */ + sizeof(http_version) - 1 + sizeof(connection_close_header) - 1 + 2; /* 2 is for "\r\n" at the header end */ - if (p->lcf->preserve_host && r->headers_in.host) { len += sizeof(host_header) - 1 + r->headers_in.host_name_len @@ -218,9 +225,16 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p) b->last = ngx_cpymem(b->last, uc->uri.data, uc->uri.len); - b->last = ngx_cpymem(b->last, - r->uri.data + uc->location->len, - r->uri.len - uc->location->len); + if (escape) { + ngx_escape_uri(b->last, r->uri.data + uc->location->len, + r->uri.len - uc->location->len); + b->last += r->uri.len - uc->location->len + escape; + + } else { + b->last = ngx_cpymem(b->last, + r->uri.data + uc->location->len, + r->uri.len - uc->location->len); + } if (r->args.len > 0) { *(b->last++) = '?'; @@ -422,7 +436,7 @@ static void ngx_http_proxy_init_upstream(void *data) p->upstream->output_chain_ctx = output; - output->sendfile = r->sendfile; + output->sendfile = r->connection->sendfile; output->pool = r->pool; output->bufs.num = 1; output->tag = (ngx_buf_tag_t) &ngx_http_proxy_module; @@ -737,8 +751,7 @@ static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p) if (rc == NGX_AGAIN) { ngx_add_timer(c->write, p->lcf->send_timeout); - c->write->available = /* STUB: lowat */ 0; - if (ngx_handle_write_event(c->write, NGX_LOWAT_EVENT) == NGX_ERROR) { + if (ngx_handle_write_event(c->write, p->lcf->send_lowat) == NGX_ERROR) { ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } @@ -1172,6 +1185,7 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p) r = p->request; r->headers_out.status = p->upstream->status; + r->headers_out.status_line = p->upstream->status_line; #if 0 r->headers_out.content_length_n = -1; @@ -1298,11 +1312,10 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p) */ ep->cyclic_temp_file = 1; - r->sendfile = 0; + r->connection->sendfile = 0; } else { ep->cyclic_temp_file = 0; - r->sendfile = 1; } clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |