Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2004-10-11 19:07:03 +0400
committerIgor Sysoev <igor@sysoev.ru>2004-10-11 19:07:03 +0400
commit924bd79e317e9a137c0d1b9d349185758a628ec4 (patch)
treef877c8b19e53e7d0a7683e3dd9aeb713146c4a8f /src/http/modules/proxy
parentaef13d7f6660f4f8d2c50c95b8e182e62c115f88 (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.c99
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_handler.h1
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_header.c20
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_parse.c3
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_upstream.c33
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);