From appa at perusio.net Fri Feb 1 13:52:46 2013 From: appa at perusio.net (=?UTF-8?B?QW50w7NuaW8=?= P. P. Almeida) Date: Fri, 01 Feb 2013 14:52:46 +0100 Subject: Transforming SSL server cert and private key in variables. In-Reply-To: <20130122133440.GH9787@mdounin.ru> References: <87mww14ix3.wl%appa@perusio.net> <20130122112104.GB9787@mdounin.ru> <87libl4b1c.wl%appa@perusio.net> <20130122133440.GH9787@mdounin.ru> Message-ID: <87vcac9m4x.wl%appa@perusio.net> On 22 Jan 2013 14h34 CET, mdounin at mdounin.ru wrote: Hello Maxim, I made some tests and definitely we cannot use in our product, it takes too much time and resources. Tested on an EC m1.medium instance. HOSTS,DATE,COMMAND,CPU_PERCENTAGE,CPU_SYSTEM,CPU_USER,ELAPSED_TIME,IO_PG_FAULTS,ICONTEXT_SWITCHING,VCONTEXT_SWITCHING,MAX_MEMORY 5001,01.Feb.2013 00:18:33,/usr/sbin/nginx -s reload,92%,0.60,1.84,0:02.62,0,3296,1,138528 10001,01.Feb.2013 00:19:32,/usr/sbin/nginx -s reload,93%,1.67,5.80,0:08.00,0,11627,1,406804 20001,01.Feb.2013 00:20:23,/usr/sbin/nginx -s reload,93%,4.17,13.68,0:19.16,0,25221,1,945164 50001,01.Feb.2013 00:22:02,/usr/sbin/nginx -s reload,60%,13.24,36.37,1:22.46,14,68338,87121,2288668 As you can see 50k hosts take more than one minute. That would be acceptable if it weren't for the fact that it uses up a lot of CPU and memory. Parsing the config seems to be the culprit here. These where simple server blocks with self-signed certs just for testing. It would be awesome if there was some sort of compilation process for the config parsing. It's too costly. Let's say you have a machine with 50k hosts, now you add another one and the machine gets a beating just for adding this one. Any comments on my test approach? Thanks, --- appa From mat999 at gmail.com Fri Feb 1 14:09:56 2013 From: mat999 at gmail.com (SplitIce) Date: Sat, 2 Feb 2013 00:39:56 +1030 Subject: Transforming SSL server cert and private key in variables. In-Reply-To: <87vcac9m4x.wl%appa@perusio.net> References: <87mww14ix3.wl%appa@perusio.net> <20130122112104.GB9787@mdounin.ru> <87libl4b1c.wl%appa@perusio.net> <20130122133440.GH9787@mdounin.ru> <87vcac9m4x.wl%appa@perusio.net> Message-ID: On a side note, a good feature for nginx would be a small SHM zone for storing SSL certificates cross reload (paired with a filemtime value) to speed up reloads. I run alot of SSL certificates myself (not using SNI but unique IPs) around 300 per node (and 7 nodes refreshed up to every minute) and have noticed the decent CPU percentage. On Sat, Feb 2, 2013 at 12:22 AM, Ant?nio P. P. Almeida wrote: > On 22 Jan 2013 14h34 CET, mdounin at mdounin.ru wrote: > > Hello Maxim, > > I made some tests and definitely we cannot use in our product, it > takes too much time and resources. > > Tested on an EC m1.medium instance. > > > HOSTS,DATE,COMMAND,CPU_PERCENTAGE,CPU_SYSTEM,CPU_USER,ELAPSED_TIME,IO_PG_FAULTS,ICONTEXT_SWITCHING,VCONTEXT_SWITCHING,MAX_MEMORY > 5001,01.Feb.2013 00:18:33,/usr/sbin/nginx -s > reload,92%,0.60,1.84,0:02.62,0,3296,1,138528 > 10001,01.Feb.2013 00:19:32,/usr/sbin/nginx -s > reload,93%,1.67,5.80,0:08.00,0,11627,1,406804 > 20001,01.Feb.2013 00:20:23,/usr/sbin/nginx -s > reload,93%,4.17,13.68,0:19.16,0,25221,1,945164 > 50001,01.Feb.2013 00:22:02,/usr/sbin/nginx -s > reload,60%,13.24,36.37,1:22.46,14,68338,87121,2288668 > > As you can see 50k hosts take more than one minute. That would be > acceptable if it weren't for the fact that it uses up a lot of CPU and > memory. Parsing the config seems to be the culprit here. > > These where simple server blocks with self-signed certs just for > testing. > > It would be awesome if there was some sort of compilation process for > the config parsing. It's too costly. Let's say you have a machine with > 50k hosts, now you add another one and the machine gets a beating just > for adding this one. > > Any comments on my test approach? > > Thanks, > --- appa > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Fri Feb 1 14:37:44 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Fri, 1 Feb 2013 14:37:44 +0000 Subject: [nginx] svn commit: r5025 - trunk/src/event Message-ID: <20130201143744.7819B3FA11C@mail.nginx.com> Author: mdounin Date: 2013-02-01 14:37:43 +0000 (Fri, 01 Feb 2013) New Revision: 5025 URL: http://trac.nginx.org/nginx/changeset/5025/nginx Log: SSL: fixed ngx_ssl_handshake() with level-triggered event methods. Missing calls to ngx_handle_write_event() and ngx_handle_read_event() resulted in a CPU hog during SSL handshake if an level-triggered event method (e.g. select) was used. Modified: trunk/src/event/ngx_event_openssl.c Modified: trunk/src/event/ngx_event_openssl.c =================================================================== --- trunk/src/event/ngx_event_openssl.c 2013-01-28 15:41:12 UTC (rev 5024) +++ trunk/src/event/ngx_event_openssl.c 2013-02-01 14:37:43 UTC (rev 5025) @@ -808,6 +808,10 @@ return NGX_ERROR; } + if (ngx_handle_write_event(c->write, 0) != NGX_OK) { + return NGX_ERROR; + } + return NGX_AGAIN; } @@ -816,6 +820,10 @@ c->read->handler = ngx_ssl_handshake_handler; c->write->handler = ngx_ssl_handshake_handler; + if (ngx_handle_read_event(c->read, 0) != NGX_OK) { + return NGX_ERROR; + } + if (ngx_handle_write_event(c->write, 0) != NGX_OK) { return NGX_ERROR; } From mdounin at mdounin.ru Fri Feb 1 14:38:18 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Fri, 1 Feb 2013 14:38:18 +0000 Subject: [nginx] svn commit: r5026 - trunk/src/http Message-ID: <20130201143818.AF5F03FA147@mail.nginx.com> Author: mdounin Date: 2013-02-01 14:38:18 +0000 (Fri, 01 Feb 2013) New Revision: 5026 URL: http://trac.nginx.org/nginx/changeset/5026/nginx Log: Request body: fixed client_body_in_file_only. After introduction of chunked request body reading support in 1.3.9 (r4931), the rb->bufs wasn't set if request body was fully preread while calling the ngx_http_read_client_request_body() function. Reported by Yichun Zhang (agentzh). Modified: trunk/src/http/ngx_http_request_body.c Modified: trunk/src/http/ngx_http_request_body.c =================================================================== --- trunk/src/http/ngx_http_request_body.c 2013-02-01 14:37:43 UTC (rev 5025) +++ trunk/src/http/ngx_http_request_body.c 2013-02-01 14:38:18 UTC (rev 5026) @@ -35,7 +35,8 @@ size_t preread; ssize_t size; ngx_int_t rc; - ngx_chain_t out; + ngx_buf_t *b; + ngx_chain_t out, *cl; ngx_http_request_body_t *rb; ngx_http_core_loc_conf_t *clcf; @@ -128,6 +129,21 @@ rc = NGX_HTTP_INTERNAL_SERVER_ERROR; goto done; } + + cl = ngx_chain_get_free_buf(r->pool, &rb->free); + if (cl == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + b = cl->buf; + + ngx_memzero(b, sizeof(ngx_buf_t)); + + b->in_file = 1; + b->file_last = rb->temp_file->file.offset; + b->file = &rb->temp_file->file; + + rb->bufs = cl; } post_handler(r); From mdounin at mdounin.ru Fri Feb 1 14:40:20 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Fri, 1 Feb 2013 14:40:20 +0000 Subject: [nginx] svn commit: r5027 - trunk/src/http/modules Message-ID: <20130201144020.7EC8B3F9FA8@mail.nginx.com> Author: mdounin Date: 2013-02-01 14:40:19 +0000 (Fri, 01 Feb 2013) New Revision: 5027 URL: http://trac.nginx.org/nginx/changeset/5027/nginx Log: FastCGI: fixed wrong connection close with fastcgi_keep_conn. With fastcgi_keep_conn it was possible that connection was closed after FCGI_STDERR record with zero padding and without any further data read yet. This happended as f->state was set to ngx_http_fastcgi_st_padding and then "break" happened, resulting in p->length being set to f->padding, i.e. 0 (which in turn resulted in connection close). Fix is to make sure we continue the loop after f->state is set. Modified: trunk/src/http/modules/ngx_http_fastcgi_module.c Modified: trunk/src/http/modules/ngx_http_fastcgi_module.c =================================================================== --- trunk/src/http/modules/ngx_http_fastcgi_module.c 2013-02-01 14:38:18 UTC (rev 5026) +++ trunk/src/http/modules/ngx_http_fastcgi_module.c 2013-02-01 14:40:19 UTC (rev 5027) @@ -1788,10 +1788,6 @@ "FastCGI sent in stderr: \"%*s\"", m + 1 - msg, msg); - if (f->pos == f->last) { - break; - } - } else { if (f->padding) { f->state = ngx_http_fastcgi_st_padding; From mdounin at mdounin.ru Fri Feb 1 14:41:07 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Fri, 1 Feb 2013 14:41:07 +0000 Subject: [nginx] svn commit: r5028 - trunk/src/http/modules Message-ID: <20130201144107.B8CF43F9FA8@mail.nginx.com> Author: mdounin Date: 2013-02-01 14:41:07 +0000 (Fri, 01 Feb 2013) New Revision: 5028 URL: http://trac.nginx.org/nginx/changeset/5028/nginx Log: FastCGI: unconditional state transitions. Checks for f->padding before state transitions make code hard to follow, remove them and make sure we always do another loop iteration after f->state is set to ngx_http_fastcgi_st_padding. Modified: trunk/src/http/modules/ngx_http_fastcgi_module.c Modified: trunk/src/http/modules/ngx_http_fastcgi_module.c =================================================================== --- trunk/src/http/modules/ngx_http_fastcgi_module.c 2013-02-01 14:40:19 UTC (rev 5027) +++ trunk/src/http/modules/ngx_http_fastcgi_module.c 2013-02-01 14:41:07 UTC (rev 5028) @@ -1356,11 +1356,7 @@ } } else { - if (f->padding) { - f->state = ngx_http_fastcgi_st_padding; - } else { - f->state = ngx_http_fastcgi_st_version; - } + f->state = ngx_http_fastcgi_st_padding; } continue; @@ -1597,11 +1593,7 @@ f->length -= u->buffer.pos - start; if (f->length == 0) { - if (f->padding) { - f->state = ngx_http_fastcgi_st_padding; - } else { - f->state = ngx_http_fastcgi_st_version; - } + f->state = ngx_http_fastcgi_st_padding; } if (rc == NGX_HTTP_PARSE_HEADER_DONE) { @@ -1696,13 +1688,8 @@ } if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) { + f->state = ngx_http_fastcgi_st_padding; - if (f->padding) { - f->state = ngx_http_fastcgi_st_padding; - } else { - f->state = ngx_http_fastcgi_st_version; - } - if (!flcf->keep_conn) { p->upstream_done = 1; } @@ -1714,13 +1701,8 @@ } if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) { + f->state = ngx_http_fastcgi_st_padding; - if (f->padding) { - f->state = ngx_http_fastcgi_st_padding; - } else { - f->state = ngx_http_fastcgi_st_version; - } - p->upstream_done = 1; if (flcf->keep_conn) { @@ -1730,7 +1712,7 @@ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0, "http fastcgi sent end request"); - break; + continue; } } @@ -1789,11 +1771,7 @@ m + 1 - msg, msg); } else { - if (f->padding) { - f->state = ngx_http_fastcgi_st_padding; - } else { - f->state = ngx_http_fastcgi_st_version; - } + f->state = ngx_http_fastcgi_st_padding; } continue; @@ -1852,33 +1830,14 @@ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0, "input buf #%d %p", b->num, b->pos); - if (f->pos + f->length < f->last) { - - if (f->padding) { - f->state = ngx_http_fastcgi_st_padding; - } else { - f->state = ngx_http_fastcgi_st_version; - } - + if (f->pos + f->length <= f->last) { + f->state = ngx_http_fastcgi_st_padding; f->pos += f->length; b->last = f->pos; continue; } - if (f->pos + f->length == f->last) { - - if (f->padding) { - f->state = ngx_http_fastcgi_st_padding; - } else { - f->state = ngx_http_fastcgi_st_version; - } - - b->last = f->last; - - break; - } - f->length -= f->last - f->pos; b->last = f->last; From mdounin at mdounin.ru Fri Feb 1 14:41:50 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Fri, 1 Feb 2013 14:41:50 +0000 Subject: [nginx] svn commit: r5029 - trunk/src/http/modules Message-ID: <20130201144150.A526A3FA098@mail.nginx.com> Author: mdounin Date: 2013-02-01 14:41:50 +0000 (Fri, 01 Feb 2013) New Revision: 5029 URL: http://trac.nginx.org/nginx/changeset/5029/nginx Log: FastCGI: proper handling of split fastcgi end request. If fastcgi end request record was split between several network packets, with fastcgi_keep_conn it was possible that connection was saved in incorrect state (e.g. with padding bytes not yet read). Modified: trunk/src/http/modules/ngx_http_fastcgi_module.c Modified: trunk/src/http/modules/ngx_http_fastcgi_module.c =================================================================== --- trunk/src/http/modules/ngx_http_fastcgi_module.c 2013-02-01 14:41:07 UTC (rev 5028) +++ trunk/src/http/modules/ngx_http_fastcgi_module.c 2013-02-01 14:41:50 UTC (rev 5029) @@ -1701,17 +1701,15 @@ } if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) { - f->state = ngx_http_fastcgi_st_padding; - p->upstream_done = 1; + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0, + "http fastcgi sent end request"); - if (flcf->keep_conn) { - r->upstream->keepalive = 1; + if (!flcf->keep_conn) { + p->upstream_done = 1; + break; } - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0, - "http fastcgi sent end request"); - continue; } } @@ -1719,6 +1717,24 @@ if (f->state == ngx_http_fastcgi_st_padding) { + if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) { + + if (f->pos + f->padding < f->last) { + p->upstream_done = 1; + break; + } + + if (f->pos + f->padding == f->last) { + p->upstream_done = 1; + r->upstream->keepalive = 1; + break; + } + + f->padding -= f->last - f->pos; + + break; + } + if (f->pos + f->padding < f->last) { f->state = ngx_http_fastcgi_st_version; f->pos += f->padding; @@ -1777,7 +1793,21 @@ continue; } + if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) { + if (f->pos + f->length <= f->last) { + f->state = ngx_http_fastcgi_st_padding; + f->pos += f->length; + + continue; + } + + f->length -= f->last - f->pos; + + break; + } + + /* f->type == NGX_HTTP_FASTCGI_STDOUT */ if (f->pos == f->last) { From mdounin at mdounin.ru Fri Feb 1 15:25:19 2013 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 1 Feb 2013 19:25:19 +0400 Subject: Transforming SSL server cert and private key in variables. In-Reply-To: <87vcac9m4x.wl%appa@perusio.net> References: <87mww14ix3.wl%appa@perusio.net> <20130122112104.GB9787@mdounin.ru> <87libl4b1c.wl%appa@perusio.net> <20130122133440.GH9787@mdounin.ru> <87vcac9m4x.wl%appa@perusio.net> Message-ID: <20130201152519.GD40753@mdounin.ru> Hello! On Fri, Feb 01, 2013 at 02:52:46PM +0100, Ant?nio P. P. Almeida wrote: > On 22 Jan 2013 14h34 CET, mdounin at mdounin.ru wrote: > > Hello Maxim, > > I made some tests and definitely we cannot use in our product, it > takes too much time and resources. > > Tested on an EC m1.medium instance. > > HOSTS,DATE,COMMAND,CPU_PERCENTAGE,CPU_SYSTEM,CPU_USER,ELAPSED_TIME,IO_PG_FAULTS,ICONTEXT_SWITCHING,VCONTEXT_SWITCHING,MAX_MEMORY > 5001,01.Feb.2013 00:18:33,/usr/sbin/nginx -s reload,92%,0.60,1.84,0:02.62,0,3296,1,138528 > 10001,01.Feb.2013 00:19:32,/usr/sbin/nginx -s reload,93%,1.67,5.80,0:08.00,0,11627,1,406804 > 20001,01.Feb.2013 00:20:23,/usr/sbin/nginx -s reload,93%,4.17,13.68,0:19.16,0,25221,1,945164 > 50001,01.Feb.2013 00:22:02,/usr/sbin/nginx -s reload,60%,13.24,36.37,1:22.46,14,68338,87121,2288668 > > As you can see 50k hosts take more than one minute. That would be > acceptable if it weren't for the fact that it uses up a lot of CPU and > memory. 50k ssl hosts is a lot, actually, and loading 50k certificates in 1 minute on a cheap virtual server looks reasonable for me. Especially if you consider total cost of 50k ssl certs. Please also make sure you are testing recent enough nginx. In paticular, the following commit speeds up ssl loading about 2x here (available in nginx 1.3.11): http://trac.nginx.org/nginx/changeset/5004/nginx The real limiting factor with many server blocks seems to be memory used for each server{}. This probably needs some optimization. > Parsing the config seems to be the culprit here. > > These where simple server blocks with self-signed certs just for > testing. > > It would be awesome if there was some sort of compilation process for > the config parsing. It's too costly. Let's say you have a machine with > 50k hosts, now you add another one and the machine gets a beating just > for adding this one. I don't think that parsing of the config is a culprit. More likely it's SSL certificate reading/checking/various random initialization/generation. (And may be server names hash generation if there are many collisions on server names.) Some profiling would be helpful. -- Maxim Dounin http://nginx.com/support.html From appa at perusio.net Fri Feb 1 15:42:31 2013 From: appa at perusio.net (=?UTF-8?B?QW50w7NuaW8=?= P. P. Almeida) Date: Fri, 01 Feb 2013 16:42:31 +0100 Subject: Transforming SSL server cert and private key in variables. In-Reply-To: <20130201152519.GD40753@mdounin.ru> References: <87mww14ix3.wl%appa@perusio.net> <20130122112104.GB9787@mdounin.ru> <87libl4b1c.wl%appa@perusio.net> <20130122133440.GH9787@mdounin.ru> <87vcac9m4x.wl%appa@perusio.net> <20130201152519.GD40753@mdounin.ru> Message-ID: <87txpw9h20.wl%appa@perusio.net> On 1 Fev 2013 16h25 CET, mdounin at mdounin.ru wrote: > Hello! Hello Maxim, >> I made some tests and definitely we cannot use in our product, it >> takes too much time and resources. >> >> Tested on an EC m1.medium instance. >> >> HOSTS,DATE,COMMAND,CPU_PERCENTAGE,CPU_SYSTEM,CPU_USER,ELAPSED_TIME,IO_PG_FAULTS,ICONTEXT_SWITCHING,VCONTEXT_SWITCHING,MAX_MEMORY >> 5001,01.Feb.2013 00:18:33,/usr/sbin/nginx -s >> reload,92%,0.60,1.84,0:02.62,0,3296,1,138528 10001,01.Feb.2013 >> 00:19:32,/usr/sbin/nginx -s >> reload,93%,1.67,5.80,0:08.00,0,11627,1,406804 20001,01.Feb.2013 >> 00:20:23,/usr/sbin/nginx -s >> reload,93%,4.17,13.68,0:19.16,0,25221,1,945164 50001,01.Feb.2013 >> 00:22:02,/usr/sbin/nginx -s >> reload,60%,13.24,36.37,1:22.46,14,68338,87121,2288668 >> >> As you can see 50k hosts take more than one minute. That would be >> acceptable if it weren't for the fact that it uses up a lot of CPU >> and memory. > > 50k ssl hosts is a lot, actually, and loading 50k certificates > in 1 minute on a cheap virtual server looks reasonable for me. > Especially if you consider total cost of 50k ssl certs. Yes, but they're the clients/users certs. Not ours. > Please also make sure you are testing recent enough nginx. In > paticular, the following commit speeds up ssl loading > about 2x here (available in nginx 1.3.11): perusio at dev:~$ /usr/sbin/nginx -V nginx version: nginx/1.3.11 built by gcc 4.7.2 (Debian 4.7.2-5) TLS SNI support enabled configure arguments: --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-debug --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --without-http_fastcgi_module --without-http_autoindex_module --without-http_split_clients_module --without-http_memcached_module --without-http_scgi_module --without-http_browser_module --without-http_split_clients_module --without-http_autoindex_module --without-http_userid_module --without-http_ssi_module --without-select_module --without-poll_module --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-i pv6 --with-file-aio > http://trac.nginx.org/nginx/changeset/5004/nginx > > The real limiting factor with many server blocks seems to be > memory used for each server{}. This probably needs some > optimization. Looking at htop, the config parsing is taking a lot of time. I know that because I also do a nginx -t before. It's just that I ommited that from the mail. Here they are: HOSTS,DATE,COMMAND,CPU_PERCENTAGE,CPU_SYSTEM,CPU_USER,ELAPSED_TIME,IO_PG_FAULTS,ICONTEXT_SWITCHING,VCONTEXT_SWITCHING,MAX_MEMORY 5001,01.Feb.2013 00:18:31,/usr/sbin/nginx_ensite 03805-08805.test-ssl.local.conf,93%,0.59,1.85,0:02.61,0,3450,17,138532 10001,01.Feb.2013 00:19:24,/usr/sbin/nginx_ensite 08806-18806.test-ssl.local.conf,93%,1.81,5.63,0:07.95,0,10684,16,406804 20001,01.Feb.2013 00:20:04,/usr/sbin/nginx_ensite 18807-38807.test-ssl.local.conf,93%,4.02,13.92,0:19.17,0,27021,17,945164 50001,01.Feb.2013 00:21:13,/usr/sbin/nginx_ensite 38808-88808.test-ssl.local.conf,93%,10.05,35.70,0:49.07,0,67976,17,2288672 nginx_ensite is a small shell script that creates a symlink and does a nginx -t. > I don't think that parsing of the config is a culprit. More > likely it's SSL certificate reading/checking/various random > initialization/generation. (And may be server names hash > generation if there are many collisions on server names.) It's not my experience. In fact, several times I mangled up the cert names and he generated the not found cert error only quite late in the process. > Some profiling would be helpful. I did a ltrace and, hands down, string operations are the main thing. For a single server block. awk 'BEGIN {s=0} /strcmp/ {s+=$1} END {print s}' single_ltrace_function_stats_libs.csv -> 4417 awk 'BEGIN {s=0} /memcpy/ {s+=$1} END {print s}' single_ltrace_function_stats_libs.csv -> 245 awk 'BEGIN {s=0} /SSL/ {s+=$1} END {print s}' single_ltrace_function_stats_libs.csv -> 49 So there are 49 ops for SSL functions against 4417 string comparisons. Is my reasoning flawed? --- appa From mdounin at mdounin.ru Fri Feb 1 16:36:39 2013 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 1 Feb 2013 20:36:39 +0400 Subject: Transforming SSL server cert and private key in variables. In-Reply-To: <87txpw9h20.wl%appa@perusio.net> References: <87mww14ix3.wl%appa@perusio.net> <20130122112104.GB9787@mdounin.ru> <87libl4b1c.wl%appa@perusio.net> <20130122133440.GH9787@mdounin.ru> <87vcac9m4x.wl%appa@perusio.net> <20130201152519.GD40753@mdounin.ru> <87txpw9h20.wl%appa@perusio.net> Message-ID: <20130201163639.GE40753@mdounin.ru> Hello! On Fri, Feb 01, 2013 at 04:42:31PM +0100, Ant?nio P. P. Almeida wrote: [...] > Looking at htop, the config parsing is taking a lot of time. I know > that because I also do a nginx -t before. It's just that I ommited > that from the mail. Here they are: > > HOSTS,DATE,COMMAND,CPU_PERCENTAGE,CPU_SYSTEM,CPU_USER,ELAPSED_TIME,IO_PG_FAULTS,ICONTEXT_SWITCHING,VCONTEXT_SWITCHING,MAX_MEMORY > 5001,01.Feb.2013 00:18:31,/usr/sbin/nginx_ensite 03805-08805.test-ssl.local.conf,93%,0.59,1.85,0:02.61,0,3450,17,138532 > 10001,01.Feb.2013 00:19:24,/usr/sbin/nginx_ensite 08806-18806.test-ssl.local.conf,93%,1.81,5.63,0:07.95,0,10684,16,406804 > 20001,01.Feb.2013 00:20:04,/usr/sbin/nginx_ensite 18807-38807.test-ssl.local.conf,93%,4.02,13.92,0:19.17,0,27021,17,945164 > 50001,01.Feb.2013 00:21:13,/usr/sbin/nginx_ensite 38808-88808.test-ssl.local.conf,93%,10.05,35.70,0:49.07,0,67976,17,2288672 > > nginx_ensite is a small shell script that creates a symlink and does a > nginx -t. The "nginx -t" does various ssl initializations as well, much like normal configuration (re)load. Parsing the configuration by itself isn't costly, it's various ssl function calls which are done while parsing are costly. You may try it yourself by commenting ssl_ceritificate/ssl_ceritifcate_key directives in your config, and looking at load/test times. > > I don't think that parsing of the config is a culprit. More > > likely it's SSL certificate reading/checking/various random > > initialization/generation. (And may be server names hash > > generation if there are many collisions on server names.) > > It's not my experience. In fact, several times I mangled up the cert > names and he generated the not found cert error only quite late in the process. > > > Some profiling would be helpful. > > I did a ltrace and, hands down, string operations are the main > thing. For a single server block. > > awk 'BEGIN {s=0} /strcmp/ {s+=$1} END {print s}' single_ltrace_function_stats_libs.csv > -> 4417 > > awk 'BEGIN {s=0} /memcpy/ {s+=$1} END {print s}' single_ltrace_function_stats_libs.csv > -> 245 > > awk 'BEGIN {s=0} /SSL/ {s+=$1} END {print s}' single_ltrace_function_stats_libs.csv > -> 49 > > So there are 49 ops for SSL functions against 4417 string comparisons. > > Is my reasoning flawed? No, as long as you are don't care about time. But if you do - you probably want to compare time spent in the functions, not number of calls. Additionally, while I'm not familiar with ltrace, I suspect it will log various libc calls from openssl as well as ones done directly from nginx, thus making the above stats completely useless. -- Maxim Dounin http://nginx.com/support.html From lekensteyn at gmail.com Sat Feb 2 21:06:51 2013 From: lekensteyn at gmail.com (Peter Wu) Date: Sat, 02 Feb 2013 22:06:51 +0100 Subject: [RFC] [PATCH] Autoindex: support sorting using URL parameters In-Reply-To: <201301302254.29505.vbart@nginx.com> References: <2685449.KCDleNYGX9@al> <201301302254.29505.vbart@nginx.com> Message-ID: <2369948.TK2Q1a05iP@al> Hi Valentin, On Wednesday 30 January 2013 22:54:29 Valentin V. Bartenev wrote: > I would prefer something like "autoindex_sort" directive > > autoindex_sort criterion [ order ]; > > with variables support. > > And if user want Apache-like behavior then he will be able to configure > it like this: > > map $arg_C $criteria { > default name; > M modified; > S size; > } > > map $arg_O $ord { > default asc; > D desc; > } > > autoindex_sort $criteria $ord; Can you give me some pointers on how to implement it? I am currently planning to use http://www.nginxguts.com/2011/01/working-with-cookies/ as guide for using variables, but I have seen some other possibilities (from a quick glance): using ngx_http_get_indexed_variable (described in a document from 2008[1]). My current idea is to: 1. Add two complex value types in ngx_http_autoindex_loc_conf_t, one for criteria, the other for order. 2. In the ngx_http_autoindex_handler function, evaluate the complex value. RFC: what should happen if the values are invalid? Simply ignore invalid sort criteria and orderings, defaulting to sorting by name in ascending order? 3. Store the resulting sort criteria and order in a struct with a pointer to it in ngx_http_autoindex_entry_t. (to avoid evaluating complex values for each qsort() call). Thanks, Peter [1]: http://antoine.bonavita.free.fr/nginx_mod_dev_en.html From jason at jasondavies.com Sun Feb 3 23:59:26 2013 From: jason at jasondavies.com (Jason Davies) Date: Sun, 3 Feb 2013 23:59:26 +0000 Subject: SPDY: failure loading large gzipped files Message-ID: <20130203235926.GA22930@jasondavies.com> I'm using nginx 1.3.11-9chl1~quantal1 from Chris Lea's PPA (which I believe is using the latest SPDY patch, patch.spdy-60_1.3.11.txt). Generate a large file containing random characters, e.g. using the following Python script (~10MB): import random f = open("10m.html", "w") f.write("\n".join(map( lambda x: "".join(map( lambda x: random.choice("0123456789abcdef"), range(100) )), range(100000) ))) f.close() Ensure that gzip is on, and gzip_types contains the appropriate file type (text/html in this case). Chrome and Firefox both fail to completely load the file; they just hang indefinitely after loading what appears to be around 1MB, though it's hard to tell exactly from Chrome's Network tab. Turning off gzip fixes the issue. If there's a way to selectively disable gzip for SPDY requests, that would also be useful to know. Thanks, -- Jason Davies, http://www.jasondavies.com/ From vbart at nginx.com Mon Feb 4 13:23:21 2013 From: vbart at nginx.com (Valentin V. Bartenev) Date: Mon, 4 Feb 2013 17:23:21 +0400 Subject: SPDY: failure loading large gzipped files In-Reply-To: <20130203235926.GA22930@jasondavies.com> References: <20130203235926.GA22930@jasondavies.com> Message-ID: <201302041723.21053.vbart@nginx.com> On Monday 04 February 2013 03:59:26 Jason Davies wrote: > I'm using nginx 1.3.11-9chl1~quantal1 from Chris Lea's PPA (which I > believe is using the latest SPDY patch, patch.spdy-60_1.3.11.txt). > > Generate a large file containing random characters, e.g. using the > following Python script (~10MB): > > import random > f = open("10m.html", "w") > f.write("\n".join(map( > lambda x: "".join(map( > lambda x: random.choice("0123456789abcdef"), > range(100) > )), > range(100000) > ))) > f.close() > > Ensure that gzip is on, and gzip_types contains the appropriate file > type (text/html in this case). > > Chrome and Firefox both fail to completely load the file; they just hang > indefinitely after loading what appears to be around 1MB, though it's > hard to tell exactly from Chrome's Network tab. > Thank you for the report. I'm able to reproduce it. > Turning off gzip fixes the issue. If there's a way to selectively > disable gzip for SPDY requests, that would also be useful to know. > Unfortunately, there is no easy way to do so. wbr, Valentin V. Bartenev -- http://nginx.com/support.html http://nginx.org/en/donation.html > Thanks, From ru at nginx.com Mon Feb 4 16:44:23 2013 From: ru at nginx.com (ru at nginx.com) Date: Mon, 4 Feb 2013 16:44:23 +0000 Subject: [nginx] svn commit: r5030 - trunk/src/http/modules Message-ID: <20130204164423.F01613F9C45@mail.nginx.com> Author: ru Date: 2013-02-04 16:44:22 +0000 (Mon, 04 Feb 2013) New Revision: 5030 URL: http://trac.nginx.org/nginx/changeset/5030/nginx Log: GeoIP: removed pseudo-support of "proxy" and "netspeed" databases. Modified: trunk/src/http/modules/ngx_http_geoip_module.c Modified: trunk/src/http/modules/ngx_http_geoip_module.c =================================================================== --- trunk/src/http/modules/ngx_http_geoip_module.c 2013-02-01 14:41:50 UTC (rev 5029) +++ trunk/src/http/modules/ngx_http_geoip_module.c 2013-02-04 16:44:22 UTC (rev 5030) @@ -705,8 +705,6 @@ switch (gcf->country->databaseType) { case GEOIP_COUNTRY_EDITION: - case GEOIP_PROXY_EDITION: - case GEOIP_NETSPEED_EDITION: return NGX_CONF_OK; From mdounin at mdounin.ru Tue Feb 5 13:41:49 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Tue, 5 Feb 2013 13:41:49 +0000 Subject: [nginx] svn commit: r5031 - trunk/misc Message-ID: <20130205134150.0282D3FA0AF@mail.nginx.com> Author: mdounin Date: 2013-02-05 13:41:48 +0000 (Tue, 05 Feb 2013) New Revision: 5031 URL: http://trac.nginx.org/nginx/changeset/5031/nginx Log: Updated OpenSSL used for win32 builds. Modified: trunk/misc/GNUmakefile Modified: trunk/misc/GNUmakefile =================================================================== --- trunk/misc/GNUmakefile 2013-02-04 16:44:22 UTC (rev 5030) +++ trunk/misc/GNUmakefile 2013-02-05 13:41:48 UTC (rev 5031) @@ -6,7 +6,7 @@ REPO = $(shell svn info | sed -n 's/^Repository Root: //p') OBJS = objs.msvc8 -OPENSSL = openssl-1.0.1c +OPENSSL = openssl-1.0.1d ZLIB = zlib-1.2.7 PCRE = pcre-8.32 From mdounin at mdounin.ru Tue Feb 5 14:06:42 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Tue, 5 Feb 2013 14:06:42 +0000 Subject: [nginx] svn commit: r5032 - trunk/docs/xml/nginx Message-ID: <20130205140642.ABA2B3FA016@mail.nginx.com> Author: mdounin Date: 2013-02-05 14:06:41 +0000 (Tue, 05 Feb 2013) New Revision: 5032 URL: http://trac.nginx.org/nginx/changeset/5032/nginx Log: nginx-1.3.12-RELEASE Modified: trunk/docs/xml/nginx/changes.xml Modified: trunk/docs/xml/nginx/changes.xml =================================================================== --- trunk/docs/xml/nginx/changes.xml 2013-02-05 13:41:48 UTC (rev 5031) +++ trunk/docs/xml/nginx/changes.xml 2013-02-05 14:06:41 UTC (rev 5032) @@ -4,6 +4,106 @@ + + + + +????????? proxy_bind, fastcgi_bind, memcached_bind, scgi_bind ? uwsgi_bind +???????????? ??????????. + + +variables support in the "proxy_bind", "fastcgi_bind", "memcached_bind", +"scgi_bind", and "uwsgi_bind" directives. + + + + + +?????????? $pipe, $request_length, $time_iso8601 ? $time_local +?????? ????? ???????????? ?? ?????? ? ????????? log_format.
+??????? Kiril Kalchev. +
+ +the $pipe, $request_length, $time_iso8601, and $time_local variables +can now be used not only in the "log_format" directive. +Thanks to Kiril Kalchev. + +
+ + + +????????? IPv6 ? ?????? ngx_http_geoip_module.
+??????? Gregor Kali?nik. +
+ +IPv6 support in the ngx_http_geoip_module.
+Thanks to Gregor Kali?nik. +
+
+ + + +????????? proxy_method ???????? ???????, ???? ???? ??????? ?? ?????? http. + + +in the "proxy_method" directive. + + + + + +? ??????? ???????? ??? ????????? segmentation fault, +???? ????????????? resolver ? ????? poll. + + +a segmentation fault might occur in a worker process +if resolver was used with the poll method. + + + + + +nginx ??? ????????? ????????? ?? ????? SSL handshake ? ???????? +??? ????????????? ??????? ????????? ?????????? select, poll ? /dev/poll. + + +nginx might hog CPU during SSL handshake with a backend +if the select, poll, or /dev/poll methods were used. + + + + + +?????? "[crit] SSL_write() failed (SSL:)". + + +the "[crit] SSL_write() failed (SSL:)" error. + + + + + +? ????????? client_body_in_file_only; +?????? ????????? ? 1.3.9. + + +in the "client_body_in_file_only" directive; +the bug had appeared in 1.3.9. + + + + + +? ????????? fastcgi_keep_conn. + + +in the "fastcgi_keep_conn" directive. + + + +
+ + From mdounin at mdounin.ru Tue Feb 5 14:07:02 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Tue, 5 Feb 2013 14:07:02 +0000 Subject: [nginx] svn commit: r5033 - tags Message-ID: <20130205140702.D10FA3F9C45@mail.nginx.com> Author: mdounin Date: 2013-02-05 14:07:01 +0000 (Tue, 05 Feb 2013) New Revision: 5033 URL: http://trac.nginx.org/nginx/changeset/5033/nginx Log: release-1.3.12 tag Added: tags/release-1.3.12/ From justin at workflowproducts.com Wed Feb 6 17:07:56 2013 From: justin at workflowproducts.com (Justin Tocci) Date: Wed, 6 Feb 2013 11:07:56 -0600 Subject: Module Developer Wanted In-Reply-To: References: Message-ID: <289B7BD2-6D8B-4112-948D-27ABC9707B5D@workflowproducts.com> We have about 700 lines of Perl that we want to replace by an NGINX module. Qualified developers should call me day or evening Eastern Standard Time. Additionally, we need a C programmer who is versed in putting together installation packages. Experience in Freebsd Ports system or similar would be relevant but not necessary. There is no bid process. All work is paid on an hourly basis. If pay exceeds $600 a W-9 will be required and a 1099-MISC will be sent to you at the end of the year. We are independent contractors ourselves and we will deal fairly with those who are interested in working with us. Regards, Justin Tocci Programmer www.workflowproducts.com 7813 Harwood Road North Richland Hills, TX 76180 cell 817-988-7758 land 817-503-9545 skype justintocci From mdounin at mdounin.ru Thu Feb 7 12:09:09 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Thu, 7 Feb 2013 12:09:09 +0000 Subject: [nginx] svn commit: r5034 - in trunk/src: core http/modules/perl Message-ID: <20130207120909.EDB2F3F9F9F@mail.nginx.com> Author: mdounin Date: 2013-02-07 12:09:09 +0000 (Thu, 07 Feb 2013) New Revision: 5034 URL: http://trac.nginx.org/nginx/changeset/5034/nginx Log: Version bump. Modified: trunk/src/core/nginx.h trunk/src/http/modules/perl/nginx.pm Modified: trunk/src/core/nginx.h =================================================================== --- trunk/src/core/nginx.h 2013-02-05 14:07:01 UTC (rev 5033) +++ trunk/src/core/nginx.h 2013-02-07 12:09:09 UTC (rev 5034) @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1003012 -#define NGINX_VERSION "1.3.12" +#define nginx_version 1003013 +#define NGINX_VERSION "1.3.13" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" Modified: trunk/src/http/modules/perl/nginx.pm =================================================================== --- trunk/src/http/modules/perl/nginx.pm 2013-02-05 14:07:01 UTC (rev 5033) +++ trunk/src/http/modules/perl/nginx.pm 2013-02-07 12:09:09 UTC (rev 5034) @@ -50,7 +50,7 @@ HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '1.3.12'; +our $VERSION = '1.3.13'; require XSLoader; XSLoader::load('nginx', $VERSION); From mdounin at mdounin.ru Thu Feb 7 12:09:56 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Thu, 7 Feb 2013 12:09:56 +0000 Subject: [nginx] svn commit: r5035 - trunk/src/core Message-ID: <20130207120956.83EC13F9C47@mail.nginx.com> Author: mdounin Date: 2013-02-07 12:09:56 +0000 (Thu, 07 Feb 2013) New Revision: 5035 URL: http://trac.nginx.org/nginx/changeset/5035/nginx Log: Added support for {SHA} passwords (ticket #50). Note: use of {SHA} passwords is discouraged as {SHA} password scheme is vulnerable to attacks using rainbow tables. Use of {SSHA}, $apr1$ or crypt() algorithms as supported by OS is recommended instead. The {SHA} password scheme support is added to avoid the need of changing the scheme recorded in password files from {SHA} to {SSHA} because such a change hides security problem with {SHA} passwords. Patch by Louis Opter, with minor changes. Modified: trunk/src/core/ngx_crypt.c Modified: trunk/src/core/ngx_crypt.c =================================================================== --- trunk/src/core/ngx_crypt.c 2013-02-07 12:09:09 UTC (rev 5034) +++ trunk/src/core/ngx_crypt.c 2013-02-07 12:09:56 UTC (rev 5035) @@ -24,6 +24,8 @@ static ngx_int_t ngx_crypt_ssha(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted); +static ngx_int_t ngx_crypt_sha(ngx_pool_t *pool, u_char *key, u_char *salt, + u_char **encrypted); #endif @@ -43,6 +45,9 @@ #if (NGX_HAVE_SHA1) } else if (ngx_strncmp(salt, "{SSHA}", sizeof("{SSHA}") - 1) == 0) { return ngx_crypt_ssha(pool, key, salt, encrypted); + + } else if (ngx_strncmp(salt, "{SHA}", sizeof("{SHA}") - 1) == 0) { + return ngx_crypt_sha(pool, key, salt, encrypted); #endif } @@ -241,6 +246,38 @@ return NGX_OK; } + +static ngx_int_t +ngx_crypt_sha(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted) +{ + size_t len; + ngx_str_t encoded, decoded; + ngx_sha1_t sha1; + u_char digest[20]; + + /* "{SHA}" base64(SHA1(key)) */ + + decoded.len = sizeof(digest); + decoded.data = digest; + + ngx_sha1_init(&sha1); + ngx_sha1_update(&sha1, key, ngx_strlen(key)); + ngx_sha1_final(digest, &sha1); + + len = sizeof("{SHA}") - 1 + ngx_base64_encoded_length(decoded.len) + 1; + + *encrypted = ngx_pnalloc(pool, len); + if (*encrypted == NULL) { + return NGX_ERROR; + } + + encoded.data = ngx_cpymem(*encrypted, "{SHA}", sizeof("{SHA}") - 1); + ngx_encode_base64(&encoded, &decoded); + encoded.data[encoded.len] = '\0'; + + return NGX_OK; +} + #endif /* NGX_HAVE_SHA1 */ #endif /* NGX_CRYPT */ From manlio.perillo at gmail.com Thu Feb 7 20:11:40 2013 From: manlio.perillo at gmail.com (Manlio Perillo) Date: Thu, 07 Feb 2013 21:11:40 +0100 Subject: Module Developer Wanted In-Reply-To: <289B7BD2-6D8B-4112-948D-27ABC9707B5D@workflowproducts.com> References: <289B7BD2-6D8B-4112-948D-27ABC9707B5D@workflowproducts.com> Message-ID: <51140A7C.1020606@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Il 06/02/2013 18:07, Justin Tocci ha scritto: > We have about 700 lines of Perl that we want to replace by an NGINX module. > Is it really necessary to write a C module? You also have an option to use Lua or Python. > [...] Regards Manlio -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAlEUCnwACgkQscQJ24LbaUQ31wCeIGhDQVwepCsVlycHWFkASDBH D8kAnRga/MKl+B4o+BBLZTkIfiTfdqPj =1HSX -----END PGP SIGNATURE----- From ibobrik at gmail.com Fri Feb 8 09:56:59 2013 From: ibobrik at gmail.com (ivan babrou) Date: Fri, 8 Feb 2013 13:56:59 +0400 Subject: try_files wildcards Message-ID: Hello! I have use-case where i need to check file presence in different directories. For example, I have static file test.css with versions in different revisions: /v1/static/test.css /v1/static/test_v001.css (same as test.css in this dir) /v2/static/test.css /v2/static/test_v002.css (same as test.css in this dir) In this case I want to make all files accessible by urls: /static/test.css /static/test_v001.css (test.css version 1) /static/test_v002.css (test.css version 2) /static/test_v000.css (test.css in the last version) Obvious solution that I see: location / { root /var/www/ try_files /*/$uri /v2/$uri =404; } This way I specify latest version as v2, but here comes the problem: try_files does not support wildcards. It is adequate to have support for wildcards (*) in try_files? Will you accept patch? Are there better and easier ways to solve my problem? -- Regards, Ian Babrou http://bobrik.name http://twitter.com/ibobrik skype:i.babrou -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Fri Feb 8 10:13:43 2013 From: mdounin at mdounin.ru (Maxim Dounin) Date: Fri, 8 Feb 2013 14:13:43 +0400 Subject: try_files wildcards In-Reply-To: References: Message-ID: <20130208101342.GM66348@mdounin.ru> Hello! On Fri, Feb 08, 2013 at 01:56:59PM +0400, ivan babrou wrote: > Hello! > > I have use-case where i need to check file presence in different > directories. > > For example, I have static file test.css with versions in different > revisions: > > /v1/static/test.css > /v1/static/test_v001.css (same as test.css in this dir) > /v2/static/test.css > /v2/static/test_v002.css (same as test.css in this dir) > > In this case I want to make all files accessible by urls: > > /static/test.css > /static/test_v001.css (test.css version 1) > /static/test_v002.css (test.css version 2) > /static/test_v000.css (test.css in the last version) Which test.css you expect to be returned for /static/test.css? > Obvious solution that I see: > > location / { > root /var/www/ > try_files /*/$uri /v2/$uri =404; > } > > This way I specify latest version as v2, but here comes the problem: > try_files does not support wildcards. > > It is adequate to have support for wildcards (*) in try_files? Will you > accept patch? I don't think so. > Are there better and easier ways to solve my problem? An obvious solution would be to keep links on a file system. -- Maxim Dounin http://nginx.com/support.html From crnewe at yahoo.com Fri Feb 8 22:53:23 2013 From: crnewe at yahoo.com (Crne We) Date: Fri, 8 Feb 2013 14:53:23 -0800 (PST) Subject: adding more features Message-ID: <1360364003.15636.YahooMailNeo@web160505.mail.bf1.yahoo.com> Can I contribute the following features to nginx: ? ?support http CONNECT method to allow things like SSL tunnel ? ?some form of 2nd factor authentication -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexander_koch_log at lavabit.com Sat Feb 9 15:41:54 2013 From: alexander_koch_log at lavabit.com (alexander_koch_log) Date: Sat, 09 Feb 2013 16:41:54 +0100 Subject: Nginx Module (I/O block) Message-ID: <51166E42.40904@lavabit.com> Hi, It is not clear to me how to avoid blocking the nginx reactor loop when creating an nginx module which should perform some long I/O operations and return the response to the client. Or is this handled internally by Nginx? Any hints are appreciated. Thanks, Alex From mdounin at mdounin.ru Sat Feb 9 21:07:07 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Sat, 9 Feb 2013 21:07:07 +0000 Subject: [nginx] svn commit: r5036 - in branches/stable-1.2/src: core http/modules/perl Message-ID: <20130209210708.470F23F9F47@mail.nginx.com> Author: mdounin Date: 2013-02-09 21:07:06 +0000 (Sat, 09 Feb 2013) New Revision: 5036 URL: http://trac.nginx.org/nginx/changeset/5036/nginx Log: Version bump. Modified: branches/stable-1.2/src/core/nginx.h branches/stable-1.2/src/http/modules/perl/nginx.pm Modified: branches/stable-1.2/src/core/nginx.h =================================================================== --- branches/stable-1.2/src/core/nginx.h 2013-02-07 12:09:56 UTC (rev 5035) +++ branches/stable-1.2/src/core/nginx.h 2013-02-09 21:07:06 UTC (rev 5036) @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1002006 -#define NGINX_VERSION "1.2.6" +#define nginx_version 1002007 +#define NGINX_VERSION "1.2.7" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" Modified: branches/stable-1.2/src/http/modules/perl/nginx.pm =================================================================== --- branches/stable-1.2/src/http/modules/perl/nginx.pm 2013-02-07 12:09:56 UTC (rev 5035) +++ branches/stable-1.2/src/http/modules/perl/nginx.pm 2013-02-09 21:07:06 UTC (rev 5036) @@ -50,7 +50,7 @@ HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '1.2.6'; +our $VERSION = '1.2.7'; require XSLoader; XSLoader::load('nginx', $VERSION); From mdounin at mdounin.ru Sat Feb 9 21:27:37 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Sat, 9 Feb 2013 21:27:37 +0000 Subject: [nginx] svn commit: r5037 - in branches/stable-1.2: . src/os/unix Message-ID: <20130209212737.DB7953F9F3E@mail.nginx.com> Author: mdounin Date: 2013-02-09 21:27:37 +0000 (Sat, 09 Feb 2013) New Revision: 5037 URL: http://trac.nginx.org/nginx/changeset/5037/nginx Log: Merge of r4944: removed GLOB_NOSORT glob option. This will result in alphabetical sorting of included files if the "include" directive with wildcards is used. Note that the behaviour is now different from that on Windows, where alphabetical sorting is not guaranteed for FindFirsFile()/FindNextFile() (used to be alphabetical on NTFS, but not on FAT). Approved by Igor Sysoev, prodded by many. Modified: branches/stable-1.2/ branches/stable-1.2/src/os/unix/ngx_files.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-09 21:07:06 UTC (rev 5036) +++ branches/stable-1.2 2013-02-09 21:27:37 UTC (rev 5037) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944 \ No newline at end of property Modified: branches/stable-1.2/src/os/unix/ngx_files.c =================================================================== --- branches/stable-1.2/src/os/unix/ngx_files.c 2013-02-09 21:07:06 UTC (rev 5036) +++ branches/stable-1.2/src/os/unix/ngx_files.c 2013-02-09 21:27:37 UTC (rev 5037) @@ -363,7 +363,7 @@ { int n; - n = glob((char *) gl->pattern, GLOB_NOSORT, NULL, &gl->pglob); + n = glob((char *) gl->pattern, 0, NULL, &gl->pglob); if (n == 0) { return NGX_OK; From mdounin at mdounin.ru Sat Feb 9 23:25:04 2013 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sun, 10 Feb 2013 03:25:04 +0400 Subject: Nginx Module (I/O block) In-Reply-To: <51166E42.40904@lavabit.com> References: <51166E42.40904@lavabit.com> Message-ID: <20130209232504.GU66348@mdounin.ru> Hello! On Sat, Feb 09, 2013 at 04:41:54PM +0100, alexander_koch_log wrote: > It is not clear to me how to avoid blocking the nginx reactor loop > when creating an nginx module which should perform some long I/O > operations and return the response to the client. Or is this > handled internally by Nginx? Correct aproach is to avoid blocking for a long time, and use non-blocking I/O and event-based notification instead. What exactly should (and can) be done depends on the exact case. E.g. to work with sockets there are lots of various functions available to simplify things. Working with files without blocking is harder and not always possible, but a common case is handled by nginx - to send some large file you just have to open the file and ask nginx to send an in-file buffer. -- Maxim Dounin http://nginx.com/support.html From mdounin at mdounin.ru Sun Feb 10 02:56:04 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Sun, 10 Feb 2013 02:56:04 +0000 Subject: [nginx] svn commit: r5038 - in branches/stable-1.2: . src/core Message-ID: <20130210025604.C28D03F9F46@mail.nginx.com> Author: mdounin Date: 2013-02-10 02:56:03 +0000 (Sun, 10 Feb 2013) New Revision: 5038 URL: http://trac.nginx.org/nginx/changeset/5038/nginx Log: Merge of r4945, r4984: ngx_inet.[ch] minor fixes. *) Fixed the NGX_SOCKADDR_STRLEN macro definition. The ngx_sock_ntop() function, when told to print both address and port, prints IPv6 address in square brackets, followed by colon and port. *) Properly initialize "struct in6_addr" with zeroes. Modified: branches/stable-1.2/ branches/stable-1.2/src/core/ngx_inet.c branches/stable-1.2/src/core/ngx_inet.h Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-09 21:27:37 UTC (rev 5037) +++ branches/stable-1.2 2013-02-10 02:56:03 UTC (rev 5038) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4945,4984 \ No newline at end of property Modified: branches/stable-1.2/src/core/ngx_inet.c =================================================================== --- branches/stable-1.2/src/core/ngx_inet.c 2013-02-09 21:27:37 UTC (rev 5037) +++ branches/stable-1.2/src/core/ngx_inet.c 2013-02-10 02:56:03 UTC (rev 5038) @@ -465,7 +465,7 @@ * prevent MSVC8 warning: * potentially uninitialized local variable 'inaddr6' used */ - ngx_memzero(inaddr6.s6_addr, sizeof(struct in6_addr)); + ngx_memzero(&inaddr6, sizeof(struct in6_addr)); #endif inaddr = ngx_inet_addr(text, len); Modified: branches/stable-1.2/src/core/ngx_inet.h =================================================================== --- branches/stable-1.2/src/core/ngx_inet.h 2013-02-09 21:27:37 UTC (rev 5037) +++ branches/stable-1.2/src/core/ngx_inet.h 2013-02-10 02:56:03 UTC (rev 5038) @@ -30,7 +30,7 @@ #if (NGX_HAVE_UNIX_DOMAIN) #define NGX_SOCKADDR_STRLEN (sizeof("unix:") - 1 + NGX_UNIX_ADDRSTRLEN) #else -#define NGX_SOCKADDR_STRLEN (NGX_INET6_ADDRSTRLEN + sizeof(":65535") - 1) +#define NGX_SOCKADDR_STRLEN (NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1) #endif #if (NGX_HAVE_UNIX_DOMAIN) From mdounin at mdounin.ru Sun Feb 10 02:58:04 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Sun, 10 Feb 2013 02:58:04 +0000 Subject: [nginx] svn commit: r5039 - in branches/stable-1.2: . auto/lib/perl src/http/modules/perl Message-ID: <20130210025804.2E6303F9F46@mail.nginx.com> Author: mdounin Date: 2013-02-10 02:58:03 +0000 (Sun, 10 Feb 2013) New Revision: 5039 URL: http://trac.nginx.org/nginx/changeset/5039/nginx Log: Merge of r4946, r4978: perl. *) Fixed build with embedded perl in certain setups (ticket #48). *) Brought the link to ngx_http_perl_module documentation up to date. Modified: branches/stable-1.2/ branches/stable-1.2/auto/lib/perl/make branches/stable-1.2/src/http/modules/perl/Makefile.PL branches/stable-1.2/src/http/modules/perl/nginx.pm Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-10 02:56:03 UTC (rev 5038) +++ branches/stable-1.2 2013-02-10 02:58:03 UTC (rev 5039) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4945,4984 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4946,4978,4984 \ No newline at end of property Modified: branches/stable-1.2/auto/lib/perl/make =================================================================== --- branches/stable-1.2/auto/lib/perl/make 2013-02-10 02:56:03 UTC (rev 5038) +++ branches/stable-1.2/auto/lib/perl/make 2013-02-10 02:58:03 UTC (rev 5039) @@ -26,9 +26,7 @@ cd $NGX_OBJS/src/http/modules/perl \ && NGX_PM_CFLAGS="\$(NGX_PM_CFLAGS) -g $NGX_CC_OPT" \ - NGX_PCRE=$PCRE \ - NGX_OBJS=$NGX_OBJS \ - NGX_OPENSSL=$OPENSSL \ + NGX_INCS="$CORE_INCS $NGX_OBJS $HTTP_INCS" \ $NGX_PERL Makefile.PL \ LIB=$NGX_PERL_MODULES \ INSTALLSITEMAN3DIR=$NGX_PERL_MODULES_MAN Modified: branches/stable-1.2/src/http/modules/perl/Makefile.PL =================================================================== --- branches/stable-1.2/src/http/modules/perl/Makefile.PL 2013-02-10 02:56:03 UTC (rev 5038) +++ branches/stable-1.2/src/http/modules/perl/Makefile.PL 2013-02-10 02:58:03 UTC (rev 5039) @@ -16,20 +16,9 @@ CCFLAGS => "$ENV{NGX_PM_CFLAGS}", OPTIMIZE => '-O', - INC => "-I ../../../../../src/core " . - "-I ../../../../../src/event " . - "-I ../../../../../src/os/unix " . - "-I ../../../../../src/http " . - "-I ../../../../../src/http/modules " . - "-I ../../../../../src/http/modules/perl " . - "-I ../../../../../$ENV{NGX_OBJS} " . - ($ENV{NGX_PCRE} =~ /^(YES|NO)/ ? "" : - ($ENV{NGX_PCRE} =~ m#^/# ? "-I $ENV{NGX_PCRE} " : - "-I ../../../../../$ENV{NGX_PCRE} ")) . - ($ENV{NGX_OPENSSL} =~ /^(YES|NO)/ ? "" : - ($ENV{NGX_OPENSSL} =~ m#^/# ? - "-I $ENV{NGX_OPENSSL}/.openssl/include " : - "-I ../../../../../$ENV{NGX_OPENSSL}/.openssl/include ")), + INC => join(" ", map { + m#^/# ? "-I $_" : "-I ../../../../../$_" + } (split /\s+/, $ENV{NGX_INCS})), depend => { 'nginx.c' => Modified: branches/stable-1.2/src/http/modules/perl/nginx.pm =================================================================== --- branches/stable-1.2/src/http/modules/perl/nginx.pm 2013-02-10 02:56:03 UTC (rev 5038) +++ branches/stable-1.2/src/http/modules/perl/nginx.pm 2013-02-10 02:58:03 UTC (rev 5039) @@ -123,7 +123,7 @@ =head1 SEE ALSO -http://sysoev.ru/nginx/docs/http/ngx_http_perl_module.html +http://nginx.org/en/docs/http/ngx_http_perl_module.html =head1 AUTHOR From mdounin at mdounin.ru Sun Feb 10 03:00:56 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Sun, 10 Feb 2013 03:00:56 +0000 Subject: [nginx] svn commit: r5040 - in branches/stable-1.2: . src/http/modules Message-ID: <20130210030057.88F9E3FA036@mail.nginx.com> Author: mdounin Date: 2013-02-10 03:00:55 +0000 (Sun, 10 Feb 2013) New Revision: 5040 URL: http://trac.nginx.org/nginx/changeset/5040/nginx Log: Merge of r4947: xslt: prevented infinite loop. If XSLT transformation failed and error 500 was handled in the same location, an infinite loop occured that exhausted the stack. Modified: branches/stable-1.2/ branches/stable-1.2/src/http/modules/ngx_http_xslt_filter_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-10 02:58:03 UTC (rev 5039) +++ branches/stable-1.2 2013-02-10 03:00:55 UTC (rev 5040) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4946,4978,4984 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4947,4978,4984 \ No newline at end of property Modified: branches/stable-1.2/src/http/modules/ngx_http_xslt_filter_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_xslt_filter_module.c 2013-02-10 02:58:03 UTC (rev 5039) +++ branches/stable-1.2/src/http/modules/ngx_http_xslt_filter_module.c 2013-02-10 03:00:55 UTC (rev 5040) @@ -307,7 +307,7 @@ ctx->done = 1; if (b == NULL) { - return ngx_http_filter_finalize_request(r, NULL, + return ngx_http_filter_finalize_request(r, &ngx_http_xslt_filter_module, NGX_HTTP_INTERNAL_SERVER_ERROR); } @@ -315,7 +315,7 @@ if (cln == NULL) { ngx_free(b->pos); - return ngx_http_filter_finalize_request(r, NULL, + return ngx_http_filter_finalize_request(r, &ngx_http_xslt_filter_module, NGX_HTTP_INTERNAL_SERVER_ERROR); } From mdounin at mdounin.ru Sun Feb 10 03:08:42 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Sun, 10 Feb 2013 03:08:42 +0000 Subject: [nginx] svn commit: r5041 - in branches/stable-1.2: . src/http src/http/modules Message-ID: <20130210030842.BB6B23F9FA3@mail.nginx.com> Author: mdounin Date: 2013-02-10 03:08:42 +0000 (Sun, 10 Feb 2013) New Revision: 5041 URL: http://trac.nginx.org/nginx/changeset/5041/nginx Log: Merge of r4948, r4949, r4964, r4973, r5011: variables. *) Allow the complex value to be defined as an empty string. This makes conversion from strings to complex values possible without the loss of functionality. *) The "auth_basic" directive gained support of variables. *) Fixed variable syntax checking in "set", "geo", "limit_conn_zone", and "perl_set" directives. *) Added checks that disallow adding a variable with an empty name. Added variable name syntax checks to "geo" and "map" directives. *) Variables $pipe, $request_length, $time_iso8601, and $time_local. Log module counterparts are preserved for efficiency. Based on patch by Kiril Kalchev. Modified: branches/stable-1.2/ branches/stable-1.2/src/http/modules/ngx_http_auth_basic_module.c branches/stable-1.2/src/http/modules/ngx_http_fastcgi_module.c branches/stable-1.2/src/http/modules/ngx_http_geo_module.c branches/stable-1.2/src/http/modules/ngx_http_map_module.c branches/stable-1.2/src/http/modules/ngx_http_proxy_module.c branches/stable-1.2/src/http/modules/ngx_http_scgi_module.c branches/stable-1.2/src/http/modules/ngx_http_split_clients_module.c branches/stable-1.2/src/http/modules/ngx_http_sub_filter_module.c branches/stable-1.2/src/http/modules/ngx_http_uwsgi_module.c branches/stable-1.2/src/http/ngx_http_core_module.c branches/stable-1.2/src/http/ngx_http_script.c branches/stable-1.2/src/http/ngx_http_variables.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-10 03:00:55 UTC (rev 5040) +++ branches/stable-1.2 2013-02-10 03:08:42 UTC (rev 5041) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4947,4978,4984 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4964,4973,4978,4984,5011 \ No newline at end of property Modified: branches/stable-1.2/src/http/modules/ngx_http_auth_basic_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_auth_basic_module.c 2013-02-10 03:00:55 UTC (rev 5040) +++ branches/stable-1.2/src/http/modules/ngx_http_auth_basic_module.c 2013-02-10 03:08:42 UTC (rev 5041) @@ -20,8 +20,8 @@ typedef struct { - ngx_str_t realm; - ngx_http_complex_value_t user_file; + ngx_http_complex_value_t *realm; + ngx_http_complex_value_t user_file; } ngx_http_auth_basic_loc_conf_t; @@ -35,22 +35,19 @@ static char *ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); static ngx_int_t ngx_http_auth_basic_init(ngx_conf_t *cf); -static char *ngx_http_auth_basic(ngx_conf_t *cf, void *post, void *data); static char *ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static ngx_conf_post_handler_pt ngx_http_auth_basic_p = ngx_http_auth_basic; - static ngx_command_t ngx_http_auth_basic_commands[] = { { ngx_string("auth_basic"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF |NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_http_set_complex_value_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_auth_basic_loc_conf_t, realm), - &ngx_http_auth_basic_p }, + NULL }, { ngx_string("auth_basic_user_file"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF @@ -103,7 +100,7 @@ ngx_fd_t fd; ngx_int_t rc; ngx_err_t err; - ngx_str_t pwd, user_file; + ngx_str_t pwd, realm, user_file; ngx_uint_t i, level, login, left, passwd; ngx_file_t file; ngx_http_auth_basic_ctx_t *ctx; @@ -117,15 +114,23 @@ alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_basic_module); - if (alcf->realm.len == 0 || alcf->user_file.value.len == 0) { + if (alcf->realm == NULL || alcf->user_file.value.data == NULL) { return NGX_DECLINED; } + if (ngx_http_complex_value(r, alcf->realm, &realm) != NGX_OK) { + return NGX_ERROR; + } + + if (realm.len == 3 && ngx_strncmp(realm.data, "off", 3) == 0) { + return NGX_DECLINED; + } + ctx = ngx_http_get_module_ctx(r, ngx_http_auth_basic_module); if (ctx) { return ngx_http_auth_basic_crypt_handler(r, ctx, &ctx->passwd, - &alcf->realm); + &realm); } rc = ngx_http_auth_basic_user(r); @@ -135,7 +140,7 @@ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no user/password was provided for basic authentication"); - return ngx_http_auth_basic_set_realm(r, &alcf->realm); + return ngx_http_auth_basic_set_realm(r, &realm); } if (rc == NGX_ERROR) { @@ -233,7 +238,7 @@ pwd.data = &buf[passwd]; return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, - &alcf->realm); + &realm); } break; @@ -271,14 +276,14 @@ ngx_cpystrn(pwd.data, &buf[passwd], pwd.len + 1); - return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, &alcf->realm); + return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, &realm); } ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "user \"%V\" was not found in \"%V\"", &r->headers_in.user, &user_file); - return ngx_http_auth_basic_set_realm(r, &alcf->realm); + return ngx_http_auth_basic_set_realm(r, &realm); } @@ -344,14 +349,29 @@ static ngx_int_t ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm) { + size_t len; + u_char *basic, *p; + r->headers_out.www_authenticate = ngx_list_push(&r->headers_out.headers); if (r->headers_out.www_authenticate == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } + len = sizeof("Basic realm=\"\"") - 1 + realm->len; + + basic = ngx_pnalloc(r->pool, len); + if (basic == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + p = ngx_cpymem(basic, "Basic realm=\"", sizeof("Basic realm=\"") - 1); + p = ngx_cpymem(p, realm->data, realm->len); + *p = '"'; + r->headers_out.www_authenticate->hash = 1; ngx_str_set(&r->headers_out.www_authenticate->key, "WWW-Authenticate"); - r->headers_out.www_authenticate->value = *realm; + r->headers_out.www_authenticate->value.data = basic; + r->headers_out.www_authenticate->value.len = len; return NGX_HTTP_UNAUTHORIZED; } @@ -386,11 +406,11 @@ ngx_http_auth_basic_loc_conf_t *prev = parent; ngx_http_auth_basic_loc_conf_t *conf = child; - if (conf->realm.data == NULL) { + if (conf->realm == NULL) { conf->realm = prev->realm; } - if (conf->user_file.value.len == 0) { + if (conf->user_file.value.data == NULL) { conf->user_file = prev->user_file; } @@ -418,37 +438,6 @@ static char * -ngx_http_auth_basic(ngx_conf_t *cf, void *post, void *data) -{ - ngx_str_t *realm = data; - - size_t len; - u_char *basic, *p; - - if (ngx_strcmp(realm->data, "off") == 0) { - ngx_str_set(realm, ""); - return NGX_CONF_OK; - } - - len = sizeof("Basic realm=\"") - 1 + realm->len + 1; - - basic = ngx_pnalloc(cf->pool, len); - if (basic == NULL) { - return NGX_CONF_ERROR; - } - - p = ngx_cpymem(basic, "Basic realm=\"", sizeof("Basic realm=\"") - 1); - p = ngx_cpymem(p, realm->data, realm->len); - *p = '"'; - - realm->len = len; - realm->data = basic; - - return NGX_CONF_OK; -} - - -static char * ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_auth_basic_loc_conf_t *alcf = conf; @@ -456,7 +445,7 @@ ngx_str_t *value; ngx_http_compile_complex_value_t ccv; - if (alcf->user_file.value.len) { + if (alcf->user_file.value.data) { return "is duplicate"; } Modified: branches/stable-1.2/src/http/modules/ngx_http_fastcgi_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_fastcgi_module.c 2013-02-10 03:00:55 UTC (rev 5040) +++ branches/stable-1.2/src/http/modules/ngx_http_fastcgi_module.c 2013-02-10 03:08:42 UTC (rev 5041) @@ -3014,7 +3014,7 @@ value = cf->args->elts; - if (flcf->cache_key.value.len) { + if (flcf->cache_key.value.data) { return "is duplicate"; } Modified: branches/stable-1.2/src/http/modules/ngx_http_geo_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_geo_module.c 2013-02-10 03:00:55 UTC (rev 5040) +++ branches/stable-1.2/src/http/modules/ngx_http_geo_module.c 2013-02-10 03:08:42 UTC (rev 5041) @@ -322,6 +322,13 @@ } name = value[1]; + + if (name.data[0] != '$') { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid variable name \"%V\"", &name); + return NGX_CONF_ERROR; + } + name.len--; name.data++; @@ -333,6 +340,13 @@ } name = value[2]; + + if (name.data[0] != '$') { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid variable name \"%V\"", &name); + return NGX_CONF_ERROR; + } + name.len--; name.data++; Modified: branches/stable-1.2/src/http/modules/ngx_http_map_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_map_module.c 2013-02-10 03:00:55 UTC (rev 5040) +++ branches/stable-1.2/src/http/modules/ngx_http_map_module.c 2013-02-10 03:08:42 UTC (rev 5041) @@ -209,6 +209,13 @@ } name = value[2]; + + if (name.data[0] != '$') { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid variable name \"%V\"", &name); + return NGX_CONF_ERROR; + } + name.len--; name.data++; Modified: branches/stable-1.2/src/http/modules/ngx_http_proxy_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_proxy_module.c 2013-02-10 03:00:55 UTC (rev 5040) +++ branches/stable-1.2/src/http/modules/ngx_http_proxy_module.c 2013-02-10 03:08:42 UTC (rev 5041) @@ -836,7 +836,7 @@ return NGX_ERROR; } - if (plcf->cache_key.value.len) { + if (plcf->cache_key.value.data) { if (ngx_http_complex_value(r, &plcf->cache_key, key) != NGX_OK) { return NGX_ERROR; @@ -3918,7 +3918,7 @@ value = cf->args->elts; - if (plcf->cache_key.value.len) { + if (plcf->cache_key.value.data) { return "is duplicate"; } Modified: branches/stable-1.2/src/http/modules/ngx_http_scgi_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_scgi_module.c 2013-02-10 03:00:55 UTC (rev 5040) +++ branches/stable-1.2/src/http/modules/ngx_http_scgi_module.c 2013-02-10 03:08:42 UTC (rev 5041) @@ -1765,7 +1765,7 @@ value = cf->args->elts; - if (scf->cache_key.value.len) { + if (scf->cache_key.value.data) { return "is duplicate"; } Modified: branches/stable-1.2/src/http/modules/ngx_http_split_clients_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_split_clients_module.c 2013-02-10 03:00:55 UTC (rev 5040) +++ branches/stable-1.2/src/http/modules/ngx_http_split_clients_module.c 2013-02-10 03:08:42 UTC (rev 5041) @@ -139,7 +139,7 @@ name = value[2]; - if (name.len < 2 || name.data[0] != '$') { + if (name.data[0] != '$') { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid variable name \"%V\"", &name); return NGX_CONF_ERROR; Modified: branches/stable-1.2/src/http/modules/ngx_http_sub_filter_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_sub_filter_module.c 2013-02-10 03:00:55 UTC (rev 5040) +++ branches/stable-1.2/src/http/modules/ngx_http_sub_filter_module.c 2013-02-10 03:08:42 UTC (rev 5041) @@ -627,7 +627,7 @@ ngx_str_t *value; ngx_http_compile_complex_value_t ccv; - if (slcf->match.len) { + if (slcf->match.data) { return "is duplicate"; } @@ -687,7 +687,7 @@ ngx_conf_merge_value(conf->once, prev->once, 1); ngx_conf_merge_str_value(conf->match, prev->match, ""); - if (conf->value.value.len == 0) { + if (conf->value.value.data == NULL) { conf->value = prev->value; } Modified: branches/stable-1.2/src/http/modules/ngx_http_uwsgi_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_uwsgi_module.c 2013-02-10 03:00:55 UTC (rev 5040) +++ branches/stable-1.2/src/http/modules/ngx_http_uwsgi_module.c 2013-02-10 03:08:42 UTC (rev 5041) @@ -1807,7 +1807,7 @@ value = cf->args->elts; - if (uwcf->cache_key.value.len) { + if (uwcf->cache_key.value.data) { return "is duplicate"; } Modified: branches/stable-1.2/src/http/ngx_http_core_module.c =================================================================== --- branches/stable-1.2/src/http/ngx_http_core_module.c 2013-02-10 03:00:55 UTC (rev 5040) +++ branches/stable-1.2/src/http/ngx_http_core_module.c 2013-02-10 03:08:42 UTC (rev 5041) @@ -4544,7 +4544,7 @@ ngx_str_null(&args); - if (cv.lengths == NULL && uri.data[0] == '/') { + if (cv.lengths == NULL && uri.len && uri.data[0] == '/') { p = (u_char *) ngx_strchr(uri.data, '?'); if (p) { Modified: branches/stable-1.2/src/http/ngx_http_script.c =================================================================== --- branches/stable-1.2/src/http/ngx_http_script.c 2013-02-10 03:00:55 UTC (rev 5040) +++ branches/stable-1.2/src/http/ngx_http_script.c 2013-02-10 03:08:42 UTC (rev 5041) @@ -114,11 +114,6 @@ v = ccv->value; - if (v->len == 0) { - ngx_conf_log_error(NGX_LOG_EMERG, ccv->cf, 0, "empty parameter"); - return NGX_ERROR; - } - nv = 0; nc = 0; @@ -133,8 +128,9 @@ } } - if (v->data[0] != '$' && (ccv->conf_prefix || ccv->root_prefix)) { - + if ((v->len == 0 || v->data[0] != '$') + && (ccv->conf_prefix || ccv->root_prefix)) + { if (ngx_conf_full_name(ccv->cf->cycle, v, ccv->conf_prefix) != NGX_OK) { return NGX_ERROR; } Modified: branches/stable-1.2/src/http/ngx_http_variables.c =================================================================== --- branches/stable-1.2/src/http/ngx_http_variables.c 2013-02-10 03:00:55 UTC (rev 5040) +++ branches/stable-1.2/src/http/ngx_http_variables.c 2013-02-10 03:08:42 UTC (rev 5041) @@ -73,12 +73,16 @@ ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_body_bytes_sent(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_pipe(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_request_completion(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_request_body(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_request_body_file(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_request_length(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_request_time(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r, @@ -112,6 +116,10 @@ ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_msec(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_time_iso8601(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_time_local(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); /* * TODO: @@ -229,6 +237,9 @@ { ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent, 0, 0, 0 }, + { ngx_string("pipe"), NULL, ngx_http_variable_pipe, + 0, 0, 0 }, + { ngx_string("request_completion"), NULL, ngx_http_variable_request_completion, 0, 0, 0 }, @@ -241,6 +252,9 @@ ngx_http_variable_request_body_file, 0, 0, 0 }, + { ngx_string("request_length"), NULL, ngx_http_variable_request_length, + 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, + { ngx_string("request_time"), NULL, ngx_http_variable_request_time, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, @@ -295,6 +309,12 @@ { ngx_string("msec"), NULL, ngx_http_variable_msec, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, + { ngx_string("time_iso8601"), NULL, ngx_http_variable_time_iso8601, + 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, + + { ngx_string("time_local"), NULL, ngx_http_variable_time_local, + 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, + #if (NGX_HAVE_TCP_INFO) { ngx_string("tcpinfo_rtt"), NULL, ngx_http_variable_tcpinfo, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, @@ -328,6 +348,12 @@ ngx_http_variable_t *v; ngx_http_core_main_conf_t *cmcf; + if (name->len == 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid variable name \"$\""); + return NULL; + } + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); key = cmcf->variables_keys->keys.elts; @@ -391,6 +417,12 @@ ngx_http_variable_t *v; ngx_http_core_main_conf_t *cmcf; + if (name->len == 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid variable name \"$\""); + return NGX_ERROR; + } + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); v = cmcf->variables.elts; @@ -1509,6 +1541,20 @@ static ngx_int_t +ngx_http_variable_pipe(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + v->data = (u_char *) (r->pipeline ? "p" : "."); + v->len = 1; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + + return NGX_OK; +} + + +static ngx_int_t ngx_http_variable_status(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { @@ -1843,6 +1889,27 @@ static ngx_int_t +ngx_http_variable_request_length(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *p; + + p = ngx_pnalloc(r->pool, NGX_OFF_T_LEN); + if (p == NULL) { + return NGX_ERROR; + } + + v->len = ngx_sprintf(p, "%O", r->request_length) - p; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = p; + + return NGX_OK; +} + + +static ngx_int_t ngx_http_variable_request_time(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { @@ -1986,6 +2053,53 @@ } +static ngx_int_t +ngx_http_variable_time_iso8601(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *p; + + p = ngx_pnalloc(r->pool, ngx_cached_http_log_iso8601.len); + if (p == NULL) { + return NGX_ERROR; + } + + ngx_memcpy(p, ngx_cached_http_log_iso8601.data, + ngx_cached_http_log_iso8601.len); + + v->len = ngx_cached_http_log_iso8601.len; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = p; + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_variable_time_local(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *p; + + p = ngx_pnalloc(r->pool, ngx_cached_http_log_time.len); + if (p == NULL) { + return NGX_ERROR; + } + + ngx_memcpy(p, ngx_cached_http_log_time.data, ngx_cached_http_log_time.len); + + v->len = ngx_cached_http_log_time.len; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = p; + + return NGX_OK; +} + + void * ngx_http_map_find(ngx_http_request_t *r, ngx_http_map_t *map, ngx_str_t *match) { From mdounin at mdounin.ru Sun Feb 10 03:18:08 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Sun, 10 Feb 2013 03:18:08 +0000 Subject: [nginx] svn commit: r5042 - in branches/stable-1.2: . auto/lib/pcre Message-ID: <20130210031808.7EC6E3F9F3E@mail.nginx.com> Author: mdounin Date: 2013-02-10 03:18:08 +0000 (Sun, 10 Feb 2013) New Revision: 5042 URL: http://trac.nginx.org/nginx/changeset/5042/nginx Log: Merge of r4961: configure: better check for PCRE JIT. On Mac OS X system toolchain by default prefers include files from /usr/local/include, but libraries from /usr/lib. This might result in various problems, in particular the one outlined below. If the PCRE library is installed into /usr/local/, this results in pcre.h being used from /usr/local/include (with PCRE_CONFIG_JIT defined), but libpcre from /usr/lib (as shipped with the OS, without pcre_free_study() symbol). As a result build fails as we use pcre_free_study() function if we try to compile with PCRE JIT support. Obvious workaround to the root cause is to ask compiler to prefer library from /usr/local/lib via ./configure --with-ld-opt="-L/usr/local/lib". On the other hand, in any case it would be good to check if the function we are going to use is available, hence the change. See thread here for details: http://mailman.nginx.org/pipermail/nginx-devel/2012-December/003074.html Prodded by Piotr Sikora. Modified: branches/stable-1.2/ branches/stable-1.2/auto/lib/pcre/conf Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-10 03:08:42 UTC (rev 5041) +++ branches/stable-1.2 2013-02-10 03:18:08 UTC (rev 5042) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4964,4973,4978,4984,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961,4964,4973,4978,4984,5011 \ No newline at end of property Modified: branches/stable-1.2/auto/lib/pcre/conf =================================================================== --- branches/stable-1.2/auto/lib/pcre/conf 2013-02-10 03:08:42 UTC (rev 5041) +++ branches/stable-1.2/auto/lib/pcre/conf 2013-02-10 03:18:08 UTC (rev 5042) @@ -172,6 +172,7 @@ ngx_feature="PCRE JIT support" ngx_feature_name="NGX_HAVE_PCRE_JIT" ngx_feature_test="int jit = 0; + pcre_free_study(NULL); pcre_config(PCRE_CONFIG_JIT, &jit); if (jit != 1) return 1;" . auto/feature From mdounin at mdounin.ru Sun Feb 10 03:20:01 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Sun, 10 Feb 2013 03:20:01 +0000 Subject: [nginx] svn commit: r5043 - in branches/stable-1.2: . src/http Message-ID: <20130210032001.54E5F3F9EB7@mail.nginx.com> Author: mdounin Date: 2013-02-10 03:20:00 +0000 (Sun, 10 Feb 2013) New Revision: 5043 URL: http://trac.nginx.org/nginx/changeset/5043/nginx Log: Merge of r4962: limit_rate fix. Limit rate: fixed integer overflow in limit calculation (ticket #256). Patch by Alexey Antropov. Modified: branches/stable-1.2/ branches/stable-1.2/src/http/ngx_http_write_filter_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-10 03:18:08 UTC (rev 5042) +++ branches/stable-1.2 2013-02-10 03:20:00 UTC (rev 5043) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961,4964,4973,4978,4984,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4962,4964,4973,4978,4984,5011 \ No newline at end of property Modified: branches/stable-1.2/src/http/ngx_http_write_filter_module.c =================================================================== --- branches/stable-1.2/src/http/ngx_http_write_filter_module.c 2013-02-10 03:18:08 UTC (rev 5042) +++ branches/stable-1.2/src/http/ngx_http_write_filter_module.c 2013-02-10 03:20:00 UTC (rev 5043) @@ -207,7 +207,7 @@ } if (r->limit_rate) { - limit = r->limit_rate * (ngx_time() - r->start_sec + 1) + limit = (off_t) r->limit_rate * (ngx_time() - r->start_sec + 1) - (c->sent - clcf->limit_rate_after); if (limit <= 0) { From mdounin at mdounin.ru Sun Feb 10 03:22:58 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Sun, 10 Feb 2013 03:22:58 +0000 Subject: [nginx] svn commit: r5044 - in branches/stable-1.2: . src/http/modules Message-ID: <20130210032259.0C6C43F9EB7@mail.nginx.com> Author: mdounin Date: 2013-02-10 03:22:58 +0000 (Sun, 10 Feb 2013) New Revision: 5044 URL: http://trac.nginx.org/nginx/changeset/5044/nginx Log: Merge of r4963: proxy: better error message about unexpected data. Requested by Igor Sysoev. Modified: branches/stable-1.2/ branches/stable-1.2/src/http/modules/ngx_http_proxy_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-10 03:20:00 UTC (rev 5043) +++ branches/stable-1.2 2013-02-10 03:22:58 UTC (rev 5044) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4962,4964,4973,4978,4984,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4964,4973,4978,4984,5011 \ No newline at end of property Modified: branches/stable-1.2/src/http/modules/ngx_http_proxy_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_proxy_module.c 2013-02-10 03:20:00 UTC (rev 5043) +++ branches/stable-1.2/src/http/modules/ngx_http_proxy_module.c 2013-02-10 03:22:58 UTC (rev 5044) @@ -1610,7 +1610,8 @@ p->upstream_done = 1; ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, - "upstream sent too much data"); + "upstream sent more data than specified in " + "\"Content-Length\" header"); } return NGX_OK; From mdounin at mdounin.ru Sun Feb 10 03:27:16 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Sun, 10 Feb 2013 03:27:16 +0000 Subject: [nginx] svn commit: r5045 - in branches/stable-1.2: . src/http Message-ID: <20130210032716.55FE13F9F75@mail.nginx.com> Author: mdounin Date: 2013-02-10 03:27:15 +0000 (Sun, 10 Feb 2013) New Revision: 5045 URL: http://trac.nginx.org/nginx/changeset/5045/nginx Log: Merge of r4965: upstream: fixed SIGSEGV with the "if" directive. Configuration like location / { set $true 1; if ($true) { proxy_pass http://backend; } if ($true) { # nothing } } resulted in segmentation fault due to NULL pointer dereference as the upstream configuration wasn't initialized in an implicit location created by the last if(), but the r->content_handler was set due to first if(). Instead of committing a suicide by dereferencing a NULL pointer, return 500 (Internal Server Error) in such cases, i.e. if uscf is NULL. Better fix would be to avoid such cases by fixing the "if" directive handling, but it's out of scope of this patch. Prodded by Piotr Sikora. Modified: branches/stable-1.2/ branches/stable-1.2/src/http/ngx_http_upstream.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-10 03:22:58 UTC (rev 5044) +++ branches/stable-1.2 2013-02-10 03:27:15 UTC (rev 5045) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4964,4973,4978,4984,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4965,4973,4978,4984,5011 \ No newline at end of property Modified: branches/stable-1.2/src/http/ngx_http_upstream.c =================================================================== --- branches/stable-1.2/src/http/ngx_http_upstream.c 2013-02-10 03:22:58 UTC (rev 5044) +++ branches/stable-1.2/src/http/ngx_http_upstream.c 2013-02-10 03:27:15 UTC (rev 5045) @@ -636,6 +636,14 @@ found: + if (uscf == NULL) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + "no upstream configuration"); + ngx_http_upstream_finalize_request(r, u, + NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + if (uscf->peer.init(r, uscf) != NGX_OK) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); From mdounin at mdounin.ru Sun Feb 10 03:52:26 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Sun, 10 Feb 2013 03:52:26 +0000 Subject: [nginx] svn commit: r5046 - in branches/stable-1.2: . src/http/modules Message-ID: <20130210035226.CA1983F9FA5@mail.nginx.com> Author: mdounin Date: 2013-02-10 03:52:26 +0000 (Sun, 10 Feb 2013) New Revision: 5046 URL: http://trac.nginx.org/nginx/changeset/5046/nginx Log: Merge of r4966: gzip: fixed zlib memLevel adjusting. An incorrect memLevel (lower than 1) might be passed to deflateInit2() if the "gzip_hash" directive is set to a value less than the value of "gzip_window" directive. This resulted in "deflateInit2() failed: -2" alert and an empty reply. Modified: branches/stable-1.2/ branches/stable-1.2/src/http/modules/ngx_http_gzip_filter_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-10 03:27:15 UTC (rev 5045) +++ branches/stable-1.2 2013-02-10 03:52:26 UTC (rev 5046) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4965,4973,4978,4984,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4966,4973,4978,4984,5011 \ No newline at end of property Modified: branches/stable-1.2/src/http/modules/ngx_http_gzip_filter_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_gzip_filter_module.c 2013-02-10 03:27:15 UTC (rev 5045) +++ branches/stable-1.2/src/http/modules/ngx_http_gzip_filter_module.c 2013-02-10 03:52:26 UTC (rev 5046) @@ -497,6 +497,10 @@ wbits--; memlevel--; } + + if (memlevel < 1) { + memlevel = 1; + } } ctx->wbits = wbits; From mdounin at mdounin.ru Sun Feb 10 03:55:19 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Sun, 10 Feb 2013 03:55:19 +0000 Subject: [nginx] svn commit: r5047 - in branches/stable-1.2: . src/core Message-ID: <20130210035521.053B93F9FAF@mail.nginx.com> Author: mdounin Date: 2013-02-10 03:55:18 +0000 (Sun, 10 Feb 2013) New Revision: 5047 URL: http://trac.nginx.org/nginx/changeset/5047/nginx Log: Merge of r4967: ngx_write_fd() and ngx_read_fd() errors handling. The ngx_write_fd() and ngx_read_fd() functions return -1 in case of error, so the incorrect comparison with NGX_FILE_ERROR (which is 0 on windows platforms) might result in inaccurate error message in the error log. Also the ngx_errno global variable is being set only if the returned value is -1. Modified: branches/stable-1.2/ branches/stable-1.2/src/core/ngx_conf_file.c branches/stable-1.2/src/core/ngx_cycle.c branches/stable-1.2/src/core/ngx_file.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-10 03:52:26 UTC (rev 5046) +++ branches/stable-1.2 2013-02-10 03:55:18 UTC (rev 5047) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4966,4973,4978,4984,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4967,4973,4978,4984,5011 \ No newline at end of property Modified: branches/stable-1.2/src/core/ngx_conf_file.c =================================================================== --- branches/stable-1.2/src/core/ngx_conf_file.c 2013-02-10 03:52:26 UTC (rev 5046) +++ branches/stable-1.2/src/core/ngx_conf_file.c 2013-02-10 03:55:18 UTC (rev 5047) @@ -983,7 +983,7 @@ n = ngx_write_fd(file[i].fd, file[i].buffer, len); - if (n == NGX_FILE_ERROR) { + if (n == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_write_fd_n " to \"%s\" failed", file[i].name.data); Modified: branches/stable-1.2/src/core/ngx_cycle.c =================================================================== --- branches/stable-1.2/src/core/ngx_cycle.c 2013-02-10 03:52:26 UTC (rev 5046) +++ branches/stable-1.2/src/core/ngx_cycle.c 2013-02-10 03:55:18 UTC (rev 5047) @@ -1145,7 +1145,7 @@ n = ngx_write_fd(file[i].fd, file[i].buffer, len); - if (n == NGX_FILE_ERROR) { + if (n == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_write_fd_n " to \"%s\" failed", file[i].name.data); Modified: branches/stable-1.2/src/core/ngx_file.c =================================================================== --- branches/stable-1.2/src/core/ngx_file.c 2013-02-10 03:52:26 UTC (rev 5046) +++ branches/stable-1.2/src/core/ngx_file.c 2013-02-10 03:55:18 UTC (rev 5047) @@ -732,14 +732,14 @@ n = ngx_read_fd(fd, buf, len); - if (n == NGX_FILE_ERROR) { + if (n == -1) { ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, ngx_read_fd_n " \"%s\" failed", from); goto failed; } if ((size_t) n != len) { - ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, + ngx_log_error(NGX_LOG_ALERT, cf->log, 0, ngx_read_fd_n " has read only %z of %uz from %s", n, size, from); goto failed; @@ -747,14 +747,14 @@ n = ngx_write_fd(nfd, buf, len); - if (n == NGX_FILE_ERROR) { + if (n == -1) { ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, ngx_write_fd_n " \"%s\" failed", to); goto failed; } if ((size_t) n != len) { - ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, + ngx_log_error(NGX_LOG_ALERT, cf->log, 0, ngx_write_fd_n " has written only %z of %uz to %s", n, size, to); goto failed; From mdounin at mdounin.ru Mon Feb 11 12:26:34 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 12:26:34 +0000 Subject: [nginx] svn commit: r5048 - in branches/stable-1.2: . src/core src/http/modules Message-ID: <20130211122634.6BE973F9F53@mail.nginx.com> Author: mdounin Date: 2013-02-11 12:26:33 +0000 (Mon, 11 Feb 2013) New Revision: 5048 URL: http://trac.nginx.org/nginx/changeset/5048/nginx Log: Merge of r4968, r4969, r4977, r4980, r4981, r4990: geo fixes. *) Geo: improved ngx_http_geo_block() code readability. *) Geo: fixed the "ranges" without ranges case. The following configuration returned an empty value for $geo: geo $geo { ranges; default default; } *) Fixed return type of internal function that allocates radix tree nodes. *) There's no need to normalize address returned by ngx_ptocidr(). *) Geo: ensure that default entry is always present. If 0.0.0.0/32 entry was present and there was no explicit "default", we failed to add an empty string as a default value. *) Trailing whitespace fix. Modified: branches/stable-1.2/ branches/stable-1.2/src/core/ngx_radix_tree.c branches/stable-1.2/src/http/modules/ngx_http_geo_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-10 03:55:18 UTC (rev 5047) +++ branches/stable-1.2 2013-02-11 12:26:33 UTC (rev 5048) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4967,4973,4978,4984,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973,4977-4978,4980-4981,4984,4990,5011 \ No newline at end of property Modified: branches/stable-1.2/src/core/ngx_radix_tree.c =================================================================== --- branches/stable-1.2/src/core/ngx_radix_tree.c 2013-02-10 03:55:18 UTC (rev 5047) +++ branches/stable-1.2/src/core/ngx_radix_tree.c 2013-02-11 12:26:33 UTC (rev 5048) @@ -9,7 +9,7 @@ #include -static void *ngx_radix_alloc(ngx_radix_tree_t *tree); +static ngx_radix_node_t *ngx_radix_alloc(ngx_radix_tree_t *tree); ngx_radix_tree_t * @@ -263,13 +263,13 @@ } -static void * +static ngx_radix_node_t * ngx_radix_alloc(ngx_radix_tree_t *tree) { - char *p; + ngx_radix_node_t *p; if (tree->free) { - p = (char *) tree->free; + p = tree->free; tree->free = tree->free->right; return p; } @@ -283,7 +283,7 @@ tree->size = ngx_pagesize; } - p = tree->start; + p = (ngx_radix_node_t *) tree->start; tree->start += sizeof(ngx_radix_node_t); tree->size -= sizeof(ngx_radix_node_t); Modified: branches/stable-1.2/src/http/modules/ngx_http_geo_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_geo_module.c 2013-02-10 03:55:18 UTC (rev 5047) +++ branches/stable-1.2/src/http/modules/ngx_http_geo_module.c 2013-02-11 12:26:33 UTC (rev 5048) @@ -189,19 +189,22 @@ *v = *ctx->u.high.default_value; - addr = ngx_http_geo_addr(r, ctx); + if (ctx->u.high.low) { + addr = ngx_http_geo_addr(r, ctx); - range = ctx->u.high.low[addr >> 16]; + range = ctx->u.high.low[addr >> 16]; - if (range) { - n = addr & 0xffff; - do { - if (n >= (ngx_uint_t) range->start && n <= (ngx_uint_t) range->end) - { - *v = *range->value; - break; - } - } while ((++range)->value); + if (range) { + n = addr & 0xffff; + do { + if (n >= (ngx_uint_t) range->start + && n <= (ngx_uint_t) range->end) + { + *v = *range->value; + break; + } + } while ((++range)->value); + } } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -303,7 +306,6 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *rv; - void **p; size_t len; ngx_str_t *value, name; ngx_uint_t i; @@ -392,9 +394,9 @@ geo->proxies = ctx.proxies; geo->proxy_recursive = ctx.proxy_recursive; - if (ctx.high.low) { + if (ctx.ranges) { - if (!ctx.binary_include) { + if (ctx.high.low && !ctx.binary_include) { for (i = 0; i < 0x10000; i++) { a = (ngx_array_t *) ctx.high.low[i]; @@ -409,8 +411,8 @@ return NGX_CONF_ERROR; } - p = (void **) ngx_cpymem(ctx.high.low[i], a->elts, len); - *p = NULL; + ngx_memcpy(ctx.high.low[i], a->elts, len); + ctx.high.low[i][a->nelts].value = NULL; ctx.data_size += len + sizeof(void *); } @@ -451,16 +453,14 @@ ngx_destroy_pool(ctx.temp_pool); ngx_destroy_pool(pool); - if (ngx_radix32tree_find(ctx.tree, 0) != NGX_RADIX_NO_VALUE) { - return rv; - } - if (ngx_radix32tree_insert(ctx.tree, 0, 0, (uintptr_t) &ngx_http_variable_null_value) == NGX_ERROR) { return NGX_CONF_ERROR; } + + /* NGX_BUSY is okay (default was set explicitly) */ } return rv; @@ -996,7 +996,7 @@ /* rc == NGX_BUSY */ old = (ngx_http_variable_value_t *) - ngx_radix32tree_find(ctx->tree, cidr.u.in.addr & cidr.u.in.mask); + ngx_radix32tree_find(ctx->tree, cidr.u.in.addr); ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "duplicate network \"%V\", value: \"%v\", old value: \"%v\"", From mdounin at mdounin.ru Mon Feb 11 12:31:46 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 12:31:46 +0000 Subject: [nginx] svn commit: r5049 - in branches/stable-1.2: . src/core src/http/modules Message-ID: <20130211123147.10F353F9E7F@mail.nginx.com> Author: mdounin Date: 2013-02-11 12:31:43 +0000 (Mon, 11 Feb 2013) New Revision: 5049 URL: http://trac.nginx.org/nginx/changeset/5049/nginx Log: Merge of r4993, r4994, r4997, r5000: geo ipv6 support. *) Geo: IPv6 support. The "ranges" mode is still limited to IPv4 only. *) Geo: properly initialize ngx_cidr_t when dealing with "default". *) Geo: made "default" affect both IPv4 and IPv6 when using prefixes. Previously, "default" was equivalent to specifying 0.0.0.0/0, now it's equivalent to specifying both 0.0.0.0/0 and ::/0 (if support for IPv6 is enabled) with the same value. *) Geo: improved code readability. Modified: branches/stable-1.2/ branches/stable-1.2/src/core/ngx_radix_tree.c branches/stable-1.2/src/core/ngx_radix_tree.h branches/stable-1.2/src/http/modules/ngx_http_geo_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 12:26:33 UTC (rev 5048) +++ branches/stable-1.2 2013-02-11 12:31:43 UTC (rev 5049) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973,4977-4978,4980-4981,4984,4990,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973,4977-4978,4980-4981,4984,4990,4993-4994,4997,5000,5011 \ No newline at end of property Modified: branches/stable-1.2/src/core/ngx_radix_tree.c =================================================================== --- branches/stable-1.2/src/core/ngx_radix_tree.c 2013-02-11 12:26:33 UTC (rev 5048) +++ branches/stable-1.2/src/core/ngx_radix_tree.c 2013-02-11 12:31:43 UTC (rev 5049) @@ -263,6 +263,203 @@ } +#if (NGX_HAVE_INET6) + +ngx_int_t +ngx_radix128tree_insert(ngx_radix_tree_t *tree, u_char *key, u_char *mask, + uintptr_t value) +{ + u_char bit; + ngx_uint_t i; + ngx_radix_node_t *node, *next; + + i = 0; + bit = 0x80; + + node = tree->root; + next = tree->root; + + while (bit & mask[i]) { + if (key[i] & bit) { + next = node->right; + + } else { + next = node->left; + } + + if (next == NULL) { + break; + } + + bit >>= 1; + node = next; + + if (bit == 0) { + if (++i == 16) { + break; + } + + bit = 0x80; + } + } + + if (next) { + if (node->value != NGX_RADIX_NO_VALUE) { + return NGX_BUSY; + } + + node->value = value; + return NGX_OK; + } + + while (bit & mask[i]) { + next = ngx_radix_alloc(tree); + if (next == NULL) { + return NGX_ERROR; + } + + next->right = NULL; + next->left = NULL; + next->parent = node; + next->value = NGX_RADIX_NO_VALUE; + + if (key[i] & bit) { + node->right = next; + + } else { + node->left = next; + } + + bit >>= 1; + node = next; + + if (bit == 0) { + if (++i == 16) { + break; + } + + bit = 0x80; + } + } + + node->value = value; + + return NGX_OK; +} + + +ngx_int_t +ngx_radix128tree_delete(ngx_radix_tree_t *tree, u_char *key, u_char *mask) +{ + u_char bit; + ngx_uint_t i; + ngx_radix_node_t *node; + + i = 0; + bit = 0x80; + node = tree->root; + + while (node && (bit & mask[i])) { + if (key[i] & bit) { + node = node->right; + + } else { + node = node->left; + } + + bit >>= 1; + + if (bit == 0) { + if (++i == 16) { + break; + } + + bit = 0x80; + } + } + + if (node == NULL) { + return NGX_ERROR; + } + + if (node->right || node->left) { + if (node->value != NGX_RADIX_NO_VALUE) { + node->value = NGX_RADIX_NO_VALUE; + return NGX_OK; + } + + return NGX_ERROR; + } + + for ( ;; ) { + if (node->parent->right == node) { + node->parent->right = NULL; + + } else { + node->parent->left = NULL; + } + + node->right = tree->free; + tree->free = node; + + node = node->parent; + + if (node->right || node->left) { + break; + } + + if (node->value != NGX_RADIX_NO_VALUE) { + break; + } + + if (node->parent == NULL) { + break; + } + } + + return NGX_OK; +} + + +uintptr_t +ngx_radix128tree_find(ngx_radix_tree_t *tree, u_char *key) +{ + u_char bit; + uintptr_t value; + ngx_uint_t i; + ngx_radix_node_t *node; + + i = 0; + bit = 0x80; + value = NGX_RADIX_NO_VALUE; + node = tree->root; + + while (node) { + if (node->value != NGX_RADIX_NO_VALUE) { + value = node->value; + } + + if (key[i] & bit) { + node = node->right; + + } else { + node = node->left; + } + + bit >>= 1; + + if (bit == 0) { + i++; + bit = 0x80; + } + } + + return value; +} + +#endif + + static ngx_radix_node_t * ngx_radix_alloc(ngx_radix_tree_t *tree) { Modified: branches/stable-1.2/src/core/ngx_radix_tree.h =================================================================== --- branches/stable-1.2/src/core/ngx_radix_tree.h 2013-02-11 12:26:33 UTC (rev 5048) +++ branches/stable-1.2/src/core/ngx_radix_tree.h 2013-02-11 12:31:43 UTC (rev 5049) @@ -36,11 +36,20 @@ ngx_radix_tree_t *ngx_radix_tree_create(ngx_pool_t *pool, ngx_int_t preallocate); + ngx_int_t ngx_radix32tree_insert(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask, uintptr_t value); ngx_int_t ngx_radix32tree_delete(ngx_radix_tree_t *tree, uint32_t key, uint32_t mask); uintptr_t ngx_radix32tree_find(ngx_radix_tree_t *tree, uint32_t key); +#if (NGX_HAVE_INET6) +ngx_int_t ngx_radix128tree_insert(ngx_radix_tree_t *tree, + u_char *key, u_char *mask, uintptr_t value); +ngx_int_t ngx_radix128tree_delete(ngx_radix_tree_t *tree, + u_char *key, u_char *mask); +uintptr_t ngx_radix128tree_find(ngx_radix_tree_t *tree, u_char *key); +#endif + #endif /* _NGX_RADIX_TREE_H_INCLUDED_ */ Modified: branches/stable-1.2/src/http/modules/ngx_http_geo_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_geo_module.c 2013-02-11 12:26:33 UTC (rev 5048) +++ branches/stable-1.2/src/http/modules/ngx_http_geo_module.c 2013-02-11 12:31:43 UTC (rev 5049) @@ -18,6 +18,14 @@ typedef struct { + ngx_radix_tree_t *tree; +#if (NGX_HAVE_INET6) + ngx_radix_tree_t *tree6; +#endif +} ngx_http_geo_trees_t; + + +typedef struct { ngx_http_geo_range_t **low; ngx_http_variable_value_t *default_value; } ngx_http_geo_high_ranges_t; @@ -35,6 +43,9 @@ ngx_str_t *net; ngx_http_geo_high_ranges_t high; ngx_radix_tree_t *tree; +#if (NGX_HAVE_INET6) + ngx_radix_tree_t *tree6; +#endif ngx_rbtree_t rbtree; ngx_rbtree_node_t sentinel; ngx_array_t *proxies; @@ -57,7 +68,7 @@ typedef struct { union { - ngx_radix_tree_t *tree; + ngx_http_geo_trees_t trees; ngx_http_geo_high_ranges_t high; } u; @@ -68,8 +79,8 @@ } ngx_http_geo_ctx_t; -static in_addr_t ngx_http_geo_addr(ngx_http_request_t *r, - ngx_http_geo_ctx_t *ctx); +static ngx_int_t ngx_http_geo_addr(ngx_http_request_t *r, + ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr); static ngx_int_t ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr); static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -82,6 +93,8 @@ ngx_http_geo_conf_ctx_t *ctx, in_addr_t start, in_addr_t end); static char *ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value); +static char *ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, + ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net); static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value); static char *ngx_http_geo_add_proxy(ngx_conf_t *cf, @@ -155,7 +168,7 @@ }; -/* AF_INET only */ +/* geo range is AF_INET only */ static ngx_int_t ngx_http_geo_cidr_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, @@ -163,11 +176,57 @@ { ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data; + in_addr_t inaddr; + ngx_addr_t addr; + struct sockaddr_in *sin; ngx_http_variable_value_t *vv; +#if (NGX_HAVE_INET6) + u_char *p; + struct in6_addr *inaddr6; +#endif - vv = (ngx_http_variable_value_t *) - ngx_radix32tree_find(ctx->u.tree, ngx_http_geo_addr(r, ctx)); + if (ngx_http_geo_addr(r, ctx, &addr) != NGX_OK) { + vv = (ngx_http_variable_value_t *) + ngx_radix32tree_find(ctx->u.trees.tree, INADDR_NONE); + goto done; + } + switch (addr.sockaddr->sa_family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr; + p = inaddr6->s6_addr; + + if (IN6_IS_ADDR_V4MAPPED(inaddr6)) { + inaddr = p[12] << 24; + inaddr += p[13] << 16; + inaddr += p[14] << 8; + inaddr += p[15]; + + vv = (ngx_http_variable_value_t *) + ngx_radix32tree_find(ctx->u.trees.tree, inaddr); + + } else { + vv = (ngx_http_variable_value_t *) + ngx_radix128tree_find(ctx->u.trees.tree6, p); + } + + break; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) addr.sockaddr; + inaddr = ntohl(sin->sin_addr.s_addr); + + vv = (ngx_http_variable_value_t *) + ngx_radix32tree_find(ctx->u.trees.tree, inaddr); + + break; + } + +done: + *v = *vv; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -183,19 +242,56 @@ { ngx_http_geo_ctx_t *ctx = (ngx_http_geo_ctx_t *) data; - in_addr_t addr; + in_addr_t inaddr; + ngx_addr_t addr; ngx_uint_t n; + struct sockaddr_in *sin; ngx_http_geo_range_t *range; +#if (NGX_HAVE_INET6) + u_char *p; + struct in6_addr *inaddr6; +#endif *v = *ctx->u.high.default_value; + if (ngx_http_geo_addr(r, ctx, &addr) == NGX_OK) { + + switch (addr.sockaddr->sa_family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr; + + if (IN6_IS_ADDR_V4MAPPED(inaddr6)) { + p = inaddr6->s6_addr; + + inaddr = p[12] << 24; + inaddr += p[13] << 16; + inaddr += p[14] << 8; + inaddr += p[15]; + + } else { + inaddr = INADDR_NONE; + } + + break; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) addr.sockaddr; + inaddr = ntohl(sin->sin_addr.s_addr); + break; + } + + } else { + inaddr = INADDR_NONE; + } + if (ctx->u.high.low) { - addr = ngx_http_geo_addr(r, ctx); + range = ctx->u.high.low[inaddr >> 16]; - range = ctx->u.high.low[addr >> 16]; - if (range) { - n = addr & 0xffff; + n = inaddr & 0xffff; do { if (n >= (ngx_uint_t) range->start && n <= (ngx_uint_t) range->end) @@ -214,54 +310,25 @@ } -static in_addr_t -ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx) +static ngx_int_t +ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx, + ngx_addr_t *addr) { - ngx_addr_t addr; - ngx_table_elt_t *xfwd; - struct sockaddr_in *sin; + ngx_table_elt_t *xfwd; - if (ngx_http_geo_real_addr(r, ctx, &addr) != NGX_OK) { - return INADDR_NONE; + if (ngx_http_geo_real_addr(r, ctx, addr) != NGX_OK) { + return NGX_ERROR; } xfwd = r->headers_in.x_forwarded_for; if (xfwd != NULL && ctx->proxies != NULL) { - (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data, + (void) ngx_http_get_forwarded_addr(r, addr, xfwd->value.data, xfwd->value.len, ctx->proxies, ctx->proxy_recursive); } -#if (NGX_HAVE_INET6) - - if (addr.sockaddr->sa_family == AF_INET6) { - u_char *p; - in_addr_t inaddr; - struct in6_addr *inaddr6; - - inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr; - - if (IN6_IS_ADDR_V4MAPPED(inaddr6)) { - p = inaddr6->s6_addr; - - inaddr = p[12] << 24; - inaddr += p[13] << 16; - inaddr += p[14] << 8; - inaddr += p[15]; - - return inaddr; - } - } - -#endif - - if (addr.sockaddr->sa_family != AF_INET) { - return INADDR_NONE; - } - - sin = (struct sockaddr_in *) addr.sockaddr; - return ntohl(sin->sin_addr.s_addr); + return NGX_OK; } @@ -315,6 +382,9 @@ ngx_http_variable_t *var; ngx_http_geo_ctx_t *geo; ngx_http_geo_conf_ctx_t ctx; +#if (NGX_HAVE_INET6) + static struct in6_addr zero; +#endif value = cf->args->elts; @@ -445,8 +515,19 @@ } } - geo->u.tree = ctx.tree; + geo->u.trees.tree = ctx.tree; +#if (NGX_HAVE_INET6) + if (ctx.tree6 == NULL) { + ctx.tree6 = ngx_radix_tree_create(cf->pool, -1); + if (ctx.tree6 == NULL) { + return NGX_CONF_ERROR; + } + } + + geo->u.trees.tree6 = ctx.tree6; +#endif + var->get_handler = ngx_http_geo_cidr_variable; var->data = (uintptr_t) geo; @@ -461,6 +542,15 @@ } /* NGX_BUSY is okay (default was set explicitly) */ + +#if (NGX_HAVE_INET6) + if (ngx_radix128tree_insert(ctx.tree6, zero.s6_addr, zero.s6_addr, + (uintptr_t) &ngx_http_variable_null_value) + == NGX_ERROR) + { + return NGX_CONF_ERROR; + } +#endif } return rv; @@ -483,7 +573,12 @@ if (ngx_strcmp(value[0].data, "ranges") == 0) { - if (ctx->tree) { + if (ctx->tree +#if (NGX_HAVE_INET6) + || ctx->tree6 +#endif + ) + { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the \"ranges\" directive must be " "the first directive inside \"geo\" block"); @@ -921,11 +1016,10 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value) { - ngx_int_t rc, del; - ngx_str_t *net; - ngx_uint_t i; - ngx_cidr_t cidr; - ngx_http_variable_value_t *val, *old; + char *rv; + ngx_int_t rc, del; + ngx_str_t *net; + ngx_cidr_t cidr; if (ctx->tree == NULL) { ctx->tree = ngx_radix_tree_create(ctx->pool, -1); @@ -934,57 +1028,108 @@ } } +#if (NGX_HAVE_INET6) + if (ctx->tree6 == NULL) { + ctx->tree6 = ngx_radix_tree_create(ctx->pool, -1); + if (ctx->tree6 == NULL) { + return NGX_CONF_ERROR; + } + } +#endif + if (ngx_strcmp(value[0].data, "default") == 0) { - /* cidr.family = AF_INET; */ + cidr.family = AF_INET; cidr.u.in.addr = 0; cidr.u.in.mask = 0; - net = &value[0]; - } else { - if (ngx_strcmp(value[0].data, "delete") == 0) { - net = &value[1]; - del = 1; + rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]); - } else { - net = &value[0]; - del = 0; + if (rv != NGX_CONF_OK) { + return rv; } - if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) { - return NGX_CONF_ERROR; - } +#if (NGX_HAVE_INET6) + cidr.family = AF_INET6; + ngx_memzero(&cidr.u.in6, sizeof(ngx_in6_cidr_t)); - if (cidr.family != AF_INET) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"geo\" supports IPv4 only"); - return NGX_CONF_ERROR; + rv = ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], &value[0]); + + if (rv != NGX_CONF_OK) { + return rv; } +#endif + return NGX_CONF_OK; + } + + if (ngx_strcmp(value[0].data, "delete") == 0) { + net = &value[1]; + del = 1; + + } else { + net = &value[0]; + del = 0; + } + + if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) { + return NGX_CONF_ERROR; + } + + if (cidr.family == AF_INET) { cidr.u.in.addr = ntohl(cidr.u.in.addr); cidr.u.in.mask = ntohl(cidr.u.in.mask); + } - if (del) { - if (ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, - cidr.u.in.mask) - != NGX_OK) - { - ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "no network \"%V\" to delete", net); - } + if (del) { + switch (cidr.family) { - return NGX_CONF_OK; +#if (NGX_HAVE_INET6) + case AF_INET6: + rc = ngx_radix128tree_delete(ctx->tree6, + cidr.u.in6.addr.s6_addr, + cidr.u.in6.mask.s6_addr); + break; +#endif + + default: /* AF_INET */ + rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, + cidr.u.in.mask); + break; } + + if (rc != NGX_OK) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "no network \"%V\" to delete", net); + } + + return NGX_CONF_OK; } - val = ngx_http_geo_value(cf, ctx, &value[1]); + return ngx_http_geo_cidr_add(cf, ctx, &cidr, &value[1], net); +} + +static char * +ngx_http_geo_cidr_add(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx, + ngx_cidr_t *cidr, ngx_str_t *value, ngx_str_t *net) +{ + ngx_int_t rc; + ngx_http_variable_value_t *val, *old; + + val = ngx_http_geo_value(cf, ctx, value); + if (val == NULL) { return NGX_CONF_ERROR; } - for (i = 2; i; i--) { - rc = ngx_radix32tree_insert(ctx->tree, cidr.u.in.addr, cidr.u.in.mask, - (uintptr_t) val); + switch (cidr->family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr, + cidr->u.in6.mask.s6_addr, + (uintptr_t) val); + if (rc == NGX_OK) { return NGX_CONF_OK; } @@ -996,20 +1141,68 @@ /* rc == NGX_BUSY */ old = (ngx_http_variable_value_t *) - ngx_radix32tree_find(ctx->tree, cidr.u.in.addr); + ngx_radix128tree_find(ctx->tree6, + cidr->u.in6.addr.s6_addr); ngx_conf_log_error(NGX_LOG_WARN, cf, 0, - "duplicate network \"%V\", value: \"%v\", old value: \"%v\"", - net, val, old); + "duplicate network \"%V\", value: \"%v\", old value: \"%v\"", + net, val, old); - rc = ngx_radix32tree_delete(ctx->tree, cidr.u.in.addr, cidr.u.in.mask); + rc = ngx_radix128tree_delete(ctx->tree6, + cidr->u.in6.addr.s6_addr, + cidr->u.in6.mask.s6_addr); if (rc == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree"); return NGX_CONF_ERROR; } + + rc = ngx_radix128tree_insert(ctx->tree6, cidr->u.in6.addr.s6_addr, + cidr->u.in6.mask.s6_addr, + (uintptr_t) val); + + break; +#endif + + default: /* AF_INET */ + rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr, + cidr->u.in.mask, (uintptr_t) val); + + if (rc == NGX_OK) { + return NGX_CONF_OK; + } + + if (rc == NGX_ERROR) { + return NGX_CONF_ERROR; + } + + /* rc == NGX_BUSY */ + + old = (ngx_http_variable_value_t *) + ngx_radix32tree_find(ctx->tree, cidr->u.in.addr); + + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "duplicate network \"%V\", value: \"%v\", old value: \"%v\"", + net, val, old); + + rc = ngx_radix32tree_delete(ctx->tree, + cidr->u.in.addr, cidr->u.in.mask); + + if (rc == NGX_ERROR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid radix tree"); + return NGX_CONF_ERROR; + } + + rc = ngx_radix32tree_insert(ctx->tree, cidr->u.in.addr, + cidr->u.in.mask, (uintptr_t) val); + + break; } + if (rc == NGX_OK) { + return NGX_CONF_OK; + } + return NGX_CONF_ERROR; } From mdounin at mdounin.ru Mon Feb 11 12:35:50 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 12:35:50 +0000 Subject: [nginx] svn commit: r5050 - in branches/stable-1.2: . src/http Message-ID: <20130211123550.21C5C3F9F56@mail.nginx.com> Author: mdounin Date: 2013-02-11 12:35:49 +0000 (Mon, 11 Feb 2013) New Revision: 5050 URL: http://trac.nginx.org/nginx/changeset/5050/nginx Log: Merge of r4974: avoid sending "100 Continue" on 413. Avoid sending "100 Continue" on 413 Request Entity Too Large. Patch by Igor Sysoev. Modified: branches/stable-1.2/ branches/stable-1.2/src/http/ngx_http_core_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 12:31:43 UTC (rev 5049) +++ branches/stable-1.2 2013-02-11 12:35:49 UTC (rev 5050) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973,4977-4978,4980-4981,4984,4990,4993-4994,4997,5000,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4977-4978,4980-4981,4984,4990,4993-4994,4997,5000,5011 \ No newline at end of property Modified: branches/stable-1.2/src/http/ngx_http_core_module.c =================================================================== --- branches/stable-1.2/src/http/ngx_http_core_module.c 2013-02-11 12:31:43 UTC (rev 5049) +++ branches/stable-1.2/src/http/ngx_http_core_module.c 2013-02-11 12:35:49 UTC (rev 5050) @@ -993,6 +993,7 @@ "client intended to send too large body: %O bytes", r->headers_in.content_length_n); + r->expect_tested = 1; (void) ngx_http_discard_request_body(r); ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE); return NGX_OK; From mdounin at mdounin.ru Mon Feb 11 12:37:06 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 12:37:06 +0000 Subject: [nginx] svn commit: r5051 - in branches/stable-1.2: . src/os/unix Message-ID: <20130211123706.F12923F9F59@mail.nginx.com> Author: mdounin Date: 2013-02-11 12:37:06 +0000 (Mon, 11 Feb 2013) New Revision: 5051 URL: http://trac.nginx.org/nginx/changeset/5051/nginx Log: Merge of r4983: crypt_r() error handling fixed. The crypt_r() function returns NULL on errors, check it explicitly instead of assuming errno will remain 0 if there are no errors (per POSIX, the setting of errno after a successful call to a function is unspecified unless the description of that function specifies that errno shall not be modified). Additionally, dropped unneeded ngx_set_errno(0) and fixed error handling of memory allocation after normal crypt(), which was inapropriate and resulted in null pointer dereference on allocation failures. Modified: branches/stable-1.2/ branches/stable-1.2/src/os/unix/ngx_user.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 12:35:49 UTC (rev 5050) +++ branches/stable-1.2 2013-02-11 12:37:06 UTC (rev 5051) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4977-4978,4980-4981,4984,4990,4993-4994,4997,5000,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4977-4978,4980-4981,4983-4984,4990,4993-4994,4997,5000,5011 \ No newline at end of property Modified: branches/stable-1.2/src/os/unix/ngx_user.c =================================================================== --- branches/stable-1.2/src/os/unix/ngx_user.c 2013-02-11 12:35:49 UTC (rev 5050) +++ branches/stable-1.2/src/os/unix/ngx_user.c 2013-02-11 12:37:06 UTC (rev 5051) @@ -28,30 +28,27 @@ { char *value; size_t len; - ngx_err_t err; struct crypt_data cd; - ngx_set_errno(0); - cd.initialized = 0; /* work around the glibc bug */ cd.current_salt[0] = ~salt[0]; value = crypt_r((char *) key, (char *) salt, &cd); - err = ngx_errno; - - if (err == 0) { + if (value) { len = ngx_strlen(value) + 1; *encrypted = ngx_pnalloc(pool, len); - if (*encrypted) { - ngx_memcpy(*encrypted, value, len); - return NGX_OK; + if (*encrypted == NULL) { + return NGX_ERROR; } + + ngx_memcpy(*encrypted, value, len); + return NGX_OK; } - ngx_log_error(NGX_LOG_CRIT, pool->log, err, "crypt_r() failed"); + ngx_log_error(NGX_LOG_CRIT, pool->log, ngx_errno, "crypt_r() failed"); return NGX_ERROR; } @@ -75,18 +72,20 @@ #endif - ngx_set_errno(0); - value = crypt((char *) key, (char *) salt); if (value) { len = ngx_strlen(value) + 1; *encrypted = ngx_pnalloc(pool, len); - if (*encrypted) { - ngx_memcpy(*encrypted, value, len); + if (*encrypted == NULL) { +#if (NGX_THREADS && NGX_NONREENTRANT_CRYPT) + ngx_mutex_unlock(ngx_crypt_mutex); +#endif + return NGX_ERROR; } + ngx_memcpy(*encrypted, value, len); #if (NGX_THREADS && NGX_NONREENTRANT_CRYPT) ngx_mutex_unlock(ngx_crypt_mutex); #endif From mdounin at mdounin.ru Mon Feb 11 13:52:13 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 13:52:13 +0000 Subject: [nginx] svn commit: r5052 - in branches/stable-1.2: . src/http/modules Message-ID: <20130211135213.BB7843F9F78@mail.nginx.com> Author: mdounin Date: 2013-02-11 13:52:13 +0000 (Mon, 11 Feb 2013) New Revision: 5052 URL: http://trac.nginx.org/nginx/changeset/5052/nginx Log: Merge of r4976: let add_header affect 201 responses (ticket #125). Modified: branches/stable-1.2/ branches/stable-1.2/src/http/modules/ngx_http_headers_filter_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 12:37:06 UTC (rev 5051) +++ branches/stable-1.2 2013-02-11 13:52:13 UTC (rev 5052) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4977-4978,4980-4981,4983-4984,4990,4993-4994,4997,5000,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4978,4980-4981,4983-4984,4990,4993-4994,4997,5000,5011 \ No newline at end of property Modified: branches/stable-1.2/src/http/modules/ngx_http_headers_filter_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_headers_filter_module.c 2013-02-11 12:37:06 UTC (rev 5051) +++ branches/stable-1.2/src/http/modules/ngx_http_headers_filter_module.c 2013-02-11 13:52:13 UTC (rev 5052) @@ -149,6 +149,7 @@ if ((conf->expires == NGX_HTTP_EXPIRES_OFF && conf->headers == NULL) || r != r->main || (r->headers_out.status != NGX_HTTP_OK + && r->headers_out.status != NGX_HTTP_CREATED && r->headers_out.status != NGX_HTTP_NO_CONTENT && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT && r->headers_out.status != NGX_HTTP_MOVED_PERMANENTLY From mdounin at mdounin.ru Mon Feb 11 13:59:09 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 13:59:09 +0000 Subject: [nginx] svn commit: r5053 - in branches/stable-1.2: . src/http/modules Message-ID: <20130211135909.DB6EE3FAA2B@mail.nginx.com> Author: mdounin Date: 2013-02-11 13:59:08 +0000 (Mon, 11 Feb 2013) New Revision: 5053 URL: http://trac.nginx.org/nginx/changeset/5053/nginx Log: Merge of r4979, r4982: image filter configuration inheritance. *) Image filter: configuration inheritance fixes. The image_filter_jpeg_quality, image_filter_sharpen and "image_filter rotate" were inherited incorrectly if a directive with variables was defined, and then redefined to a literal value, i.e. in configurations like image_filter_jpeg_quality $arg_q; location / { image_filter_jpeg_quality 50; } Patch by Ian Babrou, with minor changes. *) Image filter: fixed image_filter rotate inheritance. Configurations like location /i/ { image_filter resize 200 200; image_filter rotate 180; location /i/foo/ { image_filter resize 200 200; } } resulted in rotation incorrectly applied in the location /i/foo, without any way to clear it. Fix is to handle conf->angle/conf->acv consistently with other filter variables and do not try to inherit them if there are transformations defined for current location. Modified: branches/stable-1.2/ branches/stable-1.2/src/http/modules/ngx_http_image_filter_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 13:52:13 UTC (rev 5052) +++ branches/stable-1.2 2013-02-11 13:59:08 UTC (rev 5053) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4978,4980-4981,4983-4984,4990,4993-4994,4997,5000,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4984,4990,4993-4994,4997,5000,5011 \ No newline at end of property Modified: branches/stable-1.2/src/http/modules/ngx_http_image_filter_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_image_filter_module.c 2013-02-11 13:52:13 UTC (rev 5052) +++ branches/stable-1.2/src/http/modules/ngx_http_image_filter_module.c 2013-02-11 13:59:08 UTC (rev 5053) @@ -1169,10 +1169,22 @@ return NULL; } + /* + * set by ngx_pcalloc(): + * + * conf->width = 0; + * conf->height = 0; + * conf->angle = 0; + * conf->wcv = NULL; + * conf->hcv = NULL; + * conf->acv = NULL; + * conf->jqcv = NULL; + * conf->shcv = NULL; + */ + conf->filter = NGX_CONF_UNSET_UINT; conf->jpeg_quality = NGX_CONF_UNSET_UINT; conf->sharpen = NGX_CONF_UNSET_UINT; - conf->angle = NGX_CONF_UNSET_UINT; conf->transparency = NGX_CONF_UNSET; conf->buffer_size = NGX_CONF_UNSET_SIZE; @@ -1195,29 +1207,31 @@ conf->filter = prev->filter; conf->width = prev->width; conf->height = prev->height; + conf->angle = prev->angle; conf->wcv = prev->wcv; conf->hcv = prev->hcv; + conf->acv = prev->acv; } } - /* 75 is libjpeg default quality */ - ngx_conf_merge_uint_value(conf->jpeg_quality, prev->jpeg_quality, 75); + if (conf->jpeg_quality == NGX_CONF_UNSET_UINT) { - if (conf->jqcv == NULL) { - conf->jqcv = prev->jqcv; + /* 75 is libjpeg default quality */ + ngx_conf_merge_uint_value(conf->jpeg_quality, prev->jpeg_quality, 75); + + if (conf->jqcv == NULL) { + conf->jqcv = prev->jqcv; + } } - ngx_conf_merge_uint_value(conf->sharpen, prev->sharpen, 0); + if (conf->sharpen == NGX_CONF_UNSET_UINT) { + ngx_conf_merge_uint_value(conf->sharpen, prev->sharpen, 0); - if (conf->shcv == NULL) { - conf->shcv = prev->shcv; + if (conf->shcv == NULL) { + conf->shcv = prev->shcv; + } } - ngx_conf_merge_uint_value(conf->angle, prev->angle, 0); - if (conf->acv == NULL) { - conf->acv = prev->acv; - } - ngx_conf_merge_value(conf->transparency, prev->transparency, 1); ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, From mdounin at mdounin.ru Mon Feb 11 14:34:00 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 14:34:00 +0000 Subject: [nginx] svn commit: r5054 - in branches/stable-1.2: . auto/lib/zlib src/core src/http/modules Message-ID: <20130211143401.B30C63F9FFA@mail.nginx.com> Author: mdounin Date: 2013-02-11 14:34:00 +0000 (Mon, 11 Feb 2013) New Revision: 5054 URL: http://trac.nginx.org/nginx/changeset/5054/nginx Log: Merge of r4985, r4986, r4987, r4988, r4989, r5002: access_log gzip. *) Access log: fixed redundant buffer reallocation. Previously a new buffer was allocated for every "access_log" directive with the same file path and "buffer=" parameters, while only one buffer per file is used. *) Reopening log files code moved to a separate function. The code refactored in a way to call custom handler that can do appropriate cleanup work (if any), like flushing buffers, finishing compress streams, finalizing connections to log daemon, etc.. *) Access log: the "flush" parameter of the "access_log" directive. *) Configure: added the NGX_ZLIB define. This was introduced for conditional compilation of the code that requires the zlib library. *) Access log: the "gzip" parameter of the "access_log" directive. Note: this requires zlib version 1.2.0.4 or above to work. *) The data pointer in ngx_open_file_t objects must be initialized. Uninitialized pointer may result in arbitrary segfaults if access_log is used without buffer and without variables in file path. Patch by Tatsuhiko Kubo (ticket #268). Modified: branches/stable-1.2/ branches/stable-1.2/auto/lib/zlib/conf branches/stable-1.2/src/core/ngx_conf_file.c branches/stable-1.2/src/core/ngx_conf_file.h branches/stable-1.2/src/core/ngx_cycle.c branches/stable-1.2/src/http/modules/ngx_http_log_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 13:59:08 UTC (rev 5053) +++ branches/stable-1.2 2013-02-11 14:34:00 UTC (rev 5054) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4984,4990,4993-4994,4997,5000,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4990,4993-4994,4997,5000,5002,5011 \ No newline at end of property Modified: branches/stable-1.2/auto/lib/zlib/conf =================================================================== --- branches/stable-1.2/auto/lib/zlib/conf 2013-02-11 13:59:08 UTC (rev 5053) +++ branches/stable-1.2/auto/lib/zlib/conf 2013-02-11 14:34:00 UTC (rev 5054) @@ -9,11 +9,13 @@ case "$NGX_CC_NAME" in msvc* | owc* | bcc) + have=NGX_ZLIB . auto/have LINK_DEPS="$LINK_DEPS $ZLIB/zlib.lib" CORE_LIBS="$CORE_LIBS $ZLIB/zlib.lib" ;; icc*) + have=NGX_ZLIB . auto/have LINK_DEPS="$LINK_DEPS $ZLIB/libz.a" # to allow -ipo optimization we link with the *.o but not library @@ -30,6 +32,7 @@ ;; *) + have=NGX_ZLIB . auto/have LINK_DEPS="$LINK_DEPS $ZLIB/libz.a" CORE_LIBS="$CORE_LIBS $ZLIB/libz.a" #CORE_LIBS="$CORE_LIBS -L $ZLIB -lz" @@ -45,7 +48,7 @@ # FreeBSD, Solaris, Linux ngx_feature="zlib library" - ngx_feature_name= + ngx_feature_name="NGX_ZLIB" ngx_feature_run=no ngx_feature_incs="#include " ngx_feature_path= Modified: branches/stable-1.2/src/core/ngx_conf_file.c =================================================================== --- branches/stable-1.2/src/core/ngx_conf_file.c 2013-02-11 13:59:08 UTC (rev 5053) +++ branches/stable-1.2/src/core/ngx_conf_file.c 2013-02-11 14:34:00 UTC (rev 5054) @@ -945,7 +945,8 @@ file->name = *name; } - file->buffer = NULL; + file->flush = NULL; + file->data = NULL; return file; } @@ -954,7 +955,6 @@ static void ngx_conf_flush_files(ngx_cycle_t *cycle) { - ssize_t n, len; ngx_uint_t i; ngx_list_part_t *part; ngx_open_file_t *file; @@ -975,24 +975,9 @@ i = 0; } - len = file[i].pos - file[i].buffer; - - if (file[i].buffer == NULL || len == 0) { - continue; + if (file[i].flush) { + file[i].flush(&file[i], cycle->log); } - - n = ngx_write_fd(file[i].fd, file[i].buffer, len); - - if (n == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - ngx_write_fd_n " to \"%s\" failed", - file[i].name.data); - - } else if (n != len) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz", - file[i].name.data, n, len); - } } } Modified: branches/stable-1.2/src/core/ngx_conf_file.h =================================================================== --- branches/stable-1.2/src/core/ngx_conf_file.h 2013-02-11 13:59:08 UTC (rev 5053) +++ branches/stable-1.2/src/core/ngx_conf_file.h 2013-02-11 14:34:00 UTC (rev 5054) @@ -91,17 +91,8 @@ ngx_fd_t fd; ngx_str_t name; - u_char *buffer; - u_char *pos; - u_char *last; - -#if 0 - /* e.g. append mode, error_log */ - ngx_uint_t flags; - /* e.g. reopen db file */ - ngx_uint_t (*handler)(void *data, ngx_open_file_t *file); + void (*flush)(ngx_open_file_t *file, ngx_log_t *log); void *data; -#endif }; Modified: branches/stable-1.2/src/core/ngx_cycle.c =================================================================== --- branches/stable-1.2/src/core/ngx_cycle.c 2013-02-11 13:59:08 UTC (rev 5053) +++ branches/stable-1.2/src/core/ngx_cycle.c 2013-02-11 14:34:00 UTC (rev 5054) @@ -1115,7 +1115,6 @@ void ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user) { - ssize_t n, len; ngx_fd_t fd; ngx_uint_t i; ngx_list_part_t *part; @@ -1139,24 +1138,8 @@ continue; } - len = file[i].pos - file[i].buffer; - - if (file[i].buffer && len != 0) { - - n = ngx_write_fd(file[i].fd, file[i].buffer, len); - - if (n == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - ngx_write_fd_n " to \"%s\" failed", - file[i].name.data); - - } else if (n != len) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz", - file[i].name.data, n, len); - } - - file[i].pos = file[i].buffer; + if (file[i].flush) { + file[i].flush(&file[i], cycle->log); } fd = ngx_open_file(file[i].name.data, NGX_FILE_APPEND, Modified: branches/stable-1.2/src/http/modules/ngx_http_log_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_log_module.c 2013-02-11 13:59:08 UTC (rev 5053) +++ branches/stable-1.2/src/http/modules/ngx_http_log_module.c 2013-02-11 14:34:00 UTC (rev 5054) @@ -9,7 +9,11 @@ #include #include +#if (NGX_ZLIB) +#include +#endif + typedef struct ngx_http_log_op_s ngx_http_log_op_t; typedef u_char *(*ngx_http_log_op_run_pt) (ngx_http_request_t *r, u_char *buf, @@ -41,6 +45,17 @@ typedef struct { + u_char *start; + u_char *pos; + u_char *last; + + ngx_event_t *event; + ngx_msec_t flush; + ngx_int_t gzip; +} ngx_http_log_buf_t; + + +typedef struct { ngx_array_t *lengths; ngx_array_t *values; } ngx_http_log_script_t; @@ -78,6 +93,17 @@ static ssize_t ngx_http_log_script_write(ngx_http_request_t *r, ngx_http_log_script_t *script, u_char **name, u_char *buf, size_t len); +#if (NGX_ZLIB) +static ssize_t ngx_http_log_gzip(ngx_fd_t fd, u_char *buf, size_t len, + ngx_int_t level, ngx_log_t *log); + +static void *ngx_http_log_gzip_alloc(void *opaque, u_int items, u_int size); +static void ngx_http_log_gzip_free(void *opaque, void *address); +#endif + +static void ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log); +static void ngx_http_log_flush_handler(ngx_event_t *ev); + static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op); static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf, @@ -132,7 +158,7 @@ { ngx_string("access_log"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF - |NGX_HTTP_LMT_CONF|NGX_CONF_TAKE123, + |NGX_HTTP_LMT_CONF|NGX_CONF_1MORE, ngx_http_log_set_log, NGX_HTTP_LOC_CONF_OFFSET, 0, @@ -216,8 +242,8 @@ size_t len; ngx_uint_t i, l; ngx_http_log_t *log; - ngx_open_file_t *file; ngx_http_log_op_t *op; + ngx_http_log_buf_t *buffer; ngx_http_log_loc_conf_t *lcf; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -258,32 +284,40 @@ len += NGX_LINEFEED_SIZE; - file = log[l].file; + buffer = log[l].file ? log[l].file->data : NULL; - if (file && file->buffer) { + if (buffer) { - if (len > (size_t) (file->last - file->pos)) { + if (len > (size_t) (buffer->last - buffer->pos)) { - ngx_http_log_write(r, &log[l], file->buffer, - file->pos - file->buffer); + ngx_http_log_write(r, &log[l], buffer->start, + buffer->pos - buffer->start); - file->pos = file->buffer; + buffer->pos = buffer->start; } - if (len <= (size_t) (file->last - file->pos)) { + if (len <= (size_t) (buffer->last - buffer->pos)) { - p = file->pos; + p = buffer->pos; + if (buffer->event && p == buffer->start) { + ngx_add_timer(buffer->event, buffer->flush); + } + for (i = 0; i < log[l].format->ops->nelts; i++) { p = op[i].run(r, p, &op[i]); } ngx_linefeed(p); - file->pos = p; + buffer->pos = p; continue; } + + if (buffer->event && buffer->event->timer_set) { + ngx_del_timer(buffer->event); + } } line = ngx_pnalloc(r->pool, len); @@ -310,14 +344,29 @@ ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf, size_t len) { - u_char *name; - time_t now; - ssize_t n; - ngx_err_t err; + u_char *name; + time_t now; + ssize_t n; + ngx_err_t err; +#if (NGX_ZLIB) + ngx_http_log_buf_t *buffer; +#endif if (log->script == NULL) { name = log->file->name.data; + +#if (NGX_ZLIB) + buffer = log->file->data; + + if (buffer && buffer->gzip) { + n = ngx_http_log_gzip(log->file->fd, buf, len, buffer->gzip, + r->connection->log); + } else { + n = ngx_write_fd(log->file->fd, buf, len); + } +#else n = ngx_write_fd(log->file->fd, buf, len); +#endif } else { name = NULL; @@ -465,6 +514,194 @@ } +#if (NGX_ZLIB) + +static ssize_t +ngx_http_log_gzip(ngx_fd_t fd, u_char *buf, size_t len, ngx_int_t level, + ngx_log_t *log) +{ + int rc, wbits, memlevel; + u_char *out; + size_t size; + ssize_t n; + z_stream zstream; + ngx_err_t err; + ngx_pool_t *pool; + + wbits = MAX_WBITS; + memlevel = MAX_MEM_LEVEL - 1; + + while ((ssize_t) len < ((1 << (wbits - 1)) - 262)) { + wbits--; + memlevel--; + } + + /* + * This is a formula from deflateBound() for conservative upper bound of + * compressed data plus 18 bytes of gzip wrapper. + */ + + size = len + ((len + 7) >> 3) + ((len + 63) >> 6) + 5 + 18; + + ngx_memzero(&zstream, sizeof(z_stream)); + + pool = ngx_create_pool(256, log); + if (pool == NULL) { + /* simulate successful logging */ + return len; + } + + pool->log = log; + + zstream.zalloc = ngx_http_log_gzip_alloc; + zstream.zfree = ngx_http_log_gzip_free; + zstream.opaque = pool; + + out = ngx_pnalloc(pool, size); + if (out == NULL) { + goto done; + } + + zstream.next_in = buf; + zstream.avail_in = len; + zstream.next_out = out; + zstream.avail_out = size; + + rc = deflateInit2(&zstream, (int) level, Z_DEFLATED, wbits + 16, memlevel, + Z_DEFAULT_STRATEGY); + + if (rc != Z_OK) { + ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateInit2() failed: %d", rc); + goto done; + } + + ngx_log_debug4(NGX_LOG_DEBUG_HTTP, log, 0, + "deflate in: ni:%p no:%p ai:%ud ao:%ud", + zstream.next_in, zstream.next_out, + zstream.avail_in, zstream.avail_out); + + rc = deflate(&zstream, Z_FINISH); + + if (rc != Z_STREAM_END) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "deflate(Z_FINISH) failed: %d", rc); + goto done; + } + + ngx_log_debug5(NGX_LOG_DEBUG_HTTP, log, 0, + "deflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d", + zstream.next_in, zstream.next_out, + zstream.avail_in, zstream.avail_out, + rc); + + size -= zstream.avail_out; + + rc = deflateEnd(&zstream); + + if (rc != Z_OK) { + ngx_log_error(NGX_LOG_ALERT, log, 0, "deflateEnd() failed: %d", rc); + goto done; + } + + n = ngx_write_fd(fd, out, size); + + if (n != (ssize_t) size) { + err = (n == -1) ? ngx_errno : 0; + + ngx_destroy_pool(pool); + + ngx_set_errno(err); + return -1; + } + +done: + + ngx_destroy_pool(pool); + + /* simulate successful logging */ + return len; +} + + +static void * +ngx_http_log_gzip_alloc(void *opaque, u_int items, u_int size) +{ + ngx_pool_t *pool = opaque; + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pool->log, 0, + "gzip alloc: n:%ud s:%ud", items, size); + + return ngx_palloc(pool, items * size); +} + + +static void +ngx_http_log_gzip_free(void *opaque, void *address) +{ +#if 0 + ngx_pool_t *pool = opaque; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pool->log, 0, "gzip free: %p", address); +#endif +} + +#endif + + +static void +ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log) +{ + size_t len; + ssize_t n; + ngx_http_log_buf_t *buffer; + + buffer = file->data; + + len = buffer->pos - buffer->start; + + if (len == 0) { + return; + } + +#if (NGX_ZLIB) + if (buffer->gzip) { + n = ngx_http_log_gzip(file->fd, buffer->start, len, buffer->gzip, log); + } else { + n = ngx_write_fd(file->fd, buffer->start, len); + } +#else + n = ngx_write_fd(file->fd, buffer->start, len); +#endif + + if (n == -1) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + ngx_write_fd_n " to \"%s\" failed", + file->name.data); + + } else if ((size_t) n != len) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz", + file->name.data, n, len); + } + + buffer->pos = buffer->start; + + if (buffer->event && buffer->event->timer_set) { + ngx_del_timer(buffer->event); + } +} + + +static void +ngx_http_log_flush_handler(ngx_event_t *ev) +{ + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0, + "http log buffer flush handler"); + + ngx_http_log_flush(ev->data, ev->log); +} + + static u_char * ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op) @@ -848,10 +1085,13 @@ { ngx_http_log_loc_conf_t *llcf = conf; - ssize_t buf; + ssize_t size; + ngx_int_t gzip; ngx_uint_t i, n; - ngx_str_t *value, name; + ngx_msec_t flush; + ngx_str_t *value, name, s; ngx_http_log_t *log; + ngx_http_log_buf_t *buffer; ngx_http_log_fmt_t *fmt; ngx_http_log_main_conf_t *lmcf; ngx_http_script_compile_t sc; @@ -936,54 +1176,152 @@ && ngx_strcasecmp(fmt[i].name.data, name.data) == 0) { log->format = &fmt[i]; - goto buffer; + break; } } - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "unknown log format \"%V\"", &name); - return NGX_CONF_ERROR; + if (log->format == NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "unknown log format \"%V\"", &name); + return NGX_CONF_ERROR; + } -buffer: + size = 0; + flush = 0; + gzip = 0; - if (cf->args->nelts == 4) { - if (ngx_strncmp(value[3].data, "buffer=", 7) != 0) { + for (i = 3; i < cf->args->nelts; i++) { + + if (ngx_strncmp(value[i].data, "buffer=", 7) == 0) { + s.len = value[i].len - 7; + s.data = value[i].data + 7; + + size = ngx_parse_size(&s); + + if (size == NGX_ERROR || size == 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid buffer size \"%V\"", &s); + return NGX_CONF_ERROR; + } + + continue; + } + + if (ngx_strncmp(value[i].data, "flush=", 6) == 0) { + s.len = value[i].len - 6; + s.data = value[i].data + 6; + + flush = ngx_parse_time(&s, 0); + + if (flush == (ngx_msec_t) NGX_ERROR || flush == 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid flush time \"%V\"", &s); + return NGX_CONF_ERROR; + } + + continue; + } + + if (ngx_strncmp(value[i].data, "gzip", 4) == 0 + && (value[i].len == 4 || value[i].data[4] == '=')) + { +#if (NGX_ZLIB) + if (size == 0) { + size = 64 * 1024; + } + + if (value[i].len == 4) { + gzip = Z_BEST_SPEED; + continue; + } + + s.len = value[i].len - 5; + s.data = value[i].data + 5; + + gzip = ngx_atoi(s.data, s.len); + + if (gzip < 1 || gzip > 9) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid compression level \"%V\"", &s); + return NGX_CONF_ERROR; + } + + continue; + +#else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid parameter \"%V\"", &value[3]); + "nginx was built without zlib support"); return NGX_CONF_ERROR; +#endif } + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + if (flush && size == 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "no buffer is defined for access_log \"%V\"", + &value[1]); + return NGX_CONF_ERROR; + } + + if (size) { + if (log->script) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "buffered logs cannot have variables in name"); return NGX_CONF_ERROR; } - name.len = value[3].len - 7; - name.data = value[3].data + 7; + if (log->file->data) { + buffer = log->file->data; - buf = ngx_parse_size(&name); + if (buffer->last - buffer->start != size + || buffer->flush != flush + || buffer->gzip != gzip) + { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "access_log \"%V\" already defined " + "with conflicting parameters", + &value[1]); + return NGX_CONF_ERROR; + } - if (buf == NGX_ERROR) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "invalid buffer value \"%V\"", &name); - return NGX_CONF_ERROR; + return NGX_CONF_OK; } - if (log->file->buffer && log->file->last - log->file->pos != buf) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "access_log \"%V\" already defined " - "with different buffer size", &value[1]); + buffer = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_buf_t)); + if (buffer == NULL) { return NGX_CONF_ERROR; } - log->file->buffer = ngx_palloc(cf->pool, buf); - if (log->file->buffer == NULL) { + buffer->start = ngx_pnalloc(cf->pool, size); + if (buffer->start == NULL) { return NGX_CONF_ERROR; } - log->file->pos = log->file->buffer; - log->file->last = log->file->buffer + buf; + buffer->pos = buffer->start; + buffer->last = buffer->start + size; + + if (flush) { + buffer->event = ngx_pcalloc(cf->pool, sizeof(ngx_event_t)); + if (buffer->event == NULL) { + return NGX_CONF_ERROR; + } + + buffer->event->data = log->file; + buffer->event->handler = ngx_http_log_flush_handler; + buffer->event->log = &cf->cycle->new_log; + + buffer->flush = flush; + } + + buffer->gzip = gzip; + + log->file->flush = ngx_http_log_flush; + log->file->data = buffer; } return NGX_CONF_OK; From mdounin at mdounin.ru Mon Feb 11 14:39:50 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 14:39:50 +0000 Subject: [nginx] svn commit: r5055 - in branches/stable-1.2: . src/http src/http/modules Message-ID: <20130211143950.25C7B3F9F78@mail.nginx.com> Author: mdounin Date: 2013-02-11 14:39:49 +0000 (Mon, 11 Feb 2013) New Revision: 5055 URL: http://trac.nginx.org/nginx/changeset/5055/nginx Log: Merge of r4991: fixed proxied HEAD requests with gzip enabled. Fixed HEAD requests handling when proxying is used (ticket #261). Modified: branches/stable-1.2/ branches/stable-1.2/src/http/modules/ngx_http_gzip_filter_module.c branches/stable-1.2/src/http/ngx_http_upstream.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 14:34:00 UTC (rev 5054) +++ branches/stable-1.2 2013-02-11 14:39:49 UTC (rev 5055) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4990,4993-4994,4997,5000,5002,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4991,4993-4994,4997,5000,5002,5011 \ No newline at end of property Modified: branches/stable-1.2/src/http/modules/ngx_http_gzip_filter_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_gzip_filter_module.c 2013-02-11 14:34:00 UTC (rev 5054) +++ branches/stable-1.2/src/http/modules/ngx_http_gzip_filter_module.c 2013-02-11 14:39:49 UTC (rev 5055) @@ -320,7 +320,7 @@ ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module); - if (ctx == NULL || ctx->done) { + if (ctx == NULL || ctx->done || r->header_only) { return ngx_http_next_body_filter(r, in); } Modified: branches/stable-1.2/src/http/ngx_http_upstream.c =================================================================== --- branches/stable-1.2/src/http/ngx_http_upstream.c 2013-02-11 14:34:00 UTC (rev 5054) +++ branches/stable-1.2/src/http/ngx_http_upstream.c 2013-02-11 14:39:49 UTC (rev 5055) @@ -3099,6 +3099,7 @@ r->connection->log->action = "sending to client"; if (rc == 0 + && !r->header_only #if (NGX_HTTP_CACHE) && !r->cached #endif From mdounin at mdounin.ru Mon Feb 11 14:56:16 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 14:56:16 +0000 Subject: [nginx] svn commit: r5056 - in branches/stable-1.2: . src/http src/http/modules Message-ID: <20130211145616.5C2BA3F9FC0@mail.nginx.com> Author: mdounin Date: 2013-02-11 14:56:14 +0000 (Mon, 11 Feb 2013) New Revision: 5056 URL: http://trac.nginx.org/nginx/changeset/5056/nginx Log: Merge of r4992: off-by-one with 32/64 upstream backup servers. Fixed off-by-one during upstream state resetting when switching to backup servers if there were exactly 32 (64 on 64-bit platforms) backup servers configured. Based on patch by Thomas Chen (ticket #257). Modified: branches/stable-1.2/ branches/stable-1.2/src/http/modules/ngx_http_upstream_least_conn_module.c branches/stable-1.2/src/http/ngx_http_upstream_round_robin.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 14:39:49 UTC (rev 5055) +++ branches/stable-1.2 2013-02-11 14:56:14 UTC (rev 5056) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4991,4993-4994,4997,5000,5002,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,5000,5002,5011 \ No newline at end of property Modified: branches/stable-1.2/src/http/modules/ngx_http_upstream_least_conn_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_upstream_least_conn_module.c 2013-02-11 14:39:49 UTC (rev 5055) +++ branches/stable-1.2/src/http/modules/ngx_http_upstream_least_conn_module.c 2013-02-11 14:56:14 UTC (rev 5056) @@ -313,7 +313,9 @@ lcp->rrp.peers = peers->next; pc->tries = lcp->rrp.peers->number; - n = lcp->rrp.peers->number / (8 * sizeof(uintptr_t)) + 1; + n = (lcp->rrp.peers->number + (8 * sizeof(uintptr_t) - 1)) + / (8 * sizeof(uintptr_t)); + for (i = 0; i < n; i++) { lcp->rrp.tried[i] = 0; } Modified: branches/stable-1.2/src/http/ngx_http_upstream_round_robin.c =================================================================== --- branches/stable-1.2/src/http/ngx_http_upstream_round_robin.c 2013-02-11 14:39:49 UTC (rev 5055) +++ branches/stable-1.2/src/http/ngx_http_upstream_round_robin.c 2013-02-11 14:56:14 UTC (rev 5056) @@ -474,7 +474,9 @@ rrp->peers = peers->next; pc->tries = rrp->peers->number; - n = rrp->peers->number / (8 * sizeof(uintptr_t)) + 1; + n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1)) + / (8 * sizeof(uintptr_t)); + for (i = 0; i < n; i++) { rrp->tried[i] = 0; } From mdounin at mdounin.ru Mon Feb 11 14:58:25 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 14:58:25 +0000 Subject: [nginx] svn commit: r5057 - in branches/stable-1.2: . src/event src/http/modules Message-ID: <20130211145825.B69453FAA38@mail.nginx.com> Author: mdounin Date: 2013-02-11 14:58:25 +0000 (Mon, 11 Feb 2013) New Revision: 5057 URL: http://trac.nginx.org/nginx/changeset/5057/nginx Log: Merge of r4999, r5003: detect duplicate "events" and "keepalive". *) Upstream keepalive: detect duplicate "keepalive" directive. A failure to detect duplicate "keepalive" directive resulted in stack exhaustion. *) Events: added check for duplicate "events" directive. Modified: branches/stable-1.2/ branches/stable-1.2/src/event/ngx_event.c branches/stable-1.2/src/http/modules/ngx_http_upstream_keepalive_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 14:56:14 UTC (rev 5056) +++ branches/stable-1.2 2013-02-11 14:58:25 UTC (rev 5057) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,5000,5002,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5000,5002-5003,5011 \ No newline at end of property Modified: branches/stable-1.2/src/event/ngx_event.c =================================================================== --- branches/stable-1.2/src/event/ngx_event.c 2013-02-11 14:56:14 UTC (rev 5056) +++ branches/stable-1.2/src/event/ngx_event.c 2013-02-11 14:58:25 UTC (rev 5057) @@ -892,6 +892,10 @@ ngx_conf_t pcf; ngx_event_module_t *m; + if (*(void **) conf) { + return "is duplicate"; + } + /* count the number of the event modules and set up their indices */ ngx_event_max_module = 0; Modified: branches/stable-1.2/src/http/modules/ngx_http_upstream_keepalive_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_upstream_keepalive_module.c 2013-02-11 14:56:14 UTC (rev 5056) +++ branches/stable-1.2/src/http/modules/ngx_http_upstream_keepalive_module.c 2013-02-11 14:58:25 UTC (rev 5057) @@ -502,6 +502,10 @@ kcf = ngx_http_conf_upstream_srv_conf(uscf, ngx_http_upstream_keepalive_module); + if (kcf->original_init_upstream) { + return "is duplicate"; + } + kcf->original_init_upstream = uscf->peer.init_upstream ? uscf->peer.init_upstream : ngx_http_upstream_init_round_robin; From mdounin at mdounin.ru Mon Feb 11 15:00:43 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 15:00:43 +0000 Subject: [nginx] svn commit: r5058 - in branches/stable-1.2: . docs/man docs/text Message-ID: <20130211150043.B1CCE3FA030@mail.nginx.com> Author: mdounin Date: 2013-02-11 15:00:43 +0000 (Mon, 11 Feb 2013) New Revision: 5058 URL: http://trac.nginx.org/nginx/changeset/5058/nginx Log: Merge of r5001: year 2013. Modified: branches/stable-1.2/ branches/stable-1.2/docs/man/nginx.8 branches/stable-1.2/docs/text/LICENSE Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 14:58:25 UTC (rev 5057) +++ branches/stable-1.2 2013-02-11 15:00:43 UTC (rev 5058) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5000,5002-5003,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5003,5011 \ No newline at end of property Modified: branches/stable-1.2/docs/man/nginx.8 =================================================================== --- branches/stable-1.2/docs/man/nginx.8 2013-02-11 14:58:25 UTC (rev 5057) +++ branches/stable-1.2/docs/man/nginx.8 2013-02-11 15:00:43 UTC (rev 5058) @@ -1,6 +1,6 @@ .\" -.\" Copyright (c) 2010 Sergey A. Osokin -.\" Copyright (c) 2011,2012 Nginx, Inc. +.\" Copyright (C) 2010 Sergey A. Osokin +.\" Copyright (C) Nginx, Inc. .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without Modified: branches/stable-1.2/docs/text/LICENSE =================================================================== --- branches/stable-1.2/docs/text/LICENSE 2013-02-11 14:58:25 UTC (rev 5057) +++ branches/stable-1.2/docs/text/LICENSE 2013-02-11 15:00:43 UTC (rev 5058) @@ -1,6 +1,6 @@ /* - * Copyright (C) 2002-2012 Igor Sysoev - * Copyright (C) 2011,2012 Nginx, Inc. + * Copyright (C) 2002-2013 Igor Sysoev + * Copyright (C) 2011-2013 Nginx, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without From mdounin at mdounin.ru Mon Feb 11 15:12:06 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 15:12:06 +0000 Subject: [nginx] svn commit: r5059 - in branches/stable-1.2: . src/event Message-ID: <20130211151206.6DD533F9C0F@mail.nginx.com> Author: mdounin Date: 2013-02-11 15:12:06 +0000 (Mon, 11 Feb 2013) New Revision: 5059 URL: http://trac.nginx.org/nginx/changeset/5059/nginx Log: Merge of r5004, r5019-r5025: ssl fixes. *) SSL: speedup loading of configs with many ssl servers. The patch saves one EC_KEY_generate_key() call per server{} block by informing OpenSSL about SSL_OP_SINGLE_ECDH_USE we are going to use before the SSL_CTX_set_tmp_ecdh() call. For a configuration file with 10k simple server{} blocks with SSL enabled this change reduces startup time from 18s to 5s on a slow test box here. *) SSL: removed conditions that always hold true. *) SSL: resetting of flush flag after the data was written. There is no need to flush next chunk of data if it does not contain a buffer with the flush or last_buf flags set. *) SSL: preservation of flush flag for buffered data. Previously, if SSL buffer was not sent we lost information that the data must be flushed. *) SSL: calculation of buffer size moved closer to its usage. No functional changes. *) SSL: avoid calling SSL_write() with zero data size. According to documentation, calling SSL_write() with num=0 bytes to be sent results in undefined behavior. We don't currently call ngx_ssl_send_chain() with empty chain and buffer. This check handles the case of a chain with total data size that is a multiple of NGX_SSL_BUFSIZE, and with the special buffer at the end. In practice such cases resulted in premature connection close and critical error "SSL_write() failed (SSL:)" in the error log. *) SSL: take into account data in the buffer while limiting output. In some rare cases this can result in a more smooth sending rate. *) SSL: fixed ngx_ssl_handshake() with level-triggered event methods. Missing calls to ngx_handle_write_event() and ngx_handle_read_event() resulted in a CPU hog during SSL handshake if an level-triggered event method (e.g. select) was used. Modified: branches/stable-1.2/ branches/stable-1.2/src/event/ngx_event_openssl.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 15:00:43 UTC (rev 5058) +++ branches/stable-1.2 2013-02-11 15:12:06 UTC (rev 5059) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5003,5011 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5004,5011,5019-5025 \ No newline at end of property Modified: branches/stable-1.2/src/event/ngx_event_openssl.c =================================================================== --- branches/stable-1.2/src/event/ngx_event_openssl.c 2013-02-11 15:00:43 UTC (rev 5058) +++ branches/stable-1.2/src/event/ngx_event_openssl.c 2013-02-11 15:12:06 UTC (rev 5059) @@ -528,10 +528,10 @@ return NGX_ERROR; } + SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE); + SSL_CTX_set_tmp_ecdh(ssl->ctx, ecdh); - SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_ECDH_USE); - EC_KEY_free(ecdh); #endif #endif @@ -693,6 +693,10 @@ return NGX_ERROR; } + if (ngx_handle_write_event(c->write, 0) != NGX_OK) { + return NGX_ERROR; + } + return NGX_AGAIN; } @@ -701,6 +705,10 @@ c->read->handler = ngx_ssl_handshake_handler; c->write->handler = ngx_ssl_handshake_handler; + if (ngx_handle_read_event(c->read, 0) != NGX_OK) { + return NGX_ERROR; + } + if (ngx_handle_write_event(c->write, 0) != NGX_OK) { return NGX_ERROR; } @@ -1053,8 +1061,8 @@ buf->end = buf->start + NGX_SSL_BUFSIZE; } - send = 0; - flush = (in == NULL) ? 1 : 0; + send = buf->last - buf->pos; + flush = (in == NULL) ? 1 : buf->flush; for ( ;; ) { @@ -1076,7 +1084,6 @@ if (send + size > limit) { size = (ssize_t) (limit - send); - flush = 1; } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, @@ -1093,10 +1100,16 @@ } } + if (!flush && send < limit && buf->last < buf->end) { + break; + } + size = buf->last - buf->pos; - if (!flush && buf->last < buf->end && c->ssl->buffer) { - break; + if (size == 0) { + buf->flush = 0; + c->buffered &= ~NGX_SSL_BUFFERED; + return in; } n = ngx_ssl_write(c, buf->pos, size); @@ -1106,8 +1119,7 @@ } if (n == NGX_AGAIN) { - c->buffered |= NGX_SSL_BUFFERED; - return in; + break; } buf->pos += n; @@ -1117,16 +1129,18 @@ break; } - if (buf->pos == buf->last) { - buf->pos = buf->start; - buf->last = buf->start; - } + flush = 0; + buf->pos = buf->start; + buf->last = buf->start; + if (in == NULL || send == limit) { break; } } + buf->flush = flush; + if (buf->pos < buf->last) { c->buffered |= NGX_SSL_BUFFERED; From mdounin at mdounin.ru Mon Feb 11 15:28:51 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 15:28:51 +0000 Subject: [nginx] svn commit: r5060 - in branches/stable-1.2: . auto/cc Message-ID: <20130211152851.ED1E03F9C5F@mail.nginx.com> Author: mdounin Date: 2013-02-11 15:28:50 +0000 (Mon, 11 Feb 2013) New Revision: 5060 URL: http://trac.nginx.org/nginx/changeset/5060/nginx Log: Merge of r5012: configure: removed redundant variable assignment. Modified: branches/stable-1.2/ branches/stable-1.2/auto/cc/msvc Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 15:12:06 UTC (rev 5059) +++ branches/stable-1.2 2013-02-11 15:28:50 UTC (rev 5060) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5004,5011,5019-5025 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5004,5011-5012,5019-5025 \ No newline at end of property Modified: branches/stable-1.2/auto/cc/msvc =================================================================== --- branches/stable-1.2/auto/cc/msvc 2013-02-11 15:12:06 UTC (rev 5059) +++ branches/stable-1.2/auto/cc/msvc 2013-02-11 15:28:50 UTC (rev 5060) @@ -73,9 +73,6 @@ # disable logo CFLAGS="$CFLAGS -nologo" - -LINK="\$(CC)" - # the link flags CORE_LINK="$CORE_LINK -link -verbose:lib" From mdounin at mdounin.ru Mon Feb 11 15:31:10 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 15:31:10 +0000 Subject: [nginx] svn commit: r5061 - in branches/stable-1.2: . src/http/modules Message-ID: <20130211153110.B321C3F9EA7@mail.nginx.com> Author: mdounin Date: 2013-02-11 15:31:10 +0000 (Mon, 11 Feb 2013) New Revision: 5061 URL: http://trac.nginx.org/nginx/changeset/5061/nginx Log: Merge of r5013: proxy: fixed proxy_method to always add space. Before the patch if proxy_method was specified at http{} level the code to add trailing space wasn't executed, resulting in incorrect requests to upstream. Modified: branches/stable-1.2/ branches/stable-1.2/src/http/modules/ngx_http_proxy_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 15:28:50 UTC (rev 5060) +++ branches/stable-1.2 2013-02-11 15:31:10 UTC (rev 5061) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5004,5011-5012,5019-5025 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5004,5011-5013,5019-5025 \ No newline at end of property Modified: branches/stable-1.2/src/http/modules/ngx_http_proxy_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_proxy_module.c 2013-02-11 15:28:50 UTC (rev 5060) +++ branches/stable-1.2/src/http/modules/ngx_http_proxy_module.c 2013-02-11 15:31:10 UTC (rev 5061) @@ -2608,7 +2608,7 @@ * conf->upstream.store_lengths = NULL; * conf->upstream.store_values = NULL; * - * conf->method = NULL; + * conf->method = { 0, NULL }; * conf->headers_source = NULL; * conf->headers_set_len = NULL; * conf->headers_set = NULL; @@ -2907,10 +2907,11 @@ #endif - if (conf->method.len == 0) { - conf->method = prev->method; + ngx_conf_merge_str_value(conf->method, prev->method, ""); - } else { + if (conf->method.len + && conf->method.data[conf->method.len - 1] != ' ') + { conf->method.data[conf->method.len] = ' '; conf->method.len++; } From mdounin at mdounin.ru Mon Feb 11 15:34:30 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 15:34:30 +0000 Subject: [nginx] svn commit: r5062 - in branches/stable-1.2: . auto/lib/geoip auto/lib/libgd src/http/modules Message-ID: <20130211153430.F2C193F9C0F@mail.nginx.com> Author: mdounin Date: 2013-02-11 15:34:30 +0000 (Mon, 11 Feb 2013) New Revision: 5062 URL: http://trac.nginx.org/nginx/changeset/5062/nginx Log: Merge of r5014, r5015, r5016, r5030: geoip ipv6 support. *) Configure: fixed style of include directories. *) Configure: fixed GeoIP library detection. *) GeoIP: IPv6 support. When using IPv6 databases, IPv4 addresses are looked up as IPv4-mapped IPv6 addresses. Mostly based on a patch by Gregor Kali?\197?\161nik (ticket #250). *) GeoIP: removed pseudo-support of "proxy" and "netspeed" databases. Modified: branches/stable-1.2/ branches/stable-1.2/auto/lib/geoip/conf branches/stable-1.2/auto/lib/libgd/conf branches/stable-1.2/src/http/modules/ngx_http_geoip_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 15:31:10 UTC (rev 5061) +++ branches/stable-1.2 2013-02-11 15:34:30 UTC (rev 5062) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5004,5011-5013,5019-5025 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5004,5011-5016,5019-5025,5030 \ No newline at end of property Modified: branches/stable-1.2/auto/lib/geoip/conf =================================================================== --- branches/stable-1.2/auto/lib/geoip/conf 2013-02-11 15:31:10 UTC (rev 5061) +++ branches/stable-1.2/auto/lib/geoip/conf 2013-02-11 15:34:30 UTC (rev 5062) @@ -6,7 +6,7 @@ ngx_feature="GeoIP library" ngx_feature_name= ngx_feature_run=no - ngx_feature_incs= + ngx_feature_incs="#include " ngx_feature_path= ngx_feature_libs="-lGeoIP" ngx_feature_test="GeoIP_open(NULL, 0)" @@ -18,6 +18,7 @@ # FreeBSD port ngx_feature="GeoIP library in /usr/local/" + ngx_feature_path="/usr/local/include" if [ $NGX_RPATH = YES ]; then ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lGeoIP" @@ -34,7 +35,7 @@ # NetBSD port ngx_feature="GeoIP library in /usr/pkg/" - ngx_feature_path="/usr/pkg/include/" + ngx_feature_path="/usr/pkg/include" if [ $NGX_RPATH = YES ]; then ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lGeoIP" @@ -64,8 +65,22 @@ if [ $ngx_found = yes ]; then + + CORE_INCS="$CORE_INCS $ngx_feature_path" CORE_LIBS="$CORE_LIBS $ngx_feature_libs" + if [ $NGX_IPV6 = YES ]; then + ngx_feature="GeoIP IPv6 support" + ngx_feature_name="NGX_HAVE_GEOIP_V6" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + #ngx_feature_path= + #ngx_feature_libs= + ngx_feature_test="printf(\"%d\", GEOIP_CITY_EDITION_REV0_V6);" + . auto/feature + fi + else cat << END Modified: branches/stable-1.2/auto/lib/libgd/conf =================================================================== --- branches/stable-1.2/auto/lib/libgd/conf 2013-02-11 15:31:10 UTC (rev 5061) +++ branches/stable-1.2/auto/lib/libgd/conf 2013-02-11 15:34:30 UTC (rev 5062) @@ -35,7 +35,7 @@ # NetBSD port ngx_feature="GD library in /usr/pkg/" - ngx_feature_path="/usr/pkg/include/" + ngx_feature_path="/usr/pkg/include" if [ $NGX_RPATH = YES ]; then ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lgd" Modified: branches/stable-1.2/src/http/modules/ngx_http_geoip_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_geoip_module.c 2013-02-11 15:31:10 UTC (rev 5061) +++ branches/stable-1.2/src/http/modules/ngx_http_geoip_module.c 2013-02-11 15:34:30 UTC (rev 5062) @@ -13,12 +13,22 @@ #include +#define NGX_GEOIP_COUNTRY_CODE 0 +#define NGX_GEOIP_COUNTRY_CODE3 1 +#define NGX_GEOIP_COUNTRY_NAME 2 + + typedef struct { GeoIP *country; GeoIP *org; GeoIP *city; ngx_array_t *proxies; /* array of ngx_cidr_t */ ngx_flag_t proxy_recursive; +#if (NGX_HAVE_GEOIP_V6) + unsigned country_v6:1; + unsigned org_v6:1; + unsigned city_v6:1; +#endif } ngx_http_geoip_conf_t; @@ -28,10 +38,32 @@ } ngx_http_geoip_var_t; -typedef char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, u_long addr); +typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, + u_long addr); -static u_long ngx_http_geoip_addr(ngx_http_request_t *r, - ngx_http_geoip_conf_t *gcf); + +ngx_http_geoip_variable_handler_pt ngx_http_geoip_country_functions[] = { + GeoIP_country_code_by_ipnum, + GeoIP_country_code3_by_ipnum, + GeoIP_country_name_by_ipnum, +}; + + +#if (NGX_HAVE_GEOIP_V6) + +typedef const char *(*ngx_http_geoip_variable_handler_v6_pt)(GeoIP *, + geoipv6_t addr); + + +ngx_http_geoip_variable_handler_v6_pt ngx_http_geoip_country_v6_functions[] = { + GeoIP_country_code_by_ipnum_v6, + GeoIP_country_code3_by_ipnum_v6, + GeoIP_country_name_by_ipnum_v6, +}; + +#endif + + static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_geoip_org_variable(ngx_http_request_t *r, @@ -138,19 +170,19 @@ { ngx_string("geoip_country_code"), NULL, ngx_http_geoip_country_variable, - (uintptr_t) GeoIP_country_code_by_ipnum, 0, 0 }, + NGX_GEOIP_COUNTRY_CODE, 0, 0 }, { ngx_string("geoip_country_code3"), NULL, ngx_http_geoip_country_variable, - (uintptr_t) GeoIP_country_code3_by_ipnum, 0, 0 }, + NGX_GEOIP_COUNTRY_CODE3, 0, 0 }, { ngx_string("geoip_country_name"), NULL, ngx_http_geoip_country_variable, - (uintptr_t) GeoIP_country_name_by_ipnum, 0, 0 }, + NGX_GEOIP_COUNTRY_NAME, 0, 0 }, { ngx_string("geoip_org"), NULL, ngx_http_geoip_org_variable, - (uintptr_t) GeoIP_name_by_ipnum, 0, 0 }, + 0, 0, 0 }, { ngx_string("geoip_city_continent_code"), NULL, ngx_http_geoip_city_variable, @@ -255,12 +287,68 @@ } +#if (NGX_HAVE_GEOIP_V6) + +static geoipv6_t +ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf) +{ + ngx_addr_t addr; + ngx_table_elt_t *xfwd; + in_addr_t addr4; + struct in6_addr addr6; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + + addr.sockaddr = r->connection->sockaddr; + addr.socklen = r->connection->socklen; + /* addr.name = r->connection->addr_text; */ + + xfwd = r->headers_in.x_forwarded_for; + + if (xfwd != NULL && gcf->proxies != NULL) { + (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data, + xfwd->value.len, gcf->proxies, + gcf->proxy_recursive); + } + + switch (addr.sockaddr->sa_family) { + + case AF_INET: + /* Produce IPv4-mapped IPv6 address. */ + sin = (struct sockaddr_in *) addr.sockaddr; + addr4 = ntohl(sin->sin_addr.s_addr); + + ngx_memzero(&addr6, sizeof(struct in6_addr)); + addr6.s6_addr[10] = 0xff; + addr6.s6_addr[11] = 0xff; + addr6.s6_addr[12] = addr4 >> 24; + addr6.s6_addr[13] = addr4 >> 16; + addr6.s6_addr[14] = addr4 >> 8; + addr6.s6_addr[15] = addr4; + return addr6; + + case AF_INET6: + sin6 = (struct sockaddr_in6 *) addr.sockaddr; + return sin6->sin6_addr; + + default: + return in6addr_any; + } +} + +#endif + + static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - ngx_http_geoip_variable_handler_pt handler = - (ngx_http_geoip_variable_handler_pt) data; + ngx_http_geoip_variable_handler_pt handler = + ngx_http_geoip_country_functions[data]; +#if (NGX_HAVE_GEOIP_V6) + ngx_http_geoip_variable_handler_v6_pt handler_v6 = + ngx_http_geoip_country_v6_functions[data]; +#endif const char *val; ngx_http_geoip_conf_t *gcf; @@ -271,7 +359,13 @@ goto not_found; } +#if (NGX_HAVE_GEOIP_V6) + val = gcf->country_v6 + ? handler_v6(gcf->country, ngx_http_geoip_addr_v6(r, gcf)) + : handler(gcf->country, ngx_http_geoip_addr(r, gcf)); +#else val = handler(gcf->country, ngx_http_geoip_addr(r, gcf)); +#endif if (val == NULL) { goto not_found; @@ -297,9 +391,6 @@ ngx_http_geoip_org_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - ngx_http_geoip_variable_handler_pt handler = - (ngx_http_geoip_variable_handler_pt) data; - size_t len; char *val; ngx_http_geoip_conf_t *gcf; @@ -310,7 +401,15 @@ goto not_found; } - val = handler(gcf->org, ngx_http_geoip_addr(r, gcf)); +#if (NGX_HAVE_GEOIP_V6) + val = gcf->org_v6 + ? GeoIP_name_by_ipnum_v6(gcf->org, + ngx_http_geoip_addr_v6(r, gcf)) + : GeoIP_name_by_ipnum(gcf->org, + ngx_http_geoip_addr(r, gcf)); +#else + val = GeoIP_name_by_ipnum(gcf->org, ngx_http_geoip_addr(r, gcf)); +#endif if (val == NULL) { goto not_found; @@ -500,7 +599,15 @@ gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); if (gcf->city) { +#if (NGX_HAVE_GEOIP_V6) + return gcf->city_v6 + ? GeoIP_record_by_ipnum_v6(gcf->city, + ngx_http_geoip_addr_v6(r, gcf)) + : GeoIP_record_by_ipnum(gcf->city, + ngx_http_geoip_addr(r, gcf)); +#else return GeoIP_record_by_ipnum(gcf->city, ngx_http_geoip_addr(r, gcf)); +#endif } return NULL; @@ -598,11 +705,16 @@ switch (gcf->country->databaseType) { case GEOIP_COUNTRY_EDITION: - case GEOIP_PROXY_EDITION: - case GEOIP_NETSPEED_EDITION: return NGX_CONF_OK; +#if (NGX_HAVE_GEOIP_V6) + case GEOIP_COUNTRY_EDITION_V6: + + gcf->country_v6 = 1; + return NGX_CONF_OK; +#endif + default: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid GeoIP database \"%V\" type:%d", @@ -654,6 +766,16 @@ return NGX_CONF_OK; +#if (NGX_HAVE_GEOIP_V6) + case GEOIP_ISP_EDITION_V6: + case GEOIP_ORG_EDITION_V6: + case GEOIP_DOMAIN_EDITION_V6: + case GEOIP_ASNUM_EDITION_V6: + + gcf->org_v6 = 1; + return NGX_CONF_OK; +#endif + default: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid GeoIP database \"%V\" type:%d", @@ -703,6 +825,14 @@ return NGX_CONF_OK; +#if (NGX_HAVE_GEOIP_V6) + case GEOIP_CITY_EDITION_REV0_V6: + case GEOIP_CITY_EDITION_REV1_V6: + + gcf->city_v6 = 1; + return NGX_CONF_OK; +#endif + default: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid GeoIP City database \"%V\" type:%d", From mdounin at mdounin.ru Mon Feb 11 16:06:40 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 16:06:40 +0000 Subject: [nginx] svn commit: r5063 - in branches/stable-1.2: . src/event/modules Message-ID: <20130211160640.1C2E53F9FCD@mail.nginx.com> Author: mdounin Date: 2013-02-11 16:06:39 +0000 (Mon, 11 Feb 2013) New Revision: 5063 URL: http://trac.nginx.org/nginx/changeset/5063/nginx Log: Merge of r5017: fixed null dereference with resolver and poll. Events: fixed null pointer dereference with resolver and poll. A POLLERR signalled by poll() without POLLIN/POLLOUT, as seen on Linux, would generate both read and write events, but there's no write event handler for resolver events. A fix is to only call event handler of an active event. Modified: branches/stable-1.2/ branches/stable-1.2/src/event/modules/ngx_poll_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 15:34:30 UTC (rev 5062) +++ branches/stable-1.2 2013-02-11 16:06:39 UTC (rev 5063) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5004,5011-5016,5019-5025,5030 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5004,5011-5017,5019-5025,5030 \ No newline at end of property Modified: branches/stable-1.2/src/event/modules/ngx_poll_module.c =================================================================== --- branches/stable-1.2/src/event/modules/ngx_poll_module.c 2013-02-11 15:34:30 UTC (rev 5062) +++ branches/stable-1.2/src/event/modules/ngx_poll_module.c 2013-02-11 16:06:39 UTC (rev 5063) @@ -371,7 +371,7 @@ found = 0; - if (revents & POLLIN) { + if ((revents & POLLIN) && c->read->active) { found = 1; ev = c->read; @@ -388,7 +388,7 @@ ngx_locked_post_event(ev, queue); } - if (revents & POLLOUT) { + if ((revents & POLLOUT) && c->write->active) { found = 1; ev = c->write; From mdounin at mdounin.ru Mon Feb 11 16:09:36 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 16:09:36 +0000 Subject: [nginx] svn commit: r5064 - in branches/stable-1.2: . src/http/modules Message-ID: <20130211160936.48F8D3F9FE9@mail.nginx.com> Author: mdounin Date: 2013-02-11 16:09:35 +0000 (Mon, 11 Feb 2013) New Revision: 5064 URL: http://trac.nginx.org/nginx/changeset/5064/nginx Log: Merge of r5018: secure link: fixed configuration inheritance. The "secure_link_secret" directive was always inherited from the outer configuration level even when "secure_link" and "secure_link_md5" were specified on the inner level. Modified: branches/stable-1.2/ branches/stable-1.2/src/http/modules/ngx_http_secure_link_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 16:06:39 UTC (rev 5063) +++ branches/stable-1.2 2013-02-11 16:09:35 UTC (rev 5064) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5004,5011-5017,5019-5025,5030 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5004,5011-5025,5030 \ No newline at end of property Modified: branches/stable-1.2/src/http/modules/ngx_http_secure_link_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_secure_link_module.c 2013-02-11 16:06:39 UTC (rev 5063) +++ branches/stable-1.2/src/http/modules/ngx_http_secure_link_module.c 2013-02-11 16:09:35 UTC (rev 5064) @@ -111,7 +111,7 @@ conf = ngx_http_get_module_loc_conf(r, ngx_http_secure_link_module); - if (conf->secret.len) { + if (conf->secret.data) { return ngx_http_secure_link_old_variable(r, conf, v, data); } @@ -318,8 +318,17 @@ ngx_http_secure_link_conf_t *prev = parent; ngx_http_secure_link_conf_t *conf = child; - ngx_conf_merge_str_value(conf->secret, prev->secret, ""); + if (conf->secret.data) { + if (conf->variable || conf->md5) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"secure_link_secret\" cannot be mixed with " + "\"secure_link\" and \"secure_link_md5\""); + return NGX_CONF_ERROR; + } + return NGX_CONF_OK; + } + if (conf->variable == NULL) { conf->variable = prev->variable; } @@ -328,6 +337,10 @@ conf->md5 = prev->md5; } + if (conf->variable == NULL && conf->md5 == NULL) { + conf->secret = prev->secret; + } + return NGX_CONF_OK; } From mdounin at mdounin.ru Mon Feb 11 16:11:18 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 16:11:18 +0000 Subject: [nginx] svn commit: r5065 - in branches/stable-1.2: . src/http/modules Message-ID: <20130211161119.020AE3F9C18@mail.nginx.com> Author: mdounin Date: 2013-02-11 16:11:14 +0000 (Mon, 11 Feb 2013) New Revision: 5065 URL: http://trac.nginx.org/nginx/changeset/5065/nginx Log: Merge of r5027, r5028, r5029: fastcgi_keep_conn fixes. *) FastCGI: fixed wrong connection close with fastcgi_keep_conn. With fastcgi_keep_conn it was possible that connection was closed after FCGI_STDERR record with zero padding and without any further data read yet. This happended as f->state was set to ngx_http_fastcgi_st_padding and then "break" happened, resulting in p->length being set to f->padding, i.e. 0 (which in turn resulted in connection close). Fix is to make sure we continue the loop after f->state is set. *) FastCGI: unconditional state transitions. Checks for f->padding before state transitions make code hard to follow, remove them and make sure we always do another loop iteration after f->state is set to ngx_http_fastcgi_st_padding. *) FastCGI: proper handling of split fastcgi end request. If fastcgi end request record was split between several network packets, with fastcgi_keep_conn it was possible that connection was saved in incorrect state (e.g. with padding bytes not yet read). Modified: branches/stable-1.2/ branches/stable-1.2/src/http/modules/ngx_http_fastcgi_module.c Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 16:09:35 UTC (rev 5064) +++ branches/stable-1.2 2013-02-11 16:11:14 UTC (rev 5065) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5004,5011-5025,5030 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5004,5011-5025,5027-5030 \ No newline at end of property Modified: branches/stable-1.2/src/http/modules/ngx_http_fastcgi_module.c =================================================================== --- branches/stable-1.2/src/http/modules/ngx_http_fastcgi_module.c 2013-02-11 16:09:35 UTC (rev 5064) +++ branches/stable-1.2/src/http/modules/ngx_http_fastcgi_module.c 2013-02-11 16:11:14 UTC (rev 5065) @@ -1356,11 +1356,7 @@ } } else { - if (f->padding) { - f->state = ngx_http_fastcgi_st_padding; - } else { - f->state = ngx_http_fastcgi_st_version; - } + f->state = ngx_http_fastcgi_st_padding; } continue; @@ -1597,11 +1593,7 @@ f->length -= u->buffer.pos - start; if (f->length == 0) { - if (f->padding) { - f->state = ngx_http_fastcgi_st_padding; - } else { - f->state = ngx_http_fastcgi_st_version; - } + f->state = ngx_http_fastcgi_st_padding; } if (rc == NGX_HTTP_PARSE_HEADER_DONE) { @@ -1696,13 +1688,8 @@ } if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) { + f->state = ngx_http_fastcgi_st_padding; - if (f->padding) { - f->state = ngx_http_fastcgi_st_padding; - } else { - f->state = ngx_http_fastcgi_st_version; - } - if (!flcf->keep_conn) { p->upstream_done = 1; } @@ -1715,28 +1702,39 @@ if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) { - if (f->padding) { - f->state = ngx_http_fastcgi_st_padding; - } else { - f->state = ngx_http_fastcgi_st_version; + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0, + "http fastcgi sent end request"); + + if (!flcf->keep_conn) { + p->upstream_done = 1; + break; } - p->upstream_done = 1; + continue; + } + } - if (flcf->keep_conn) { + + if (f->state == ngx_http_fastcgi_st_padding) { + + if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) { + + if (f->pos + f->padding < f->last) { + p->upstream_done = 1; + break; + } + + if (f->pos + f->padding == f->last) { + p->upstream_done = 1; r->upstream->keepalive = 1; + break; } - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0, - "http fastcgi sent end request"); + f->padding -= f->last - f->pos; break; } - } - - if (f->state == ngx_http_fastcgi_st_padding) { - if (f->pos + f->padding < f->last) { f->state = ngx_http_fastcgi_st_version; f->pos += f->padding; @@ -1788,22 +1786,28 @@ "FastCGI sent in stderr: \"%*s\"", m + 1 - msg, msg); - if (f->pos == f->last) { - break; - } - } else { - if (f->padding) { - f->state = ngx_http_fastcgi_st_padding; - } else { - f->state = ngx_http_fastcgi_st_version; - } + f->state = ngx_http_fastcgi_st_padding; } continue; } + if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) { + if (f->pos + f->length <= f->last) { + f->state = ngx_http_fastcgi_st_padding; + f->pos += f->length; + + continue; + } + + f->length -= f->last - f->pos; + + break; + } + + /* f->type == NGX_HTTP_FASTCGI_STDOUT */ if (f->pos == f->last) { @@ -1856,33 +1860,14 @@ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0, "input buf #%d %p", b->num, b->pos); - if (f->pos + f->length < f->last) { - - if (f->padding) { - f->state = ngx_http_fastcgi_st_padding; - } else { - f->state = ngx_http_fastcgi_st_version; - } - + if (f->pos + f->length <= f->last) { + f->state = ngx_http_fastcgi_st_padding; f->pos += f->length; b->last = f->pos; continue; } - if (f->pos + f->length == f->last) { - - if (f->padding) { - f->state = ngx_http_fastcgi_st_padding; - } else { - f->state = ngx_http_fastcgi_st_version; - } - - b->last = f->last; - - break; - } - f->length -= f->last - f->pos; b->last = f->last; From mdounin at mdounin.ru Mon Feb 11 23:37:20 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 23:37:20 +0000 Subject: [nginx] svn commit: r5066 - trunk/misc Message-ID: <20130211233720.F2AD93F9F0F@mail.nginx.com> Author: mdounin Date: 2013-02-11 23:37:20 +0000 (Mon, 11 Feb 2013) New Revision: 5066 URL: http://trac.nginx.org/nginx/changeset/5066/nginx Log: Updated OpenSSL used for win32 builds. Modified: trunk/misc/GNUmakefile Modified: trunk/misc/GNUmakefile =================================================================== --- trunk/misc/GNUmakefile 2013-02-11 16:11:14 UTC (rev 5065) +++ trunk/misc/GNUmakefile 2013-02-11 23:37:20 UTC (rev 5066) @@ -6,7 +6,7 @@ REPO = $(shell svn info | sed -n 's/^Repository Root: //p') OBJS = objs.msvc8 -OPENSSL = openssl-1.0.1d +OPENSSL = openssl-1.0.1e ZLIB = zlib-1.2.7 PCRE = pcre-8.32 From mdounin at mdounin.ru Mon Feb 11 23:57:14 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 11 Feb 2013 23:57:14 +0000 Subject: [nginx] svn commit: r5067 - in branches/stable-1.2: . misc Message-ID: <20130211235715.304C53F9F3E@mail.nginx.com> Author: mdounin Date: 2013-02-11 23:57:13 +0000 (Mon, 11 Feb 2013) New Revision: 5067 URL: http://trac.nginx.org/nginx/changeset/5067/nginx Log: Merge of r5005, r5031, r5066: PCRE and OpenSSL for win32 builds. Modified: branches/stable-1.2/ branches/stable-1.2/misc/GNUmakefile Index: branches/stable-1.2 =================================================================== --- branches/stable-1.2 2013-02-11 23:37:20 UTC (rev 5066) +++ branches/stable-1.2 2013-02-11 23:57:13 UTC (rev 5067) Property changes on: branches/stable-1.2 ___________________________________________________________________ Modified: svn:mergeinfo ## -1 +1 ## -/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5004,5011-5025,5027-5030 +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5005,5011-5025,5027-5031,5066 \ No newline at end of property Modified: branches/stable-1.2/misc/GNUmakefile =================================================================== --- branches/stable-1.2/misc/GNUmakefile 2013-02-11 23:37:20 UTC (rev 5066) +++ branches/stable-1.2/misc/GNUmakefile 2013-02-11 23:57:13 UTC (rev 5067) @@ -6,9 +6,9 @@ REPO = $(shell svn info | sed -n 's/^Repository Root: //p') OBJS = objs.msvc8 -OPENSSL = openssl-1.0.1c +OPENSSL = openssl-1.0.1e ZLIB = zlib-1.2.7 -PCRE = pcre-8.31 +PCRE = pcre-8.32 release: From mdounin at mdounin.ru Tue Feb 12 13:40:17 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Tue, 12 Feb 2013 13:40:17 +0000 Subject: [nginx] svn commit: r5068 - branches/stable-1.2/docs/xml/nginx Message-ID: <20130212134018.14AD93FA0D2@mail.nginx.com> Author: mdounin Date: 2013-02-12 13:40:16 +0000 (Tue, 12 Feb 2013) New Revision: 5068 URL: http://trac.nginx.org/nginx/changeset/5068/nginx Log: nginx-1.2.7-RELEASE Modified: branches/stable-1.2/docs/xml/nginx/changes.xml Modified: branches/stable-1.2/docs/xml/nginx/changes.xml =================================================================== --- branches/stable-1.2/docs/xml/nginx/changes.xml 2013-02-11 23:57:13 UTC (rev 5067) +++ branches/stable-1.2/docs/xml/nginx/changes.xml 2013-02-12 13:40:16 UTC (rev 5068) @@ -5,6 +5,259 @@ + + + + +?????? ??? ????????????? ????????? include ? ?????? ?? Unix-???????? +?????????? ????? ??????????? ? ?????????? ???????. + + +now if the "include" directive with mask is used on Unix systems, +included files are sorted in alphabetical order. + + + + + +????????? add_header ????????? ?????? ? ?????? ? ????? 201. + + +the "add_header" directive adds headers to 201 responses. + + + + + +????????? geo ?????? ???????????? IPv6 ?????? ? ??????? CIDR. + + +the "geo" directive now supports IPv6 addresses in CIDR notation. + + + + + +????????? flush ? gzip ? ????????? access_log. + + +the "flush" and "gzip" parameters of the "access_log" directive. + + + + + +????????? auth_basic ???????????? ??????????. + + +variables support in the "auth_basic" directive. + + + + + +?????????? $pipe, $request_length, $time_iso8601 ? $time_local +?????? ????? ???????????? ?? ?????? ? ????????? log_format.
+??????? Kiril Kalchev. +
+ +the $pipe, $request_length, $time_iso8601, and $time_local variables +can now be used not only in the "log_format" directive. +Thanks to Kiril Kalchev. + +
+ + + +????????? IPv6 ? ?????? ngx_http_geoip_module.
+??????? Gregor Kali?nik. +
+ +IPv6 support in the ngx_http_geoip_module.
+Thanks to Gregor Kali?nik. +
+
+ + + +nginx ? ????????? ??????? ?? ????????? ? ??????? ngx_http_perl_module. + + +nginx could not be built with the ngx_http_perl_module in some cases. + + + + + +? ??????? ???????? ??? ????????? segmentation fault, +???? ????????????? ?????? ngx_http_xslt_module. + + +a segmentation fault might occur in a worker process +if the ngx_http_xslt_module was used. + + + + + +nginx ??? ?? ?????????? ?? MacOSX.
+??????? Piotr Sikora. +
+ +nginx could not be built on MacOSX in some cases.
+Thanks to Piotr Sikora. +
+
+ + + +??? ????????????? ????????? limit_rate ? ???????? ?????????? ???????? +?? 32-?????? ???????? ????? ??? ???????????? ?? ???????.
+??????? ??????? ?????????. +
+ +the "limit_rate" directive with high rates +might result in truncated responses on 32-bit platforms.
+Thanks to Alexey Antropov. +
+
+ + + +? ??????? ???????? ??? ????????? segmentation fault, +???? ?????????????? ????????? if.
+??????? Piotr Sikora. +
+ +a segmentation fault might occur in a worker process +if the "if" directive was used.
+Thanks to Piotr Sikora. +
+
+ + + +????? "100 Continue" ????????? +?????? ? ??????? "413 Request Entity Too Large". + + +a "100 Continue" response was issued +with "413 Request Entity Too Large" responses. + + + + + +????????? image_filter, image_filter_jpeg_quality ? image_filter_sharpen +????? ????????????? ???????????.
+??????? ????? ???????. +
+ +the "image_filter", "image_filter_jpeg_quality" +and "image_filter_sharpen" directives +might be inherited incorrectly.
+Thanks to Ian Babrou. +
+
+ + + +??? ????????????? ????????? auth_basic ??? Linux +????? ????????? ?????? "crypt_r() failed". + + +"crypt_r() failed" errors might appear +if the "auth_basic" directive was used on Linux. + + + + + +? ????????? backup-????????.
+??????? Thomas Chen. +
+ +in backup servers handling.
+Thanks to Thomas Chen. +
+
+ + + +??? ????????????? HEAD-???????? ??? ???????????? ???????????? ?????, +???? ?????????????? ????????? gzip. + + +proxied HEAD requests might return incorrect response +if the "gzip" directive was used. + + + + + +?? ?????? ??? ?? ????? ???????????????? ?????????? segmentation fault, +???? ????????? keepalive ???? ??????? ????????? ??? +? ????? ????? upstream. + + +a segmentation fault occurred on start or during reconfiguration +if the "keepalive" directive was specified more than once +in a single upstream block. + + + + + +????????? proxy_method ???????? ???????, ???? ???? ??????? ?? ?????? http. + + +in the "proxy_method" directive. + + + + + +? ??????? ???????? ??? ????????? segmentation fault, +???? ????????????? resolver ? ????? poll. + + +a segmentation fault might occur in a worker process +if resolver was used with the poll method. + + + + + +nginx ??? ????????? ????????? ?? ????? SSL handshake ? ???????? +??? ????????????? ??????? ????????? ?????????? select, poll ? /dev/poll. + + +nginx might hog CPU during SSL handshake with a backend +if the select, poll, or /dev/poll methods were used. + + + + + +?????? "[crit] SSL_write() failed (SSL:)". + + +the "[crit] SSL_write() failed (SSL:)" error. + + + + + +? ????????? fastcgi_keep_conn. + + +in the "fastcgi_keep_conn" directive. + + + +
+ + From mdounin at mdounin.ru Tue Feb 12 13:40:47 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Tue, 12 Feb 2013 13:40:47 +0000 Subject: [nginx] svn commit: r5069 - in tags: . release-1.2.7 Message-ID: <20130212134047.85B743FA0D8@mail.nginx.com> Author: mdounin Date: 2013-02-12 13:40:46 +0000 (Tue, 12 Feb 2013) New Revision: 5069 URL: http://trac.nginx.org/nginx/changeset/5069/nginx Log: release-1.2.7 tag Added: tags/release-1.2.7/ Index: tags/release-1.2.7 =================================================================== --- branches/stable-1.2 2013-02-12 13:40:16 UTC (rev 5068) +++ tags/release-1.2.7 2013-02-12 13:40:46 UTC (rev 5069) Property changes on: tags/release-1.2.7 ___________________________________________________________________ Added: svn:ignore ## -0,0 +1,14 ## +access.log +client_body_temp +fastcgi_temp +proxy_temp +scgi_temp +uwsgi_temp +GNUmakefile +Makefile +makefile +nginx +nginx.conf +nginx-*.tar.gz +objs* +tmp Added: svn:mergeinfo ## -0,0 +1 ## +/trunk:4611-4632,4636-4657,4671-4672,4674-4676,4682,4684-4699,4704-4706,4713,4736-4741,4754,4756-4771,4775,4777-4780,4782-4785,4795,4811-4820,4822-4824,4828-4835,4840-4844,4865-4872,4885-4887,4890-4896,4913-4925,4933-4934,4939,4944-4949,4961-4969,4973-4974,4976-4994,4997,4999-5005,5011-5025,5027-5031,5066 \ No newline at end of property From ywu at about.com Tue Feb 12 15:38:13 2013 From: ywu at about.com (YongFeng Wu) Date: Tue, 12 Feb 2013 10:38:13 -0500 Subject: open_file_cache_events Message-ID: <000301ce0936$f8449050$e8cdb0f0$@com> Hi, http core module has a directive "open_file_cache_events", but it is not listed in the official documentation anywhere. I'm just wondering why. Thanks a lot, ywu -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Tue Feb 12 15:59:26 2013 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 12 Feb 2013 19:59:26 +0400 Subject: open_file_cache_events In-Reply-To: <000301ce0936$f8449050$e8cdb0f0$@com> References: <000301ce0936$f8449050$e8cdb0f0$@com> Message-ID: <20130212155926.GM20890@mdounin.ru> Hello! On Tue, Feb 12, 2013 at 10:38:13AM -0500, YongFeng Wu wrote: > http core module has a directive "open_file_cache_events", but it is not > listed in the official documentation anywhere. > > I'm just wondering why. It's not documented on purpose: the code is incomplete and racy. Don't use it. -- Maxim Dounin http://nginx.com/support.html From igor at sysoev.ru Tue Feb 12 15:59:42 2013 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 12 Feb 2013 19:59:42 +0400 Subject: open_file_cache_events In-Reply-To: <000301ce0936$f8449050$e8cdb0f0$@com> References: <000301ce0936$f8449050$e8cdb0f0$@com> Message-ID: <4992B5D9-7B69-4E35-976D-D8993CCD9E09@sysoev.ru> On Feb 12, 2013, at 19:38 , YongFeng Wu wrote: > > Hi, > > http core module has a directive ?open_file_cache_events?, but it is not listed in the official documentation anywhere. > > I?m just wondering why. Becaase it's broken: there is now a race condition in nginx between closing file and kqueue event. -- Igor Sysoev http://nginx.com/support.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From ibobrik at gmail.com Tue Feb 12 17:10:17 2013 From: ibobrik at gmail.com (ivan babrou) Date: Tue, 12 Feb 2013 21:10:17 +0400 Subject: server_name and listen behaviour Message-ID: Hi, I have a question. It's better to describe with example I point one.local and two.local to 127.0.0.1 and create following servers in config for nginx: server { listen 80; server_name one.local; location / { return 404; } } server { listen two.local:80; server_name two.local; location / { return 403; } } If I request one.local then 403 is returned. If i change listen for one.local to one.local:80 then 404 correctly returned, but only after restart, reload doesn't help (that's probably bug too). I expect to get 404 if i request one.local even if I listen on all addresses. Am I right? Thanks! -- Regards, Ian Babrou http://bobrik.name http://twitter.com/ibobrik skype:i.babrou -------------- next part -------------- An HTML attachment was scrubbed... URL: From igor at sysoev.ru Tue Feb 12 19:06:25 2013 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 12 Feb 2013 23:06:25 +0400 Subject: server_name and listen behaviour In-Reply-To: References: Message-ID: On Feb 12, 2013, at 21:10 , ivan babrou wrote: > Hi, I have a question. It's better to describe with example > > I point one.local and two.local to 127.0.0.1 and create following servers in config for nginx: > > server { > listen 80; > server_name one.local; > > location / { > return 404; > } > } > > server { > listen two.local:80; > server_name two.local; > > location / { > return 403; > } > } > > If I request one.local then 403 is returned. If i change listen for one.local to one.local:80 then 404 correctly returned, but only after restart, reload doesn't help (that's probably bug too). Is there in error_log error something like "listen(127.0.0.1:80) failed (98: Address already in use)" ? > I expect to get 404 if i request one.local even if I listen on all addresses. Am I right? No. Your first configuration is server { listen *:80; server_name one.local; } server { listen 127.0.0.1:80; server_name two.local; } A client connects to 127.0.0.1:80, so nginx uses the second server to processes request. When you change listen in the first server to 127.0.0.1:80, nginx has two servers for this listen port and chooses server using "Host" header. -- Igor Sysoev http://nginx.com/support.html From ru at nginx.com Tue Feb 12 19:14:23 2013 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 12 Feb 2013 23:14:23 +0400 Subject: server_name and listen behaviour In-Reply-To: References: Message-ID: <20130212191423.GA69825@lo0.su> On Tue, Feb 12, 2013 at 09:10:17PM +0400, ivan babrou wrote: > Hi, I have a question. It's better to describe with example > I point one.local and two.local to 127.0.0.1 and create following servers > in config for nginx: > server { > ? listen 80; > ? server_name one.local; > ? location / { > ? ? return 404; > ? } > } > server { > ? listen two.local:80; > ? server_name two.local; > ? location / { > ? ? return 403; > ? } > } > If I request one.local then 403 is returned. If i change listen for > one.local to one.local:80 then 404 correctly returned, but only after > restart, reload doesn't help (that's probably bug too). > I expect to get 404 if i request one.local even if I listen on all > addresses. Am I right? 127.0.0.1:80 and *:80 are two different socket addresses, and when you connect to 127.0.0.1:80, the first one will be used (two.local in your case). This is not specific to nginx, it's how sockets work. nginx by default optimizes such a config by creating only one listening socket [1], and pessimizes by using getsockaddr() to differentiate between multiple sockaddrs. This optimization can be turned off by using "bind" parameter (or some other parameters, see [1] for details). Nevertheless, 127.0.0.1:80 and *:80 are still two different addresses, and 127.0.0.1:80 is more specific than *:80. As to "reload not working", I cannot reproduce this: (in my config I always return 200 with "$server_name") $ echo 'GET http://one:8000/' | nc 127.0.0.1 8000 two.local # here config was changed to listen on 127.0.0.1:80 # instead of *:80 for one.local # reload (kill -HUP nginx master process) $ kill -HUP 33122 $ echo 'GET http://one:8000/' | nc 127.0.0.1 8000 one.local [1] http://nginx.org/r/listen From igor at sysoev.ru Tue Feb 12 19:32:08 2013 From: igor at sysoev.ru (Igor Sysoev) Date: Tue, 12 Feb 2013 23:32:08 +0400 Subject: server_name and listen behaviour In-Reply-To: <20130212191423.GA69825@lo0.su> References: <20130212191423.GA69825@lo0.su> Message-ID: On Feb 12, 2013, at 23:14 , Ruslan Ermilov wrote: > On Tue, Feb 12, 2013 at 09:10:17PM +0400, ivan babrou wrote: >> Hi, I have a question. It's better to describe with example >> I point one.local and two.local to 127.0.0.1 and create following servers >> in config for nginx: >> server { >> listen 80; >> server_name one.local; >> location / { >> return 404; >> } >> } >> server { >> listen two.local:80; >> server_name two.local; >> location / { >> return 403; >> } >> } >> If I request one.local then 403 is returned. If i change listen for >> one.local to one.local:80 then 404 correctly returned, but only after >> restart, reload doesn't help (that's probably bug too). >> I expect to get 404 if i request one.local even if I listen on all >> addresses. Am I right? > > 127.0.0.1:80 and *:80 are two different socket addresses, > and when you connect to 127.0.0.1:80, the first one will > be used (two.local in your case). This is not specific > to nginx, it's how sockets work. > > nginx by default optimizes such a config by creating only > one listening socket [1], and pessimizes by using getsockaddr() > to differentiate between multiple sockaddrs. This optimization > can be turned off by using "bind" parameter (or some other > parameters, see [1] for details). Nevertheless, 127.0.0.1:80 > and *:80 are still two different addresses, and 127.0.0.1:80 > is more specific than *:80. > > As to "reload not working", I cannot reproduce this: > > (in my config I always return 200 with "$server_name") > > $ echo 'GET http://one:8000/' | nc 127.0.0.1 8000 > two.local > > # here config was changed to listen on 127.0.0.1:80 > # instead of *:80 for one.local > > # reload (kill -HUP nginx master process) > > $ kill -HUP 33122 > $ echo 'GET http://one:8000/' | nc 127.0.0.1 8000 > one.local > > [1] http://nginx.org/r/listen I believe on Linux you cannot use listen *:80 bind; listen 127.0.0.1:80 bind; -- Igor Sysoev http://nginx.com/support.html From ibobrik at gmail.com Wed Feb 13 04:49:57 2013 From: ibobrik at gmail.com (ivan babrou) Date: Wed, 13 Feb 2013 08:49:57 +0400 Subject: server_name and listen behaviour In-Reply-To: References: Message-ID: On 12 February 2013 23:06, Igor Sysoev wrote: > On Feb 12, 2013, at 21:10 , ivan babrou wrote: > > > Hi, I have a question. It's better to describe with example > > > > I point one.local and two.local to 127.0.0.1 and create following > servers in config for nginx: > > > > server { > > listen 80; > > server_name one.local; > > > > location / { > > return 404; > > } > > } > > > > server { > > listen two.local:80; > > server_name two.local; > > > > location / { > > return 403; > > } > > } > > > > If I request one.local then 403 is returned. If i change listen for > one.local to one.local:80 then 404 correctly returned, but only after > restart, reload doesn't help (that's probably bug too). > > Is there in error_log error something like "listen(127.0.0.1:80) failed > (98: Address already in use)" ? > No, there's no such thing. > > I expect to get 404 if i request one.local even if I listen on all > addresses. Am I right? > > > No. Your first configuration is > > server { > listen *:80; > server_name one.local; > } > > server { > listen 127.0.0.1:80; > server_name two.local; > } > > A client connects to 127.0.0.1:80, so nginx uses the second server to > processes request. > When you change listen in the first server to 127.0.0.1:80, nginx has two > servers for this > listen port and chooses server using "Host" header. > This is what netstat says: callisto ~ # netstat -ntl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 127.0.0.1:21213 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:5432 0.0.0.0:* LISTEN tcp6 0 0 ::1:21213 :::* LISTEN tcp6 0 0 :::22 :::* LISTEN tcp6 0 0 :::5432 :::* LISTEN Here I only see 0.0.0.0:80 and 127.0.0.1:80 looks like a subset for this. So why can't nginx use the same socket? > -- > Igor Sysoev > http://nginx.com/support.html > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- Regards, Ian Babrou http://bobrik.name http://twitter.com/ibobrik skype:i.babrou -------------- next part -------------- An HTML attachment was scrubbed... URL: From igor at sysoev.ru Wed Feb 13 04:57:03 2013 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 13 Feb 2013 08:57:03 +0400 Subject: server_name and listen behaviour In-Reply-To: References: Message-ID: On Feb 13, 2013, at 8:49 , ivan babrou wrote: > On 12 February 2013 23:06, Igor Sysoev wrote: > On Feb 12, 2013, at 21:10 , ivan babrou wrote: > > > Hi, I have a question. It's better to describe with example > > > > I point one.local and two.local to 127.0.0.1 and create following servers in config for nginx: > > > > server { > > listen 80; > > server_name one.local; > > > > location / { > > return 404; > > } > > } > > > > server { > > listen two.local:80; > > server_name two.local; > > > > location / { > > return 403; > > } > > } > > > > If I request one.local then 403 is returned. If i change listen for one.local to one.local:80 then 404 correctly returned, but only after restart, reload doesn't help (that's probably bug too). > > Is there in error_log error something like "listen(127.0.0.1:80) failed (98: Address already in use)" ? > > No, there's no such thing. Then it should work with just reload. > > I expect to get 404 if i request one.local even if I listen on all addresses. Am I right? > > > No. Your first configuration is > > server { > listen *:80; > server_name one.local; > } > > server { > listen 127.0.0.1:80; > server_name two.local; > } > > A client connects to 127.0.0.1:80, so nginx uses the second server to processes request. > When you change listen in the first server to 127.0.0.1:80, nginx has two servers for this > listen port and chooses server using "Host" header. > > This is what netstat says: > > callisto ~ # netstat -ntl > Active Internet connections (only servers) > Proto Recv-Q Send-Q Local Address Foreign Address State > tcp 0 0 127.0.0.1:21213 0.0.0.0:* LISTEN > tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN > tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN > tcp 0 0 0.0.0.0:5432 0.0.0.0:* LISTEN > tcp6 0 0 ::1:21213 :::* LISTEN > tcp6 0 0 :::22 :::* LISTEN > tcp6 0 0 :::5432 :::* LISTEN > > Here I only see 0.0.0.0:80 and 127.0.0.1:80 looks like a subset for this. So why can't nginx use the same socket? If there is "listen *:80", nginx uses this single socket to accept all connections to 80 port and then learn local address with getsockaddr(), see Ruslan email for details. -- Igor Sysoev http://nginx.com/support.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From ibobrik at gmail.com Wed Feb 13 04:56:56 2013 From: ibobrik at gmail.com (ivan babrou) Date: Wed, 13 Feb 2013 08:56:56 +0400 Subject: server_name and listen behaviour In-Reply-To: <20130212191423.GA69825@lo0.su> References: <20130212191423.GA69825@lo0.su> Message-ID: On 12 February 2013 23:14, Ruslan Ermilov wrote: > On Tue, Feb 12, 2013 at 09:10:17PM +0400, ivan babrou wrote: > > Hi, I have a question. It's better to describe with example > > I point one.local and two.local to 127.0.0.1 and create following > servers > > in config for nginx: > > server { > > listen 80; > > server_name one.local; > > location / { > > return 404; > > } > > } > > server { > > listen two.local:80; > > server_name two.local; > > location / { > > return 403; > > } > > } > > If I request one.local then 403 is returned. If i change listen for > > one.local to one.local:80 then 404 correctly returned, but only after > > restart, reload doesn't help (that's probably bug too). > > I expect to get 404 if i request one.local even if I listen on all > > addresses. Am I right? > > 127.0.0.1:80 and *:80 are two different socket addresses, > and when you connect to 127.0.0.1:80, the first one will > be used (two.local in your case). This is not specific > to nginx, it's how sockets work. > > nginx by default optimizes such a config by creating only > one listening socket [1], and pessimizes by using getsockaddr() > to differentiate between multiple sockaddrs. This optimization > can be turned off by using "bind" parameter (or some other > parameters, see [1] for details). Nevertheless, 127.0.0.1:80 > and *:80 are still two different addresses, and 127.0.0.1:80 > is more specific than *:80. See below, I only see one listening address in netstat. As to "reload not working", I cannot reproduce this: > > (in my config I always return 200 with "$server_name") > > $ echo 'GET http://one:8000/' | nc 127.0.0.1 8000 > two.local > > # here config was changed to listen on 127.0.0.1:80 > # instead of *:80 for one.local > > # reload (kill -HUP nginx master process) > > $ kill -HUP 33122 > $ echo 'GET http://one:8000/' | nc 127.0.0.1 8000 > one.local > I have listen *:80 before reload, then change it to listen one.local:80 and reaload. nginx/1.2.6 Before reload: callisto ~ # netstat -ntl | fgrep ':80' tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN After reload: callisto ~ # netstat -ntl | fgrep ':80' tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN After restart: callisto ~ # netstat -ntl | fgrep ':80' tcp 0 0 127.0.0.1:80 0.0.0.0:* LISTEN Did you have one.local and two local when you check this? > [1] http://nginx.org/r/listen > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- Regards, Ian Babrou http://bobrik.name http://twitter.com/ibobrik skype:i.babrou -------------- next part -------------- An HTML attachment was scrubbed... URL: From ibobrik at gmail.com Wed Feb 13 05:06:39 2013 From: ibobrik at gmail.com (ivan babrou) Date: Wed, 13 Feb 2013 09:06:39 +0400 Subject: server_name and listen behaviour In-Reply-To: References: Message-ID: On 13 February 2013 08:57, Igor Sysoev wrote: > On Feb 13, 2013, at 8:49 , ivan babrou wrote: > > On 12 February 2013 23:06, Igor Sysoev wrote: > >> On Feb 12, 2013, at 21:10 , ivan babrou wrote: >> >> > Hi, I have a question. It's better to describe with example >> > >> > I point one.local and two.local to 127.0.0.1 and create following >> servers in config for nginx: >> > >> > server { >> > listen 80; >> > server_name one.local; >> > >> > location / { >> > return 404; >> > } >> > } >> > >> > server { >> > listen two.local:80; >> > server_name two.local; >> > >> > location / { >> > return 403; >> > } >> > } >> > >> > If I request one.local then 403 is returned. If i change listen for >> one.local to one.local:80 then 404 correctly returned, but only after >> restart, reload doesn't help (that's probably bug too). >> >> Is there in error_log error something like "listen(127.0.0.1:80) >> failed (98: Address already in use)" ? >> > > No, there's no such thing. > > > Then it should work with just reload. > Found that in logs after reload. > > I expect to get 404 if i request one.local even if I listen on all >> addresses. Am I right? >> >> >> No. Your first configuration is >> >> server { >> listen *:80; >> server_name one.local; >> } >> >> server { >> listen 127.0.0.1:80 ; >> server_name two.local; >> } >> >> A client connects to 127.0.0.1:80 , so nginx uses the >> second server to processes request. >> When you change listen in the first server to 127.0.0.1:80, >> nginx has two servers for this >> listen port and chooses server using "Host" header. >> > > This is what netstat says: > > callisto ~ # netstat -ntl > Active Internet connections (only servers) > Proto Recv-Q Send-Q Local Address Foreign Address State > > tcp 0 0 127.0.0.1:21213 0.0.0.0:* > LISTEN > tcp 0 0 0.0.0.0:80 0.0.0.0:* > LISTEN > tcp 0 0 0.0.0.0:22 0.0.0.0:* > LISTEN > tcp 0 0 0.0.0.0:5432 0.0.0.0:* > LISTEN > tcp6 0 0 ::1:21213 :::* LISTEN > > tcp6 0 0 :::22 :::* LISTEN > > tcp6 0 0 :::5432 :::* LISTEN > > Here I only see 0.0.0.0:80 and 127.0.0.1:80looks like a subset for this. So why can't nginx use the same socket? > > > If there is "listen *:80", nginx uses this single socket to accept all > connections to 80 port and > then learn local address with getsockaddr(), see Ruslan email for details. > I don't see why nginx cant' find that server_name one.local matches incoming request on that socket. Nginx may check not only listen with 127.0.0.1, but also listen with *, why not? > > -- > Igor Sysoev > http://nginx.com/support.html > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- Regards, Ian Babrou http://bobrik.name http://twitter.com/ibobrik skype:i.babrou -------------- next part -------------- An HTML attachment was scrubbed... URL: From igor at sysoev.ru Wed Feb 13 05:18:36 2013 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 13 Feb 2013 09:18:36 +0400 Subject: server_name and listen behaviour In-Reply-To: References: Message-ID: <65C9A9EB-373F-4CAA-9E51-B26D2D8EA3FA@sysoev.ru> On Feb 13, 2013, at 9:06 , ivan babrou wrote: > On 13 February 2013 08:57, Igor Sysoev wrote: > On Feb 13, 2013, at 8:49 , ivan babrou wrote: > >> On 12 February 2013 23:06, Igor Sysoev wrote: >> On Feb 12, 2013, at 21:10 , ivan babrou wrote: >> >> > Hi, I have a question. It's better to describe with example >> > >> > I point one.local and two.local to 127.0.0.1 and create following servers in config for nginx: >> > >> > server { >> > listen 80; >> > server_name one.local; >> > >> > location / { >> > return 404; >> > } >> > } >> > >> > server { >> > listen two.local:80; >> > server_name two.local; >> > >> > location / { >> > return 403; >> > } >> > } >> > >> > If I request one.local then 403 is returned. If i change listen for one.local to one.local:80 then 404 correctly returned, but only after restart, reload doesn't help (that's probably bug too). >> >> Is there in error_log error something like "listen(127.0.0.1:80) failed (98: Address already in use)" ? >> >> No, there's no such thing. > > Then it should work with just reload. > > Found that in logs after reload. This is Linux "feature". >> > I expect to get 404 if i request one.local even if I listen on all addresses. Am I right? >> >> >> No. Your first configuration is >> >> server { >> listen *:80; >> server_name one.local; >> } >> >> server { >> listen 127.0.0.1:80; >> server_name two.local; >> } >> >> A client connects to 127.0.0.1:80, so nginx uses the second server to processes request. >> When you change listen in the first server to 127.0.0.1:80, nginx has two servers for this >> listen port and chooses server using "Host" header. >> >> This is what netstat says: >> >> callisto ~ # netstat -ntl >> Active Internet connections (only servers) >> Proto Recv-Q Send-Q Local Address Foreign Address State >> tcp 0 0 127.0.0.1:21213 0.0.0.0:* LISTEN >> tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN >> tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN >> tcp 0 0 0.0.0.0:5432 0.0.0.0:* LISTEN >> tcp6 0 0 ::1:21213 :::* LISTEN >> tcp6 0 0 :::22 :::* LISTEN >> tcp6 0 0 :::5432 :::* LISTEN >> >> Here I only see 0.0.0.0:80 and 127.0.0.1:80 looks like a subset for this. So why can't nginx use the same socket? > > If there is "listen *:80", nginx uses this single socket to accept all connections to 80 port and > then learn local address with getsockaddr(), see Ruslan email for details. > > I don't see why nginx cant' find that server_name one.local matches incoming request on that socket. Nginx may check not only listen with 127.0.0.1, but also listen with *, why not? On Linux there is no way to listen on both wildcard address and specific addresses. You have to listen on either on wildcard addresss or several specific addresses. So on Linux there is no way to limit a host to specific address and nginx emulates other OSes behaviour. If you want to process one.local on both *:80 and 127.0.0.1:80 you should use this: server { listen *:80; listen 127.0.0.1:80 server_name one.local; } server { listen 127.0.0.1:80 server_name two.local; } -- Igor Sysoev http://nginx.com/support.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From ru at nginx.com Wed Feb 13 08:18:16 2013 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 13 Feb 2013 12:18:16 +0400 Subject: server_name and listen behaviour In-Reply-To: References: <20130212191423.GA69825@lo0.su> Message-ID: <20130213081816.GA64583@lo0.su> On Wed, Feb 13, 2013 at 08:56:56AM +0400, ivan babrou wrote: > On 12 February 2013 23:14, Ruslan Ermilov wrote: > > > On Tue, Feb 12, 2013 at 09:10:17PM +0400, ivan babrou wrote: > > > Hi, I have a question. It's better to describe with example > > > I point one.local and two.local to 127.0.0.1 and create following > > servers > > > in config for nginx: > > > server { > > > listen 80; > > > server_name one.local; > > > location / { > > > return 404; > > > } > > > } > > > server { > > > listen two.local:80; > > > server_name two.local; > > > location / { > > > return 403; > > > } > > > } > > > If I request one.local then 403 is returned. If i change listen for > > > one.local to one.local:80 then 404 correctly returned, but only after > > > restart, reload doesn't help (that's probably bug too). > > > I expect to get 404 if i request one.local even if I listen on all > > > addresses. Am I right? > > > > 127.0.0.1:80 and *:80 are two different socket addresses, > > and when you connect to 127.0.0.1:80, the first one will > > be used (two.local in your case). This is not specific > > to nginx, it's how sockets work. > > > > nginx by default optimizes such a config by creating only > > one listening socket [1], and pessimizes by using getsockaddr() > > to differentiate between multiple sockaddrs. This optimization > > can be turned off by using "bind" parameter (or some other > > parameters, see [1] for details). Nevertheless, 127.0.0.1:80 > > and *:80 are still two different addresses, and 127.0.0.1:80 > > is more specific than *:80. > > > See below, I only see one listening address in netstat. > > As to "reload not working", I cannot reproduce this: [...] > I have listen *:80 before reload, then change it to listen one.local:80 and > reaload. nginx/1.2.6 > > Before reload: > > callisto ~ # netstat -ntl | fgrep ':80' > tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN > > After reload: > > callisto ~ # netstat -ntl | fgrep ':80' > tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN > > After restart: > > callisto ~ # netstat -ntl | fgrep ':80' > tcp 0 0 127.0.0.1:80 0.0.0.0:* LISTEN > > Did you have one.local and two local when you check this? Just for the record. Here's how it works on BSD-like systems: : $ ps 36455 : PID TT STAT TIME COMMAND : 36455 s004 S+ 0:00.00 nginx: master process objs/nginx -p . -c x.conf : : $ cat x.conf : [...] : http { : server { : listen *:8000; : server_name one; : return 200 "$server_name\n"; : } : server { : listen 127.0.0.1:8000; : server_name two; : return 200 "$server_name\n"; : } : } : : $ echo 'GET http://one/' | nc 127.0.0.1 8000 : two : : $ echo 'GET http://two/' | nc 127.0.0.1 8000 : two : : $ netstat -anL | grep 8000 : 0/0/128 *.8000 : : $ vim x.conf : [...] : : $ cat x.conf : [...] : http { : server { : listen 127.0.0.1:8000; : server_name one; : return 200 "$server_name\n"; : } : server { : listen 127.0.0.1:8000; : server_name two; : return 200 "$server_name\n"; : } : } : : $ kill -HUP 36455 : : $ netstat -anL | grep 8000 : 0/0/128 127.0.0.1.8000 : $ echo 'GET http://one/' | nc 127.0.0.1 8000 : one : $ echo 'GET http://two/' | nc 127.0.0.1 8000 : two But as Igor already mentioned, trying this on Linux fails at the "reload" step because Linux cannot create two sockets for *:8000 and 127.0.0.1:8000: 2013/02/13 08:15:57 [notice] 17532#0: signal 1 (SIGHUP) received, reconfiguring 2013/02/13 08:15:57 [notice] 17532#0: reconfiguring 2013/02/13 08:15:57 [emerg] 17532#0: bind() to 127.0.0.1:8000 failed (98: Address already in use) 2013/02/13 08:15:57 [notice] 17532#0: try again to bind() after 500ms 2013/02/13 08:15:57 [emerg] 17532#0: bind() to 127.0.0.1:8000 failed (98: Address already in use) 2013/02/13 08:15:57 [notice] 17532#0: try again to bind() after 500ms 2013/02/13 08:15:57 [emerg] 17532#0: bind() to 127.0.0.1:8000 failed (98: Address already in use) 2013/02/13 08:15:57 [notice] 17532#0: try again to bind() after 500ms 2013/02/13 08:15:57 [emerg] 17532#0: bind() to 127.0.0.1:8000 failed (98: Address already in use) 2013/02/13 08:15:57 [notice] 17532#0: try again to bind() after 500ms 2013/02/13 08:15:57 [emerg] 17532#0: bind() to 127.0.0.1:8000 failed (98: Address already in use) 2013/02/13 08:15:57 [notice] 17532#0: try again to bind() after 500ms 2013/02/13 08:15:57 [emerg] 17532#0: still could not bind() So nginx rolls back to previous configuration [1]. [1] http://nginx.org/libxslt/en/docs/control.html#reconfiguration From mdounin at mdounin.ru Wed Feb 13 14:39:48 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Wed, 13 Feb 2013 14:39:48 +0000 Subject: [nginx] svn commit: r5070 - trunk/src/http/modules Message-ID: <20130213143948.705743F9FA6@mail.nginx.com> Author: mdounin Date: 2013-02-13 14:39:46 +0000 (Wed, 13 Feb 2013) New Revision: 5070 URL: http://trac.nginx.org/nginx/changeset/5070/nginx Log: Fixed false memset warning on Linux with -O3 (ticket #275). Prodded by John Leach. Modified: trunk/src/http/modules/ngx_http_autoindex_module.c Modified: trunk/src/http/modules/ngx_http_autoindex_module.c =================================================================== --- trunk/src/http/modules/ngx_http_autoindex_module.c 2013-02-12 13:40:46 UTC (rev 5069) +++ trunk/src/http/modules/ngx_http_autoindex_module.c 2013-02-13 14:39:46 UTC (rev 5070) @@ -489,8 +489,11 @@ } b->last = ngx_cpymem(b->last, "", sizeof("") - 1); - ngx_memset(b->last, ' ', NGX_HTTP_AUTOINDEX_NAME_LEN - len); - b->last += NGX_HTTP_AUTOINDEX_NAME_LEN - len; + + if (NGX_HTTP_AUTOINDEX_NAME_LEN - len > 0) { + ngx_memset(b->last, ' ', NGX_HTTP_AUTOINDEX_NAME_LEN - len); + b->last += NGX_HTTP_AUTOINDEX_NAME_LEN - len; + } } *b->last++ = ' '; From mdounin at mdounin.ru Fri Feb 15 16:50:24 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Fri, 15 Feb 2013 16:50:24 +0000 Subject: [nginx] svn commit: r5071 - trunk/auto/lib/perl Message-ID: <20130215165025.EA8CE3F9F41@mail.nginx.com> Author: mdounin Date: 2013-02-15 16:50:22 +0000 (Fri, 15 Feb 2013) New Revision: 5071 URL: http://trac.nginx.org/nginx/changeset/5071/nginx Log: Configure: rebuild perl module nginx.so if headers are changed. Note: the "-p" argument of cp(1) dropped intentionally, to force nginx.so rebuild. It is considered too boring to properly list all dependencies in Makefile.PL. Modified: trunk/auto/lib/perl/make Modified: trunk/auto/lib/perl/make =================================================================== --- trunk/auto/lib/perl/make 2013-02-13 14:39:46 UTC (rev 5070) +++ trunk/auto/lib/perl/make 2013-02-15 16:50:22 UTC (rev 5071) @@ -6,11 +6,12 @@ cat << END >> $NGX_MAKEFILE $NGX_OBJS/src/http/modules/perl/blib/arch/auto/nginx/nginx.so: \ + \$(CORE_DEPS) \$(HTTP_DEPS) \ src/http/modules/perl/nginx.pm \ src/http/modules/perl/nginx.xs \ src/http/modules/perl/ngx_http_perl_module.h \ $NGX_OBJS/src/http/modules/perl/Makefile - cp -p src/http/modules/perl/nginx.* $NGX_OBJS/src/http/modules/perl/ + cp src/http/modules/perl/nginx.* $NGX_OBJS/src/http/modules/perl/ cd $NGX_OBJS/src/http/modules/perl && \$(MAKE) From zipoking at gmail.com Sat Feb 16 10:10:22 2013 From: zipoking at gmail.com (=?ISO-8859-2?Q?Pawe=B3_Smoli=F1ski?=) Date: Sat, 16 Feb 2013 11:10:22 +0100 Subject: SPDY+CORS not working under Chrome Message-ID: Hi, I've following problem: we are running website with SPDY enabled (nginx 1.3.12 with SPDY patch 62 and OpenSSL 1.0.1e) where we are providing API interface too. This API is used by other site (mobile interface) and in order to have this whole thing working I've added following configuration to nginx in order to have cross-origin requests working (found this somewhere in the web): if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0; return 200; } The problem with that is Chrome browser is reporting that OPTIONS failed when SPDY is enabled - when I turn off SPDY support everything is working as expected. Any idea how to workaround this (and maybe it's some bug inside Chrome)? Cheers, Pawe? -------------- next part -------------- An HTML attachment was scrubbed... URL: From yawning at schwanenlied.me Sat Feb 16 12:16:32 2013 From: yawning at schwanenlied.me (Yawning Angel) Date: Sat, 16 Feb 2013 04:16:32 -0800 Subject: RFC: PolarSSL support. Message-ID: <511F78A0.6050400@schwanenlied.me> Hello, In my (regrettably) copious spare time I have been working on adding support for PolarSSL[0] as an alternative to OpenSSL. I'm getting close to the point where I am comfortable with the code and would like to see if there is interest from the community and developers for this option. What I have so far: * src/event/ngx_event_polarssl.[h,c] (and some kludges to the build system so I can test my code). * Works in so much that a webserver compiled with my code can serve https (still needs more testing and code review). What needs to be done before it's usable: * Need to implement ngx_ssl_trusted_certificate, just haven't gotten around to it yet. * Need to write implementations for ngx_ssl_get_session (and ngx_ssl_free_session) so that ngx_http_upstream_round_robin works again. This should be relatively easy but I need to figure out how the module in question expects these to behave (The OpenSSL versions are #defines to OpenSSL routines and PolarSSL's internal behavior is reasonably different here). * Logging related cleanup. * PolarSSL supports SNI, but in the interest of keeping my changes self contained (Currently no functional changes to the nginx code apart from the addition of my module). I haven't implemented that yet because it requires modifying the http SSL module. * Need to figure out the nginx build system properly and integrate building with PolarSSL properly. * Need to see if the mail protocol support works. What I'd like to do after the first revision: * A few of the modules call OpenSSL routines (Eg: SSL_CTX_set_cipher_list, X509_verify_cert_error_string). Currently I provide wrappers for those routines in ngx_event_polarssl.c but they should be abstracted to ngx_ functions (Eg: ngx_set_cipher_list). * I haven't gotten around to making ngx_md5 and ngx_sha1 use PolarSSL yet. Would be trivial once my module is properly integrated into the build system. This post is mostly just trying to see if people would find this a useful addition before I start on ticking items off the list. Regards, -- Yawning Angel [0]: http://www.polarssl.org From yawning at schwanenlied.me Sun Feb 17 13:21:33 2013 From: yawning at schwanenlied.me (Yawning Angel) Date: Sun, 17 Feb 2013 05:21:33 -0800 Subject: RFC: PolarSSL support. In-Reply-To: <511F78A0.6050400@schwanenlied.me> References: <511F78A0.6050400@schwanenlied.me> Message-ID: <5120D95D.8060008@schwanenlied.me> Hello, The diff containing my first pass implementation is available at: http://www.schwanenlied.me/yawning/nginx/nginx-1.3.12-polarssl-20130217.diff.gz Behavioral differences: * ssl_ciphers_list format is different, though it will accept the default cipher list setting ("HIGH:!aNULL:!MD5"). For testing purposes I used: "TLS-RSA-WITH-RC4-128-SHA:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256:TLS-RSA-WITH-AES-256-CBC-SHA256:TLS-RSA-WITH-AES-256-GCM-SHA384:TLS-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA". * ssl_prefer_server_ciphers does not do anything. * I intentionally did not implement support for PolarSSL's builtin session cache because it's not very good (It's a linked list). shared and none should work. * SSLv2 is not supported by PolarSSL and will never be. * ECDH is not supported by PolarSSL yet but it is on their roadmap. * Stapling is not supported by PolarSSL. Not sure if it will be. Known issues: * When building with specifying the PolarSSL source directory with --with-polarssl=[path], the make used needs to be GNU make due to PolarSSL shipping with GNU make files. * ngx_http_upstream_roundrobin will not do SSL session reuse, since I intended for the patch to be minimally intrusive. It's possible to re-add this functionality, with changes to the module. * My auto integration does not have support for building on non-U*ix systems, because I do not have a windows development environment setup (PolarSSL supports the platform however). * SNI does not work because I haven't gone and written it yet. * Clients that send a SSLv2 Client Hello will fail to handshake (PolarSSL issue. They used to support this backward compatibility option, but support for it was pulled in v1.2.0, I posted on their support forums asking about this). * ngx_md5 and ngx_sha1 integration still not done yet, so on some systems[0] this may try to link against OpenSSL and have the compile or link fail. This is a build system issue and not a code issue. I haven't tested the client functionality (proxy modules) or mail, but I have no reason to expect that it shouldn't just work. Most of the code is shamelessly cribbed from ngx_event_openssl.[h,c], so I feel good about most of the code. The auto stuff wasn't all that documented so I'm not sure if I did it right (and it still needs work). Thoughts, comments, feedback appreciated. Regards, -- Yawning Angel [0]: I did the development on FreeBSD which has system MD5 and SHA1. From glebius at nginx.com Mon Feb 18 11:35:28 2013 From: glebius at nginx.com (glebius at nginx.com) Date: Mon, 18 Feb 2013 11:35:28 +0000 Subject: [nginx] svn commit: r5072 - trunk/auto Message-ID: <20130218113528.D8EE83F9ED0@mail.nginx.com> Author: glebius Date: 2013-02-18 11:35:28 +0000 (Mon, 18 Feb 2013) New Revision: 5072 URL: http://trac.nginx.org/nginx/changeset/5072/nginx Log: Configure: changed default compiler from "gcc" to "cc". This allows to automatically pick the preferred system compiler on systems with multiple compilers. Reviewed by: mdounin, ru Modified: trunk/auto/options Modified: trunk/auto/options =================================================================== --- trunk/auto/options 2013-02-15 16:50:22 UTC (rev 5071) +++ trunk/auto/options 2013-02-18 11:35:28 UTC (rev 5072) @@ -15,7 +15,7 @@ NGX_USER= NGX_GROUP= -CC=${CC:-gcc} +CC=${CC:-cc} CPP= NGX_OBJS=objs From mdounin at mdounin.ru Mon Feb 18 13:50:53 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 18 Feb 2013 13:50:53 +0000 Subject: [nginx] svn commit: r5073 - in trunk/src/http: . modules Message-ID: <20130218135054.1E7BF3F9C1B@mail.nginx.com> Author: mdounin Date: 2013-02-18 13:50:52 +0000 (Mon, 18 Feb 2013) New Revision: 5073 URL: http://trac.nginx.org/nginx/changeset/5073/nginx Log: Proxy: support for connection upgrade (101 Switching Protocols). This allows to proxy WebSockets by using configuration like this: location /chat/ { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } Connection upgrade is allowed as long as it was requested by a client via the Upgrade request header. Modified: trunk/src/http/modules/ngx_http_chunked_filter_module.c trunk/src/http/modules/ngx_http_proxy_module.c trunk/src/http/ngx_http_header_filter_module.c trunk/src/http/ngx_http_request.c trunk/src/http/ngx_http_request.h trunk/src/http/ngx_http_upstream.c trunk/src/http/ngx_http_upstream.h trunk/src/http/ngx_http_variables.c Modified: trunk/src/http/modules/ngx_http_chunked_filter_module.c =================================================================== --- trunk/src/http/modules/ngx_http_chunked_filter_module.c 2013-02-18 11:35:28 UTC (rev 5072) +++ trunk/src/http/modules/ngx_http_chunked_filter_module.c 2013-02-18 13:50:52 UTC (rev 5073) @@ -62,6 +62,7 @@ if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED || r->headers_out.status == NGX_HTTP_NO_CONTENT + || r->headers_out.status < NGX_HTTP_OK || r != r->main || (r->method & NGX_HTTP_HEAD)) { Modified: trunk/src/http/modules/ngx_http_proxy_module.c =================================================================== --- trunk/src/http/modules/ngx_http_proxy_module.c 2013-02-18 11:35:28 UTC (rev 5072) +++ trunk/src/http/modules/ngx_http_proxy_module.c 2013-02-18 13:50:52 UTC (rev 5073) @@ -1474,6 +1474,14 @@ u->keepalive = !u->headers_in.connection_close; } + if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS) { + u->keepalive = 0; + + if (r->headers_in.upgrade) { + u->upgrade = 1; + } + } + return NGX_OK; } Modified: trunk/src/http/ngx_http_header_filter_module.c =================================================================== --- trunk/src/http/ngx_http_header_filter_module.c 2013-02-18 11:35:28 UTC (rev 5072) +++ trunk/src/http/ngx_http_header_filter_module.c 2013-02-18 13:50:52 UTC (rev 5073) @@ -379,7 +379,10 @@ len += sizeof("Transfer-Encoding: chunked" CRLF) - 1; } - if (r->keepalive) { + if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) { + len += sizeof("Connection: upgrade" CRLF) - 1; + + } else if (r->keepalive) { len += sizeof("Connection: keep-alive" CRLF) - 1; /* @@ -548,7 +551,11 @@ sizeof("Transfer-Encoding: chunked" CRLF) - 1); } - if (r->keepalive) { + if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) { + b->last = ngx_cpymem(b->last, "Connection: upgrade" CRLF, + sizeof("Connection: upgrade" CRLF) - 1); + + } else if (r->keepalive) { b->last = ngx_cpymem(b->last, "Connection: keep-alive" CRLF, sizeof("Connection: keep-alive" CRLF) - 1); Modified: trunk/src/http/ngx_http_request.c =================================================================== --- trunk/src/http/ngx_http_request.c 2013-02-18 11:35:28 UTC (rev 5072) +++ trunk/src/http/ngx_http_request.c 2013-02-18 13:50:52 UTC (rev 5073) @@ -130,6 +130,10 @@ offsetof(ngx_http_headers_in_t, expect), ngx_http_process_unique_header_line }, + { ngx_string("Upgrade"), + offsetof(ngx_http_headers_in_t, upgrade), + ngx_http_process_header_line }, + #if (NGX_HTTP_GZIP) { ngx_string("Accept-Encoding"), offsetof(ngx_http_headers_in_t, accept_encoding), Modified: trunk/src/http/ngx_http_request.h =================================================================== --- trunk/src/http/ngx_http_request.h 2013-02-18 11:35:28 UTC (rev 5072) +++ trunk/src/http/ngx_http_request.h 2013-02-18 13:50:52 UTC (rev 5073) @@ -64,6 +64,10 @@ #define NGX_HTTP_LOG_UNSAFE 8 +#define NGX_HTTP_CONTINUE 100 +#define NGX_HTTP_SWITCHING_PROTOCOLS 101 +#define NGX_HTTP_PROCESSING 102 + #define NGX_HTTP_OK 200 #define NGX_HTTP_CREATED 201 #define NGX_HTTP_ACCEPTED 202 @@ -184,6 +188,7 @@ ngx_table_elt_t *transfer_encoding; ngx_table_elt_t *expect; + ngx_table_elt_t *upgrade; #if (NGX_HTTP_GZIP) ngx_table_elt_t *accept_encoding; Modified: trunk/src/http/ngx_http_upstream.c =================================================================== --- trunk/src/http/ngx_http_upstream.c 2013-02-18 11:35:28 UTC (rev 5072) +++ trunk/src/http/ngx_http_upstream.c 2013-02-18 13:50:52 UTC (rev 5073) @@ -46,6 +46,16 @@ ngx_http_upstream_t *u); static void ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u); +static void ngx_http_upstream_upgrade(ngx_http_request_t *r, + ngx_http_upstream_t *u); +static void ngx_http_upstream_upgraded_read_downstream(ngx_http_request_t *r); +static void ngx_http_upstream_upgraded_write_downstream(ngx_http_request_t *r); +static void ngx_http_upstream_upgraded_read_upstream(ngx_http_request_t *r, + ngx_http_upstream_t *u); +static void ngx_http_upstream_upgraded_write_upstream(ngx_http_request_t *r, + ngx_http_upstream_t *u); +static void ngx_http_upstream_process_upgraded(ngx_http_request_t *r, + ngx_uint_t from_upstream); static void ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r); static void @@ -1327,6 +1337,7 @@ } u->keepalive = 0; + u->upgrade = 0; ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t)); u->headers_in.content_length_n = -1; @@ -2078,6 +2089,11 @@ return; } + if (u->upgrade) { + ngx_http_upstream_upgrade(r, u); + return; + } + c = r->connection; if (r->header_only) { @@ -2361,6 +2377,278 @@ static void +ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u) +{ + int tcp_nodelay; + ngx_connection_t *c; + ngx_http_core_loc_conf_t *clcf; + + c = r->connection; + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + /* TODO: prevent upgrade if not requested or not possible */ + + r->keepalive = 0; + c->log->action = "proxying upgraded connection"; + + u->read_event_handler = ngx_http_upstream_upgraded_read_upstream; + u->write_event_handler = ngx_http_upstream_upgraded_write_upstream; + r->read_event_handler = ngx_http_upstream_upgraded_read_downstream; + r->write_event_handler = ngx_http_upstream_upgraded_write_downstream; + + if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay"); + + tcp_nodelay = 1; + + if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, + (const void *) &tcp_nodelay, sizeof(int)) == -1) + { + ngx_connection_error(c, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + c->tcp_nodelay = NGX_TCP_NODELAY_SET; + + if (setsockopt(u->peer.connection->fd, IPPROTO_TCP, TCP_NODELAY, + (const void *) &tcp_nodelay, sizeof(int)) == -1) + { + ngx_connection_error(u->peer.connection, ngx_socket_errno, + "setsockopt(TCP_NODELAY) failed"); + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + u->peer.connection->tcp_nodelay = NGX_TCP_NODELAY_SET; + } + + if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) { + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + if (u->peer.connection->read->ready + || u->buffer.pos != u->buffer.last) + { + ngx_http_upstream_process_upgraded(r, 1); + } + + if (c->read->ready + || r->header_in->pos != r->header_in->last) + { + ngx_http_upstream_process_upgraded(r, 0); + } +} + + +static void +ngx_http_upstream_upgraded_read_downstream(ngx_http_request_t *r) +{ + ngx_http_upstream_process_upgraded(r, 0); +} + + +static void +ngx_http_upstream_upgraded_write_downstream(ngx_http_request_t *r) +{ + ngx_http_upstream_process_upgraded(r, 1); +} + + +static void +ngx_http_upstream_upgraded_read_upstream(ngx_http_request_t *r, + ngx_http_upstream_t *u) +{ + ngx_http_upstream_process_upgraded(r, 1); +} + + +static void +ngx_http_upstream_upgraded_write_upstream(ngx_http_request_t *r, + ngx_http_upstream_t *u) +{ + ngx_http_upstream_process_upgraded(r, 0); +} + + +static void +ngx_http_upstream_process_upgraded(ngx_http_request_t *r, + ngx_uint_t from_upstream) +{ + size_t size; + ssize_t n; + ngx_buf_t *b; + ngx_uint_t do_write; + ngx_connection_t *c, *downstream, *upstream, *dst, *src; + ngx_http_upstream_t *u; + ngx_http_core_loc_conf_t *clcf; + + c = r->connection; + u = r->upstream; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http upstream process upgraded, fu:%ui", from_upstream); + + downstream = c; + upstream = u->peer.connection; + + if (downstream->write->timedout) { + c->timedout = 1; + ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out"); + ngx_http_upstream_finalize_request(r, u, NGX_HTTP_REQUEST_TIME_OUT); + return; + } + + if (upstream->read->timedout || upstream->write->timedout) { + ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out"); + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + if (from_upstream) { + src = upstream; + dst = downstream; + b = &u->buffer; + + } else { + src = downstream; + dst = upstream; + b = &u->from_client; + + if (r->header_in->last > r->header_in->pos) { + b = r->header_in; + b->end = b->last; + do_write = 1; + } + + if (b->start == NULL) { + b->start = ngx_palloc(r->pool, u->conf->buffer_size); + if (b->start == NULL) { + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + b->pos = b->start; + b->last = b->start; + b->end = b->start + u->conf->buffer_size; + b->temporary = 1; + b->tag = u->output.tag; + } + } + + for ( ;; ) { + + if (do_write) { + + size = b->last - b->pos; + + if (size && dst->write->ready) { + + n = dst->send(dst, b->pos, size); + + if (n == NGX_ERROR) { + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + if (n > 0) { + b->pos += n; + + if (b->pos == b->last) { + b->pos = b->start; + b->last = b->start; + } + } + } + } + + size = b->end - b->last; + + if (size && src->read->ready) { + + n = src->recv(src, b->last, size); + + if (n == NGX_AGAIN || n == 0) { + break; + } + + if (n > 0) { + do_write = 1; + b->last += n; + + continue; + } + + if (n == NGX_ERROR) { + src->read->eof = 1; + } + } + + break; + } + + if ((upstream->read->eof && u->buffer.pos == u->buffer.last) + || (downstream->read->eof && u->from_client.pos == u->from_client.last) + || (downstream->read->eof && upstream->read->eof)) + { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http upstream upgraded done"); + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (ngx_handle_write_event(upstream->write, u->conf->send_lowat) + != NGX_OK) + { + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + if (upstream->write->active && !upstream->write->ready) { + ngx_add_timer(upstream->write, u->conf->send_timeout); + + } else if (upstream->write->timer_set) { + ngx_del_timer(upstream->write); + } + + if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) { + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + if (upstream->read->active && !upstream->read->ready) { + ngx_add_timer(upstream->read, u->conf->read_timeout); + + } else if (upstream->read->timer_set) { + ngx_del_timer(upstream->read); + } + + if (ngx_handle_write_event(downstream->write, clcf->send_lowat) + != NGX_OK) + { + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + if (ngx_handle_read_event(downstream->read, 0) != NGX_OK) { + ngx_http_upstream_finalize_request(r, u, 0); + return; + } + + if (downstream->write->active && !downstream->write->ready) { + ngx_add_timer(downstream->write, clcf->send_timeout); + + } else if (downstream->write->timer_set) { + ngx_del_timer(downstream->write); + } +} + + +static void ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r) { ngx_event_t *wev; Modified: trunk/src/http/ngx_http_upstream.h =================================================================== --- trunk/src/http/ngx_http_upstream.h 2013-02-18 11:35:28 UTC (rev 5072) +++ trunk/src/http/ngx_http_upstream.h 2013-02-18 13:50:52 UTC (rev 5073) @@ -284,6 +284,8 @@ ngx_http_upstream_resolved_t *resolved; + ngx_buf_t from_client; + ngx_buf_t buffer; off_t length; @@ -329,6 +331,7 @@ unsigned buffering:1; unsigned keepalive:1; + unsigned upgrade:1; unsigned request_sent:1; unsigned header_sent:1; Modified: trunk/src/http/ngx_http_variables.c =================================================================== --- trunk/src/http/ngx_http_variables.c 2013-02-18 11:35:28 UTC (rev 5072) +++ trunk/src/http/ngx_http_variables.c 2013-02-18 13:50:52 UTC (rev 5073) @@ -1747,7 +1747,11 @@ size_t len; char *p; - if (r->keepalive) { + if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) { + len = sizeof("upgrade") - 1; + p = "upgrade"; + + } else if (r->keepalive) { len = sizeof("keep-alive") - 1; p = "keep-alive"; From mdounin at mdounin.ru Mon Feb 18 15:08:46 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Mon, 18 Feb 2013 15:08:46 +0000 Subject: [nginx] svn commit: r5074 - trunk/src/http Message-ID: <20130218150846.6A7963F9F87@mail.nginx.com> Author: mdounin Date: 2013-02-18 15:08:46 +0000 (Mon, 18 Feb 2013) New Revision: 5074 URL: http://trac.nginx.org/nginx/changeset/5074/nginx Log: Proxy: fixed do_write handling in previous commit. As rightfully complained by MSVC, do_write variable was used uninitialized. Correct fix is to set it's initial value based on event happened. Modified: trunk/src/http/ngx_http_upstream.c Modified: trunk/src/http/ngx_http_upstream.c =================================================================== --- trunk/src/http/ngx_http_upstream.c 2013-02-18 13:50:52 UTC (rev 5073) +++ trunk/src/http/ngx_http_upstream.c 2013-02-18 15:08:46 UTC (rev 5074) @@ -55,7 +55,7 @@ static void ngx_http_upstream_upgraded_write_upstream(ngx_http_request_t *r, ngx_http_upstream_t *u); static void ngx_http_upstream_process_upgraded(ngx_http_request_t *r, - ngx_uint_t from_upstream); + ngx_uint_t from_upstream, ngx_uint_t do_write); static void ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r); static void @@ -2432,13 +2432,13 @@ if (u->peer.connection->read->ready || u->buffer.pos != u->buffer.last) { - ngx_http_upstream_process_upgraded(r, 1); + ngx_http_upstream_process_upgraded(r, 1, 1); } if (c->read->ready || r->header_in->pos != r->header_in->last) { - ngx_http_upstream_process_upgraded(r, 0); + ngx_http_upstream_process_upgraded(r, 0, 1); } } @@ -2446,14 +2446,14 @@ static void ngx_http_upstream_upgraded_read_downstream(ngx_http_request_t *r) { - ngx_http_upstream_process_upgraded(r, 0); + ngx_http_upstream_process_upgraded(r, 0, 0); } static void ngx_http_upstream_upgraded_write_downstream(ngx_http_request_t *r) { - ngx_http_upstream_process_upgraded(r, 1); + ngx_http_upstream_process_upgraded(r, 1, 1); } @@ -2461,7 +2461,7 @@ ngx_http_upstream_upgraded_read_upstream(ngx_http_request_t *r, ngx_http_upstream_t *u) { - ngx_http_upstream_process_upgraded(r, 1); + ngx_http_upstream_process_upgraded(r, 1, 0); } @@ -2469,18 +2469,17 @@ ngx_http_upstream_upgraded_write_upstream(ngx_http_request_t *r, ngx_http_upstream_t *u) { - ngx_http_upstream_process_upgraded(r, 0); + ngx_http_upstream_process_upgraded(r, 0, 1); } static void ngx_http_upstream_process_upgraded(ngx_http_request_t *r, - ngx_uint_t from_upstream) + ngx_uint_t from_upstream, ngx_uint_t do_write) { size_t size; ssize_t n; ngx_buf_t *b; - ngx_uint_t do_write; ngx_connection_t *c, *downstream, *upstream, *dst, *src; ngx_http_upstream_t *u; ngx_http_core_loc_conf_t *clcf; From vbart at nginx.com Mon Feb 18 17:36:59 2013 From: vbart at nginx.com (Valentin V. Bartenev) Date: Mon, 18 Feb 2013 21:36:59 +0400 Subject: SPDY: failure loading large gzipped files In-Reply-To: <20130203235926.GA22930@jasondavies.com> References: <20130203235926.GA22930@jasondavies.com> Message-ID: <201302182136.59656.vbart@nginx.com> On Monday 04 February 2013 03:59:26 Jason Davies wrote: > I'm using nginx 1.3.11-9chl1~quantal1 from Chris Lea's PPA (which I > believe is using the latest SPDY patch, patch.spdy-60_1.3.11.txt). > > Generate a large file containing random characters, e.g. using the > following Python script (~10MB): > > import random > f = open("10m.html", "w") > f.write("\n".join(map( > lambda x: "".join(map( > lambda x: random.choice("0123456789abcdef"), > range(100) > )), > range(100000) > ))) > f.close() > > Ensure that gzip is on, and gzip_types contains the appropriate file > type (text/html in this case). > > Chrome and Firefox both fail to completely load the file; they just hang > indefinitely after loading what appears to be around 1MB, though it's > hard to tell exactly from Chrome's Network tab. > > Turning off gzip fixes the issue. If there's a way to selectively > disable gzip for SPDY requests, that would also be useful to know. > > Thanks, Fixed in http://nginx.org/patches/spdy/patch.spdy-63_1.3.12.txt wbr, Valentin V. Bartenev -- http://nginx.com/support.html http://nginx.org/en/donation.html From mdounin at mdounin.ru Tue Feb 19 15:14:50 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Tue, 19 Feb 2013 15:14:50 +0000 Subject: [nginx] svn commit: r5075 - trunk/docs/xml/nginx Message-ID: <20130219151450.E25A33F9C5F@mail.nginx.com> Author: mdounin Date: 2013-02-19 15:14:48 +0000 (Tue, 19 Feb 2013) New Revision: 5075 URL: http://trac.nginx.org/nginx/changeset/5075/nginx Log: nginx-1.3.13-RELEASE Modified: trunk/docs/xml/nginx/changes.xml Modified: trunk/docs/xml/nginx/changes.xml =================================================================== --- trunk/docs/xml/nginx/changes.xml 2013-02-18 15:08:46 UTC (rev 5074) +++ trunk/docs/xml/nginx/changes.xml 2013-02-19 15:14:48 UTC (rev 5075) @@ -4,6 +4,45 @@ + + + + + +?????? ??? ?????? ?? ????????? ???????????? ?????????? ? ?????? "cc". + + +a compiler with name "cc" is now used by default. + + + + + +????????? ????????????? WebSocket-??????????.
+??????? Apcera ? CloudBees ?? ????????????? ??????????. +
+ +support for proxying of WebSocket connections.
+Thanks to Apcera and CloudBees for sponsoring this work. +
+
+ + + +????????? auth_basic_user_file ???????????? ?????????? ??????? +??????? "{SHA}".
+??????? Louis Opter. +
+ +the "auth_basic_user_file" directive supports "{SHA}" +password encryption method.
+Thanks to Louis Opter. +
+
+ +
+ + From mdounin at mdounin.ru Tue Feb 19 15:15:12 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Tue, 19 Feb 2013 15:15:12 +0000 Subject: [nginx] svn commit: r5076 - tags Message-ID: <20130219151512.56B423F9C5F@mail.nginx.com> Author: mdounin Date: 2013-02-19 15:15:11 +0000 (Tue, 19 Feb 2013) New Revision: 5076 URL: http://trac.nginx.org/nginx/changeset/5076/nginx Log: release-1.3.13 tag Added: tags/release-1.3.13/ From vbart at nginx.com Tue Feb 19 17:45:14 2013 From: vbart at nginx.com (vbart at nginx.com) Date: Tue, 19 Feb 2013 17:45:14 +0000 Subject: [nginx] svn commit: r5077 - in trunk/src: core http/modules/perl Message-ID: <20130219174514.736F13FAA7D@mail.nginx.com> Author: vbart Date: 2013-02-19 17:45:12 +0000 (Tue, 19 Feb 2013) New Revision: 5077 URL: http://trac.nginx.org/nginx/changeset/5077/nginx Log: Version bump. Modified: trunk/src/core/nginx.h trunk/src/http/modules/perl/nginx.pm Modified: trunk/src/core/nginx.h =================================================================== --- trunk/src/core/nginx.h 2013-02-19 15:15:11 UTC (rev 5076) +++ trunk/src/core/nginx.h 2013-02-19 17:45:12 UTC (rev 5077) @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1003013 -#define NGINX_VERSION "1.3.13" +#define nginx_version 1003014 +#define NGINX_VERSION "1.3.14" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" Modified: trunk/src/http/modules/perl/nginx.pm =================================================================== --- trunk/src/http/modules/perl/nginx.pm 2013-02-19 15:15:11 UTC (rev 5076) +++ trunk/src/http/modules/perl/nginx.pm 2013-02-19 17:45:12 UTC (rev 5077) @@ -50,7 +50,7 @@ HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '1.3.13'; +our $VERSION = '1.3.14'; require XSLoader; XSLoader::load('nginx', $VERSION); From vbart at nginx.com Tue Feb 19 17:48:46 2013 From: vbart at nginx.com (vbart at nginx.com) Date: Tue, 19 Feb 2013 17:48:46 +0000 Subject: [nginx] svn commit: r5078 - in trunk/src/http: . modules Message-ID: <20130219174846.82EC63FAB22@mail.nginx.com> Author: vbart Date: 2013-02-19 17:48:45 +0000 (Tue, 19 Feb 2013) New Revision: 5078 URL: http://trac.nginx.org/nginx/changeset/5078/nginx Log: Removed zero termination of shm zone names. It was added in r2717 and no longer needed since r2721, where the termination was added to ngx_shm_alloc() and ngx_init_zone_pool(). So then it only corrupts error messages about ivalid zones. Modified: trunk/src/http/modules/ngx_http_ssl_module.c trunk/src/http/ngx_http_file_cache.c Modified: trunk/src/http/modules/ngx_http_ssl_module.c =================================================================== --- trunk/src/http/modules/ngx_http_ssl_module.c 2013-02-19 17:45:12 UTC (rev 5077) +++ trunk/src/http/modules/ngx_http_ssl_module.c 2013-02-19 17:48:45 UTC (rev 5078) @@ -661,7 +661,6 @@ for (j = sizeof("shared:") - 1; j < value[i].len; j++) { if (value[i].data[j] == ':') { - value[i].data[j] = '\0'; break; } Modified: trunk/src/http/ngx_http_file_cache.c =================================================================== --- trunk/src/http/ngx_http_file_cache.c 2013-02-19 17:45:12 UTC (rev 5077) +++ trunk/src/http/ngx_http_file_cache.c 2013-02-19 17:48:45 UTC (rev 5078) @@ -1674,8 +1674,6 @@ p = (u_char *) ngx_strchr(name.data, ':'); if (p) { - *p = '\0'; - name.len = p - name.data; p++; From mdounin at mdounin.ru Wed Feb 20 13:50:54 2013 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 20 Feb 2013 17:50:54 +0400 Subject: [PATCH] websockets support for uwsgi protocol In-Reply-To: <7e944b12d0024dd29d89ffec3e743a09.squirrel@manage.unbit.it> References: <7e944b12d0024dd29d89ffec3e743a09.squirrel@manage.unbit.it> Message-ID: <20130220135054.GW81985@mdounin.ru> Hello! (Cc'd nginx-devel@ as this is better list for this discussion.) On Wed, Feb 20, 2013 at 02:30:38PM +0100, Roberto De Ioris wrote: > Hi, the (tiny) attached patch enable support for new websockets handling > when the uwsgi protocol is used instead of HTTP. > > I have tested it with various websocket libraries and with the api > available in uWSGI 1.9. > > From 1.9 sources (with nginx pointing to uwsgi port 3031): > > ./uwsgi -s :3031 -w tests.websockets_echo --gevent 10 > > > no additional configuration is needed for nginx Should we also do the same for SCGI? I personally think it is more or less the same for all CGI-based protocols, and the only problematic one is FastCGI, which probably still needs wrapping within FCGI_STDIN/FCGI_STDOUT records instead of real connection upgrade. -- Maxim Dounin http://nginx.com/support.html From roberto at unbit.it Wed Feb 20 13:53:07 2013 From: roberto at unbit.it (Roberto De Ioris) Date: Wed, 20 Feb 2013 14:53:07 +0100 Subject: [PATCH] websockets support for uwsgi protocol In-Reply-To: <20130220135054.GW81985@mdounin.ru> References: <7e944b12d0024dd29d89ffec3e743a09.squirrel@manage.unbit.it> <20130220135054.GW81985@mdounin.ru> Message-ID: <8b097697f2ec8602e609a78209cdab58.squirrel@manage.unbit.it> > Hello! > > (Cc'd nginx-devel@ as this is better list for this discussion.) > > On Wed, Feb 20, 2013 at 02:30:38PM +0100, Roberto De Ioris wrote: > >> Hi, the (tiny) attached patch enable support for new websockets handling >> when the uwsgi protocol is used instead of HTTP. >> >> I have tested it with various websocket libraries and with the api >> available in uWSGI 1.9. >> >> From 1.9 sources (with nginx pointing to uwsgi port 3031): >> >> ./uwsgi -s :3031 -w tests.websockets_echo --gevent 10 >> >> >> no additional configuration is needed for nginx > > Should we also do the same for SCGI? > > I personally think it is more or less the same for all CGI-based > protocols, and the only problematic one is FastCGI, which probably > still needs wrapping within FCGI_STDIN/FCGI_STDOUT records instead > of real connection upgrade. > > AFAIK scgi body management works in the same way as the uwsgi one, so the patch should be usable there too -- Roberto De Ioris http://unbit.it From roberto at unbit.it Wed Feb 20 14:07:53 2013 From: roberto at unbit.it (Roberto De Ioris) Date: Wed, 20 Feb 2013 15:07:53 +0100 Subject: [PATCH] websockets support for uwsgi protocol In-Reply-To: <8b097697f2ec8602e609a78209cdab58.squirrel@manage.unbit.it> References: <7e944b12d0024dd29d89ffec3e743a09.squirrel@manage.unbit.it> <20130220135054.GW81985@mdounin.ru> <8b097697f2ec8602e609a78209cdab58.squirrel@manage.unbit.it> Message-ID: > >> Hello! >> >> (Cc'd nginx-devel@ as this is better list for this discussion.) >> >> On Wed, Feb 20, 2013 at 02:30:38PM +0100, Roberto De Ioris wrote: >> >>> Hi, the (tiny) attached patch enable support for new websockets >>> handling >>> when the uwsgi protocol is used instead of HTTP. >>> >>> I have tested it with various websocket libraries and with the api >>> available in uWSGI 1.9. >>> >>> From 1.9 sources (with nginx pointing to uwsgi port 3031): >>> >>> ./uwsgi -s :3031 -w tests.websockets_echo --gevent 10 >>> >>> >>> no additional configuration is needed for nginx >> >> Should we also do the same for SCGI? >> >> I personally think it is more or less the same for all CGI-based >> protocols, and the only problematic one is FastCGI, which probably >> still needs wrapping within FCGI_STDIN/FCGI_STDOUT records instead >> of real connection upgrade. >> >> > > AFAIK scgi body management works in the same way as the uwsgi one, so the > patch should be usable there too Ok, i can confirm the same patch applied to the SCGI module in the same position works (at least with uWSGI 1.9 in SCGI mode) ./uwsgi --scgi-nph-socket :3031 -w tests.websockets_echo --gevent 10 remember to add scgi_param PATH_INFO $document_uri; to the nginx config to make it work -- Roberto De Ioris http://unbit.it From mdounin at mdounin.ru Wed Feb 20 15:11:49 2013 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 20 Feb 2013 19:11:49 +0400 Subject: [PATCH] websockets support for uwsgi protocol In-Reply-To: References: <7e944b12d0024dd29d89ffec3e743a09.squirrel@manage.unbit.it> <20130220135054.GW81985@mdounin.ru> <8b097697f2ec8602e609a78209cdab58.squirrel@manage.unbit.it> Message-ID: <20130220151149.GX81985@mdounin.ru> Hello! On Wed, Feb 20, 2013 at 03:07:53PM +0100, Roberto De Ioris wrote: > > > > >> Hello! > >> > >> (Cc'd nginx-devel@ as this is better list for this discussion.) > >> > >> On Wed, Feb 20, 2013 at 02:30:38PM +0100, Roberto De Ioris wrote: > >> > >>> Hi, the (tiny) attached patch enable support for new websockets > >>> handling > >>> when the uwsgi protocol is used instead of HTTP. > >>> > >>> I have tested it with various websocket libraries and with the api > >>> available in uWSGI 1.9. > >>> > >>> From 1.9 sources (with nginx pointing to uwsgi port 3031): > >>> > >>> ./uwsgi -s :3031 -w tests.websockets_echo --gevent 10 > >>> > >>> > >>> no additional configuration is needed for nginx > >> > >> Should we also do the same for SCGI? > >> > >> I personally think it is more or less the same for all CGI-based > >> protocols, and the only problematic one is FastCGI, which probably > >> still needs wrapping within FCGI_STDIN/FCGI_STDOUT records instead > >> of real connection upgrade. > >> > >> > > > > AFAIK scgi body management works in the same way as the uwsgi one, so the > > patch should be usable there too > > > Ok, i can confirm the same patch applied to the SCGI module in the same > position works (at least with uWSGI 1.9 in SCGI mode) > > ./uwsgi --scgi-nph-socket :3031 -w tests.websockets_echo --gevent 10 > > remember to add > > scgi_param PATH_INFO $document_uri; > > to the nginx config to make it work Ok, so the next question is: any specific reason to exclude normal CGI responses with "Status" as in your patch? I in fact don't like the idea of supporting http-like answers with status like from CGI-like protocols, correct way is to use "Status" header. Not sure why Manlio introduced it at all, probably due to some compatibility concerns (and due to the fact that SCGI specification explicitly refuses to specify response format). Something like this should be better, IMHO: diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c --- a/src/http/modules/ngx_http_scgi_module.c +++ b/src/http/modules/ngx_http_scgi_module.c @@ -984,7 +984,7 @@ ngx_http_scgi_process_header(ngx_http_re u = r->upstream; if (u->headers_in.status_n) { - return NGX_OK; + goto done; } if (u->headers_in.status) { @@ -1015,6 +1015,14 @@ ngx_http_scgi_process_header(ngx_http_re u->state->status = u->headers_in.status_n; } + done: + + if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS + && r->headers_in.upgrade) + { + u->upgrade = 1; + } + return NGX_OK; } diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -1018,7 +1018,7 @@ ngx_http_uwsgi_process_header(ngx_http_r u = r->upstream; if (u->headers_in.status_n) { - return NGX_OK; + goto done; } if (u->headers_in.status) { @@ -1049,6 +1049,14 @@ ngx_http_uwsgi_process_header(ngx_http_r u->state->status = u->headers_in.status_n; } + done: + + if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS + && r->headers_in.upgrade) + { + u->upgrade = 1; + } + return NGX_OK; } -- Maxim Dounin http://nginx.com/support.html From roberto at unbit.it Wed Feb 20 15:20:29 2013 From: roberto at unbit.it (Roberto De Ioris) Date: Wed, 20 Feb 2013 16:20:29 +0100 Subject: [PATCH] websockets support for uwsgi protocol In-Reply-To: <20130220151149.GX81985@mdounin.ru> References: <7e944b12d0024dd29d89ffec3e743a09.squirrel@manage.unbit.it> <20130220135054.GW81985@mdounin.ru> <8b097697f2ec8602e609a78209cdab58.squirrel@manage.unbit.it> <20130220151149.GX81985@mdounin.ru> Message-ID: > > Ok, so the next question is: any specific reason to exclude normal > CGI responses with "Status" as in your patch? > > I in fact don't like the idea of supporting http-like answers with > status like from CGI-like protocols, correct way is to use > "Status" header. Not sure why Manlio introduced it at all, > probably due to some compatibility concerns (and due to the fact > that SCGI specification explicitly refuses to specify response > format). Honestly i do not remember why Manlio added support for nph (but i have added it to uWSGI SCGI parser too, so in my subconsciuous there should be a good reason :P) regarding your updated patch is better for sure -- Roberto De Ioris http://unbit.it From mdounin at mdounin.ru Wed Feb 20 16:41:06 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Wed, 20 Feb 2013 16:41:06 +0000 Subject: [nginx] svn commit: r5079 - trunk/src/http/modules Message-ID: <20130220164106.A7F793F9C0D@mail.nginx.com> Author: mdounin Date: 2013-02-20 16:41:05 +0000 (Wed, 20 Feb 2013) New Revision: 5079 URL: http://trac.nginx.org/nginx/changeset/5079/nginx Log: Connection upgrade support in uwsgi and scgi modules. Prodded by Roberto De Ioris. Modified: trunk/src/http/modules/ngx_http_scgi_module.c trunk/src/http/modules/ngx_http_uwsgi_module.c Modified: trunk/src/http/modules/ngx_http_scgi_module.c =================================================================== --- trunk/src/http/modules/ngx_http_scgi_module.c 2013-02-19 17:48:45 UTC (rev 5078) +++ trunk/src/http/modules/ngx_http_scgi_module.c 2013-02-20 16:41:05 UTC (rev 5079) @@ -984,7 +984,7 @@ u = r->upstream; if (u->headers_in.status_n) { - return NGX_OK; + goto done; } if (u->headers_in.status) { @@ -1015,6 +1015,14 @@ u->state->status = u->headers_in.status_n; } + done: + + if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS + && r->headers_in.upgrade) + { + u->upgrade = 1; + } + return NGX_OK; } Modified: trunk/src/http/modules/ngx_http_uwsgi_module.c =================================================================== --- trunk/src/http/modules/ngx_http_uwsgi_module.c 2013-02-19 17:48:45 UTC (rev 5078) +++ trunk/src/http/modules/ngx_http_uwsgi_module.c 2013-02-20 16:41:05 UTC (rev 5079) @@ -1018,7 +1018,7 @@ u = r->upstream; if (u->headers_in.status_n) { - return NGX_OK; + goto done; } if (u->headers_in.status) { @@ -1049,6 +1049,14 @@ u->state->status = u->headers_in.status_n; } + done: + + if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS + && r->headers_in.upgrade) + { + u->upgrade = 1; + } + return NGX_OK; } From mdounin at mdounin.ru Wed Feb 20 16:41:37 2013 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 20 Feb 2013 20:41:37 +0400 Subject: [PATCH] websockets support for uwsgi protocol In-Reply-To: References: <7e944b12d0024dd29d89ffec3e743a09.squirrel@manage.unbit.it> <20130220135054.GW81985@mdounin.ru> <8b097697f2ec8602e609a78209cdab58.squirrel@manage.unbit.it> <20130220151149.GX81985@mdounin.ru> Message-ID: <20130220164137.GA81985@mdounin.ru> Hello! On Wed, Feb 20, 2013 at 04:20:29PM +0100, Roberto De Ioris wrote: > > > > > Ok, so the next question is: any specific reason to exclude normal > > CGI responses with "Status" as in your patch? > > > > I in fact don't like the idea of supporting http-like answers with > > status like from CGI-like protocols, correct way is to use > > "Status" header. Not sure why Manlio introduced it at all, > > probably due to some compatibility concerns (and due to the fact > > that SCGI specification explicitly refuses to specify response > > format). > > Honestly i do not remember why Manlio added support for nph (but i have > added it to uWSGI SCGI parser too, so in my subconsciuous there should be > a good reason :P) > > regarding your updated patch is better for sure Committed, thnx. -- Maxim Dounin http://nginx.com/support.html From defan at nginx.com Thu Feb 21 23:31:57 2013 From: defan at nginx.com (defan at nginx.com) Date: Thu, 21 Feb 2013 23:31:57 +0000 Subject: [nginx] svn commit: r5080 - trunk/src/http/modules Message-ID: <20130221233157.8D0F43FAC90@mail.nginx.com> Author: defan Date: 2013-02-21 23:31:57 +0000 (Thu, 21 Feb 2013) New Revision: 5080 URL: http://trac.nginx.org/nginx/changeset/5080/nginx Log: Introduced variables in ngx_http_stub_status module. Three new variables were added: $connections_active, $connections_reading and $connections_writing. Modified: trunk/src/http/modules/ngx_http_stub_status_module.c Modified: trunk/src/http/modules/ngx_http_stub_status_module.c =================================================================== --- trunk/src/http/modules/ngx_http_stub_status_module.c 2013-02-20 16:41:05 UTC (rev 5079) +++ trunk/src/http/modules/ngx_http_stub_status_module.c 2013-02-21 23:31:57 UTC (rev 5080) @@ -10,6 +10,10 @@ #include +static ngx_int_t ngx_http_stub_status_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_stub_status_add_variables(ngx_conf_t *cf); + static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -28,7 +32,7 @@ static ngx_http_module_t ngx_http_stub_status_module_ctx = { - NULL, /* preconfiguration */ + ngx_http_stub_status_add_variables, /* preconfiguration */ NULL, /* postconfiguration */ NULL, /* create main configuration */ @@ -58,6 +62,21 @@ }; +static ngx_http_variable_t ngx_http_stub_status_vars[] = { + + { ngx_string("connections_active"), NULL, ngx_http_stub_status_variable, + 0, NGX_HTTP_VAR_NOCACHEABLE, 0 }, + + { ngx_string("connections_reading"), NULL, ngx_http_stub_status_variable, + 1, NGX_HTTP_VAR_NOCACHEABLE, 0 }, + + { ngx_string("connections_writing"), NULL, ngx_http_stub_status_variable, + 2, NGX_HTTP_VAR_NOCACHEABLE, 0 }, + + { ngx_null_string, NULL, NULL, 0, 0, 0 } +}; + + static ngx_int_t ngx_http_status_handler(ngx_http_request_t *r) { size_t size; @@ -133,6 +152,66 @@ } +static ngx_int_t +ngx_http_stub_status_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + u_char *p; + ngx_atomic_int_t value; + + p = ngx_pnalloc(r->pool, NGX_ATOMIC_T_LEN); + if (p == NULL) { + return NGX_ERROR; + } + + switch (data) { + case 0: + value = *ngx_stat_active; + break; + + case 1: + value = *ngx_stat_reading; + break; + + case 2: + value = *ngx_stat_writing; + break; + + /* suppress warning */ + default: + value = 0; + break; + } + + v->len = ngx_sprintf(p, "%uA", value) - p; + v->valid = 1; + v->no_cacheable = 0; + v->not_found = 0; + v->data = p; + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_stub_status_add_variables(ngx_conf_t *cf) +{ + ngx_http_variable_t *var, *v; + + for (v = ngx_http_stub_status_vars; v->name.len; v++) { + var = ngx_http_add_variable(cf, &v->name, v->flags); + if (var == NULL) { + return NGX_ERROR; + } + + var->get_handler = v->get_handler; + var->data = v->data; + } + + return NGX_OK; +} + + static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_core_loc_conf_t *clcf; From ibobrik at gmail.com Fri Feb 22 05:52:42 2013 From: ibobrik at gmail.com (ivan babrou) Date: Fri, 22 Feb 2013 09:52:42 +0400 Subject: image_filter enhancement In-Reply-To: References: <20121127160328.GZ40452@mdounin.ru> <20121204130841.GI40452@mdounin.ru> <20121205145244.GO40452@mdounin.ru> <20121218105341.GK40452@mdounin.ru> <20121225160542.GD40452@mdounin.ru> Message-ID: Is there anything else I should fix? On 7 January 2013 17:01, ivan babrou wrote: > Btw, here's latest version with zero-termination and other fixes: > > diff --git a/ngx_http_image_filter_module.c > b/ngx_http_image_filter_module.c > index 3aee1a4..b086e3c 100644 > --- a/ngx_http_image_filter_module.c > +++ b/ngx_http_image_filter_module.c > @@ -32,6 +32,11 @@ > #define NGX_HTTP_IMAGE_GIF 2 > #define NGX_HTTP_IMAGE_PNG 3 > > +#define NGX_HTTP_IMAGE_OFFSET_CENTER 0 > +#define NGX_HTTP_IMAGE_OFFSET_LEFT 1 > +#define NGX_HTTP_IMAGE_OFFSET_RIGHT 2 > +#define NGX_HTTP_IMAGE_OFFSET_TOP 3 > +#define NGX_HTTP_IMAGE_OFFSET_BOTTOM 4 > > #define NGX_HTTP_IMAGE_BUFFERED 0x08 > > @@ -43,11 +48,15 @@ typedef struct { > ngx_uint_t angle; > ngx_uint_t jpeg_quality; > ngx_uint_t sharpen; > + ngx_uint_t offset_x; > + ngx_uint_t offset_y; > > ngx_flag_t transparency; > > ngx_http_complex_value_t *wcv; > ngx_http_complex_value_t *hcv; > + ngx_http_complex_value_t *oxcv; > + ngx_http_complex_value_t *oycv; > ngx_http_complex_value_t *acv; > ngx_http_complex_value_t *jqcv; > ngx_http_complex_value_t *shcv; > @@ -66,6 +75,8 @@ typedef struct { > ngx_uint_t height; > ngx_uint_t max_width; > ngx_uint_t max_height; > + ngx_uint_t offset_x; > + ngx_uint_t offset_y; > ngx_uint_t angle; > > ngx_uint_t phase; > @@ -110,6 +121,8 @@ static char > *ngx_http_image_filter_jpeg_quality(ngx_conf_t *cf, > ngx_command_t *cmd, void *conf); > static char *ngx_http_image_filter_sharpen(ngx_conf_t *cf, ngx_command_t > *cmd, > void *conf); > +static char *ngx_http_image_filter_offset(ngx_conf_t *cf, ngx_command_t > *cmd, > + void *conf); > static ngx_int_t ngx_http_image_filter_init(ngx_conf_t *cf); > > > @@ -150,6 +163,13 @@ static ngx_command_t > ngx_http_image_filter_commands[] = { > offsetof(ngx_http_image_filter_conf_t, buffer_size), > NULL }, > > + { ngx_string("image_filter_crop_offset"), > + > NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, > + ngx_http_image_filter_offset, > + NGX_HTTP_LOC_CONF_OFFSET, > + 0, > + NULL }, > + > ngx_null_command > }; > > @@ -737,7 +757,8 @@ ngx_http_image_resize(ngx_http_request_t *r, > ngx_http_image_filter_ctx_t *ctx) > { > int sx, sy, dx, dy, ox, oy, ax, ay, size, > colors, palette, transparent, sharpen, > - red, green, blue, t; > + red, green, blue, t, > + offset_x, offset_y; > u_char *out; > ngx_buf_t *b; > ngx_uint_t resize; > @@ -932,8 +953,24 @@ transparent: > return NULL; > } > > - ox /= 2; > - oy /= 2; > + offset_x = ngx_http_image_filter_get_value(r, conf->oxcv, > + conf->offset_x); > + offset_y = ngx_http_image_filter_get_value(r, conf->oycv, > + conf->offset_y); > + > + if (offset_x == NGX_HTTP_IMAGE_OFFSET_LEFT) { > + ox = 0; > + > + } else if (offset_x == NGX_HTTP_IMAGE_OFFSET_CENTER) { > + ox /= 2; > + } > + > + if (offset_y == NGX_HTTP_IMAGE_OFFSET_TOP) { > + oy = 0; > + > + } else if (offset_y == NGX_HTTP_IMAGE_OFFSET_CENTER) { > + oy /= 2; > + } > > ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, > "image crop: %d x %d @ %d x %d", > @@ -1141,17 +1178,43 @@ ngx_http_image_filter_get_value(ngx_http_request_t > *r, > > > static ngx_uint_t > -ngx_http_image_filter_value(ngx_str_t *value) > +ngx_http_image_filter_value(ngx_str_t *v) > { > ngx_int_t n; > > - if (value->len == 1 && value->data[0] == '-') { > + if (v->len == 1 && v->data[0] == '-') { > return (ngx_uint_t) -1; > } > > - n = ngx_atoi(value->data, value->len); > + n = ngx_atoi(v->data, v->len); > + > + if (n == NGX_ERROR) { > + > + if (v->len == sizeof("left") - 1 > + && ngx_strncmp(v->data, "left", v->len) == 0) > + { > + return NGX_HTTP_IMAGE_OFFSET_LEFT; > + > + } else if (v->len == sizeof("right") - 1 > + && ngx_strncmp(v->data, "right", sizeof("right") - 1) > == 0) > + { > + return NGX_HTTP_IMAGE_OFFSET_RIGHT; > + > + } else if (v->len == sizeof("top") - 1 > + && ngx_strncmp(v->data, "top", sizeof("top") - 1) == 0) > + { > + return NGX_HTTP_IMAGE_OFFSET_TOP; > > - if (n > 0) { > + } else if (v->len == sizeof("bottom") - 1 > + && ngx_strncmp(v->data, "bottom", sizeof("bottom") - > 1) == 0) > + { > + return NGX_HTTP_IMAGE_OFFSET_BOTTOM; > + > + } else { > + return NGX_HTTP_IMAGE_OFFSET_CENTER; > + } > + > + } else if (n > 0) { > return (ngx_uint_t) n; > } > > @@ -1175,6 +1238,8 @@ ngx_http_image_filter_create_conf(ngx_conf_t *cf) > conf->angle = NGX_CONF_UNSET_UINT; > conf->transparency = NGX_CONF_UNSET; > conf->buffer_size = NGX_CONF_UNSET_SIZE; > + conf->offset_x = NGX_CONF_UNSET_UINT; > + conf->offset_y = NGX_CONF_UNSET_UINT; > > return conf; > } > @@ -1230,6 +1295,24 @@ ngx_http_image_filter_merge_conf(ngx_conf_t *cf, > void *parent, void *child) > ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, > 1 * 1024 * 1024); > > + if (conf->offset_x == NGX_CONF_UNSET_UINT) { > + ngx_conf_merge_uint_value(conf->offset_x, prev->offset_x, > + NGX_HTTP_IMAGE_OFFSET_CENTER); > + > + if (conf->oxcv == NULL) { > + conf->oxcv = prev->oxcv; > + } > + } > + > + if (conf->offset_y == NGX_CONF_UNSET_UINT) { > + ngx_conf_merge_uint_value(conf->offset_y, prev->offset_y, > + NGX_HTTP_IMAGE_OFFSET_CENTER); > + > + if (conf->oycv == NULL) { > + conf->oycv = prev->oycv; > + } > + } > + > return NGX_CONF_OK; > } > > @@ -1481,6 +1564,66 @@ ngx_http_image_filter_sharpen(ngx_conf_t *cf, > ngx_command_t *cmd, > } > > > +static char * > +ngx_http_image_filter_offset(ngx_conf_t *cf, ngx_command_t *cmd, > + void *conf) > +{ > + ngx_http_image_filter_conf_t *imcf = conf; > + > + ngx_str_t *value; > + ngx_http_complex_value_t cv; > + ngx_http_compile_complex_value_t ccv; > + > + value = cf->args->elts; > + > + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); > + > + ccv.cf = cf; > + ccv.value = &value[1]; > + ccv.complex_value = &cv; > + > + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { > + return NGX_CONF_ERROR; > + } > + > + if (cv.lengths == NULL) { > + imcf->offset_x = ngx_http_image_filter_value(&value[1]); > + > + } else { > + imcf->oxcv = ngx_palloc(cf->pool, > sizeof(ngx_http_complex_value_t)); > + if (imcf->oxcv == NULL) { > + return NGX_CONF_ERROR; > + } > + > + *imcf->oxcv = cv; > + } > + > + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); > + > + ccv.cf = cf; > + ccv.value = &value[2]; > + ccv.complex_value = &cv; > + > + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { > + return NGX_CONF_ERROR; > + } > + > + if (cv.lengths == NULL) { > + imcf->offset_y = ngx_http_image_filter_value(&value[2]); > + > + } else { > + imcf->oycv = ngx_palloc(cf->pool, > sizeof(ngx_http_complex_value_t)); > + if (imcf->oycv == NULL) { > + return NGX_CONF_ERROR; > + } > + > + *imcf->oycv = cv; > + } > + > + return NGX_CONF_OK; > +} > + > + > static ngx_int_t > ngx_http_image_filter_init(ngx_conf_t *cf) > { > > > > On 25 December 2012 20:05, Maxim Dounin wrote: > >> Hello! >> >> On Thu, Dec 20, 2012 at 09:01:38PM +0400, ivan babrou wrote: >> >> > I've send patch for configuration semantics in separate thread. >> > >> > Here's lastest version of my patch that may be applied after. Is there >> > something else that I should fix? >> >> I would like to see clarification on how are you going to handle >> just bare numbers specified. As of now the code seems to don't do >> any special processing and seems to assume all values are correct, >> which might not be true and will result in some mostly arbitray >> crop offset selection. It might make sense to actually support >> percents as in Maxim Bublis's patch[1]. >> >> [1] http://mailman.nginx.org/pipermail/nginx-devel/2012-April/002156.html >> >> [...] >> >> > @@ -1151,7 +1188,24 @@ ngx_http_image_filter_value(ngx_str_t *value) >> > >> > n = ngx_atoi(value->data, value->len); >> > >> > - if (n > 0) { >> > + if (n == NGX_ERROR) { >> > + if (ngx_strncmp(value->data, "left", value->len) == 0) { >> > + return NGX_HTTP_IMAGE_OFFSET_LEFT; >> > + >> > + } else if (ngx_strncmp(value->data, "right", value->len) == 0) >> { >> > + return NGX_HTTP_IMAGE_OFFSET_RIGHT; >> > + >> > + } else if (ngx_strncmp(value->data, "top", value->len) == 0) { >> > + return NGX_HTTP_IMAGE_OFFSET_TOP; >> > + >> > + } else if (ngx_strncmp(value->data, "bottom", value->len) == >> 0) { >> > + return NGX_HTTP_IMAGE_OFFSET_BOTTOM; >> > + >> > + } else { >> > + return NGX_HTTP_IMAGE_OFFSET_CENTER; >> > + } >> > + >> > + } else if (n > 0) { >> > return (ngx_uint_t) n; >> > } >> > >> >> The ngx_strncmp() checks are incorrect, see here: >> http://mailman.nginx.org/pipermail/nginx-devel/2012-December/003065.html >> >> You may also move them below "if (n > 0)" the check for better >> readability. >> >> > @@ -1175,6 +1229,8 @@ ngx_http_image_filter_create_conf(ngx_conf_t *cf) >> > conf->angle = NGX_CONF_UNSET_UINT; >> > conf->transparency = NGX_CONF_UNSET; >> > conf->buffer_size = NGX_CONF_UNSET_SIZE; >> > + conf->crop_offset_x = NGX_CONF_UNSET_UINT; >> > + conf->crop_offset_y = NGX_CONF_UNSET_UINT; >> >> The "crop_" prefix probably should be dropped here for better >> readability (and to match other names in the code like "oxcv"). >> >> [...] >> >> -- >> Maxim Dounin >> http://nginx.com/support.html >> >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel at nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-devel >> > > > > -- > Regards, Ian Babrou > http://bobrik.name http://twitter.com/ibobrik skype:i.babrou > -- Regards, Ian Babrou http://bobrik.name http://twitter.com/ibobrik skype:i.babrou -------------- next part -------------- An HTML attachment was scrubbed... URL: From piotr at cloudflare.com Fri Feb 22 22:06:20 2013 From: piotr at cloudflare.com (Piotr Sikora) Date: Fri, 22 Feb 2013 14:06:20 -0800 Subject: [PATCH] Retry failed SSL session cache allocations Message-ID: Hey, in case of fully populated SSL session cache with no memory left for new allocations, ngx_ssl_new_session() will try to expire the oldest non-expired session and retry, but only in case when slab allocation fails for "cached_sess", not when slab allocation fails for either "sess_id" or "id", which can happen for number of reasons and results in new session not being cached. Attached patch fixes this by adding retry logic to "sess_id" & "id" allocations. Best regards, Piotr Sikora diff -r 1c472e3b8c10 src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c Thu Feb 21 23:31:57 2013 +0000 +++ b/src/event/ngx_event_openssl.c Fri Feb 22 13:14:32 2013 -0800 @@ -1842,8 +1842,18 @@ } sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t)); + if (sess_id == NULL) { - goto failed; + + /* drop the oldest non-expired session and try once more */ + + ngx_ssl_expire_sessions(cache, shpool, 0); + + sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t)); + + if (sess_id == NULL) { + goto failed; + } } #if (NGX_PTR_SIZE == 8) @@ -1853,8 +1863,18 @@ #else id = ngx_slab_alloc_locked(shpool, sess->session_id_length); + if (id == NULL) { - goto failed; + + /* drop the oldest non-expired session and try once more */ + + ngx_ssl_expire_sessions(cache, shpool, 0); + + id = ngx_slab_alloc_locked(shpool, sess->session_id_length); + + if (id == NULL) { + goto failed; + } } #endif From mdounin at mdounin.ru Sat Feb 23 11:50:43 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Sat, 23 Feb 2013 11:50:43 +0000 Subject: [nginx] svn commit: r5081 - trunk/src/http/modules Message-ID: <20130223115043.53C683F9DF8@mail.nginx.com> Author: mdounin Date: 2013-02-23 11:50:42 +0000 (Sat, 23 Feb 2013) New Revision: 5081 URL: http://trac.nginx.org/nginx/changeset/5081/nginx Log: Trailing whitespace fix. Modified: trunk/src/http/modules/ngx_http_scgi_module.c trunk/src/http/modules/ngx_http_uwsgi_module.c Modified: trunk/src/http/modules/ngx_http_scgi_module.c =================================================================== --- trunk/src/http/modules/ngx_http_scgi_module.c 2013-02-21 23:31:57 UTC (rev 5080) +++ trunk/src/http/modules/ngx_http_scgi_module.c 2013-02-23 11:50:42 UTC (rev 5081) @@ -1018,7 +1018,7 @@ done: if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS - && r->headers_in.upgrade) + && r->headers_in.upgrade) { u->upgrade = 1; } Modified: trunk/src/http/modules/ngx_http_uwsgi_module.c =================================================================== --- trunk/src/http/modules/ngx_http_uwsgi_module.c 2013-02-21 23:31:57 UTC (rev 5080) +++ trunk/src/http/modules/ngx_http_uwsgi_module.c 2013-02-23 11:50:42 UTC (rev 5081) @@ -1052,7 +1052,7 @@ done: if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS - && r->headers_in.upgrade) + && r->headers_in.upgrade) { u->upgrade = 1; } From mdounin at mdounin.ru Sat Feb 23 11:54:25 2013 From: mdounin at mdounin.ru (mdounin at mdounin.ru) Date: Sat, 23 Feb 2013 11:54:25 +0000 Subject: [nginx] svn commit: r5082 - trunk/src/event Message-ID: <20130223115425.8898B3F9FAE@mail.nginx.com> Author: mdounin Date: 2013-02-23 11:54:25 +0000 (Sat, 23 Feb 2013) New Revision: 5082 URL: http://trac.nginx.org/nginx/changeset/5082/nginx Log: SSL: retry "sess_id" and "id" allocations. In case of fully populated SSL session cache with no memory left for new allocations, ngx_ssl_new_session() will try to expire the oldest non-expired session and retry, but only in case when slab allocation fails for "cached_sess", not when slab allocation fails for either "sess_id" or "id", which can happen for number of reasons and results in new session not being cached. Patch fixes this by adding retry logic to "sess_id" & "id" allocations. Patch by Piotr Sikora. Modified: trunk/src/event/ngx_event_openssl.c Modified: trunk/src/event/ngx_event_openssl.c =================================================================== --- trunk/src/event/ngx_event_openssl.c 2013-02-23 11:50:42 UTC (rev 5081) +++ trunk/src/event/ngx_event_openssl.c 2013-02-23 11:54:25 UTC (rev 5082) @@ -1842,8 +1842,18 @@ } sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t)); + if (sess_id == NULL) { - goto failed; + + /* drop the oldest non-expired session and try once more */ + + ngx_ssl_expire_sessions(cache, shpool, 0); + + sess_id = ngx_slab_alloc_locked(shpool, sizeof(ngx_ssl_sess_id_t)); + + if (sess_id == NULL) { + goto failed; + } } #if (NGX_PTR_SIZE == 8) @@ -1853,8 +1863,18 @@ #else id = ngx_slab_alloc_locked(shpool, sess->session_id_length); + if (id == NULL) { - goto failed; + + /* drop the oldest non-expired session and try once more */ + + ngx_ssl_expire_sessions(cache, shpool, 0); + + id = ngx_slab_alloc_locked(shpool, sess->session_id_length); + + if (id == NULL) { + goto failed; + } } #endif From mdounin at mdounin.ru Sat Feb 23 11:54:49 2013 From: mdounin at mdounin.ru (Maxim Dounin) Date: Sat, 23 Feb 2013 15:54:49 +0400 Subject: [PATCH] Retry failed SSL session cache allocations In-Reply-To: References: Message-ID: <20130223115449.GL81985@mdounin.ru> Hello! On Fri, Feb 22, 2013 at 02:06:20PM -0800, Piotr Sikora wrote: > Hey, > in case of fully populated SSL session cache with no memory left for > new allocations, ngx_ssl_new_session() will try to expire the oldest > non-expired session and retry, but only in case when slab allocation > fails for "cached_sess", not when slab allocation fails for either > "sess_id" or "id", which can happen for number of reasons and results > in new session not being cached. > > Attached patch fixes this by adding retry logic to "sess_id" & "id" allocations. Committed, thank you. -- Maxim Dounin http://nginx.com/support.html From vbart at nginx.com Sat Feb 23 13:23:49 2013 From: vbart at nginx.com (vbart at nginx.com) Date: Sat, 23 Feb 2013 13:23:49 +0000 Subject: [nginx] svn commit: r5083 - trunk/src/http Message-ID: <20130223132350.689273F9F4A@mail.nginx.com> Author: vbart Date: 2013-02-23 13:23:48 +0000 (Sat, 23 Feb 2013) New Revision: 5083 URL: http://trac.nginx.org/nginx/changeset/5083/nginx Log: Fixed potential segfault in ngx_http_keepalive_handler(). In case of error in the read event handling we close a connection by calling ngx_http_close_connection(), that also destroys connection pool. Thereafter, an attempt to free a buffer (added in r4892) that was allocated from the pool could cause SIGSEGV and is meaningless as well (the buffer already freed with the pool). Modified: trunk/src/http/ngx_http_request.c Modified: trunk/src/http/ngx_http_request.c =================================================================== --- trunk/src/http/ngx_http_request.c 2013-02-23 11:54:25 UTC (rev 5082) +++ trunk/src/http/ngx_http_request.c 2013-02-23 13:23:48 UTC (rev 5083) @@ -2758,6 +2758,7 @@ if (n == NGX_AGAIN) { if (ngx_handle_read_event(rev, 0) != NGX_OK) { ngx_http_close_connection(c); + return; } /* From alexander_koch_log at lavabit.com Sat Feb 23 20:32:07 2013 From: alexander_koch_log at lavabit.com (alexander_koch_log) Date: Sat, 23 Feb 2013 21:32:07 +0100 Subject: aio + directio Message-ID: <51292747.8030704@lavabit.com> Hi, Quoting "http://nginx.org/en/docs/http/ngx_http_core_module.html#aio" > /(....)Reading of unaligned file's end is still made in blocking mode. > The same holds true for byte range requests, and for FLV requests not > from the beginning of a file: reading of unaligned data at the > beginning and end of a file will be blocking(....)/ Am I correct to understand if a file is unaligned and byte-range request is sent from say the middle of the file to few bytes "before the end of the file" that the aio call will not block and it will only block if reading from the beginning of the file and at the end of the file? Thank you. Alex -------------- next part -------------- An HTML attachment was scrubbed... URL: From igor at sysoev.ru Sun Feb 24 06:16:11 2013 From: igor at sysoev.ru (Igor Sysoev) Date: Sun, 24 Feb 2013 10:16:11 +0400 Subject: aio + directio In-Reply-To: <51292747.8030704@lavabit.com> References: <51292747.8030704@lavabit.com> Message-ID: On Feb 24, 2013, at 0:32 , alexander_koch_log wrote: > Hi, > > Quoting "http://nginx.org/en/docs/http/ngx_http_core_module.html#aio" > >> (....)Reading of unaligned file?s end is still made in blocking mode. The same holds true for byte range requests, and for FLV requests not from the beginning of a file: reading of unaligned data at the beginning and end of a file will be blocking(....) > > > Am I correct to understand if a file is unaligned and byte-range request is sent from say the middle of the file to few bytes "before the end of the file" that the aio call will not block and it will only block if reading from the beginning of the file and at the end of the file? No, any unaligned access is a blocking operation. This text should be fixed. -- Igor Sysoev http://nginx.com/support.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From sina at redteam.io Sun Feb 24 23:28:05 2013 From: sina at redteam.io (SiNA Rabbani) Date: Sun, 24 Feb 2013 23:28:05 +0000 Subject: NGiNX or NGINX? Message-ID: <512AA205.1020701@redteam.io> How do you guys like the software to be names? NGINX or Nginx or NGiNX? Thanks, SiNA -- ?Be the change you want to see in the world.? Gandhi XMPP: inf0 at jabber.ccc.de a5dae15f45a37e9768f6deae7b54807fc4942ec9 twitter.com/wwwiretap From andrew at nginx.com Mon Feb 25 00:59:51 2013 From: andrew at nginx.com (Andrew Alexeev) Date: Sun, 24 Feb 2013 18:59:51 -0600 Subject: NGiNX or NGINX? In-Reply-To: <512AA205.1020701@redteam.io> References: <512AA205.1020701@redteam.io> Message-ID: On Feb 24, 2013, at 5:28 PM, SiNA Rabbani wrote: > How do you guys like the software to be names? NGINX or Nginx or NGiNX? Either "nginx" or "NGINX". > Thanks, > SiNA > > -- > ?Be the change you want to see in the world.? Gandhi > > XMPP: inf0 at jabber.ccc.de a5dae15f45a37e9768f6deae7b54807fc4942ec9 > twitter.com/wwwiretap > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From andrew at nginx.com Mon Feb 25 00:59:51 2013 From: andrew at nginx.com (Andrew Alexeev) Date: Sun, 24 Feb 2013 18:59:51 -0600 Subject: NGiNX or NGINX? In-Reply-To: <512AA205.1020701@redteam.io> References: <512AA205.1020701@redteam.io> Message-ID: On Feb 24, 2013, at 5:28 PM, SiNA Rabbani wrote: > How do you guys like the software to be names? NGINX or Nginx or NGiNX? Either "nginx" or "NGINX". > Thanks, > SiNA > > -- > ?Be the change you want to see in the world.? Gandhi > > XMPP: inf0 at jabber.ccc.de a5dae15f45a37e9768f6deae7b54807fc4942ec9 > twitter.com/wwwiretap > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From mdounin at mdounin.ru Mon Feb 25 12:35:36 2013 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 25 Feb 2013 16:35:36 +0400 Subject: image_filter enhancement In-Reply-To: References: <20121204130841.GI40452@mdounin.ru> <20121205145244.GO40452@mdounin.ru> <20121218105341.GK40452@mdounin.ru> <20121225160542.GD40452@mdounin.ru> Message-ID: <20130225123536.GV81985@mdounin.ru> Hello! On Fri, Feb 22, 2013 at 09:52:42AM +0400, ivan babrou wrote: > Is there anything else I should fix? The patch is flagged in my inbox, and I'll look at it as time permits. It's not high priority though, as it's not first iteration of the review. And quick look suggests that you haven't addressed concerns expressed in previous reviews. If you want to speed up things, you may do so by carefully re-reading previous reviews and either addressing expressed concerns and/or explaing why the taken aproach is right one in your opinion. [...] -- Maxim Dounin http://nginx.com/support.html From ru at nginx.com Wed Feb 27 13:22:21 2013 From: ru at nginx.com (ru at nginx.com) Date: Wed, 27 Feb 2013 13:22:21 +0000 Subject: [nginx] svn commit: r5084 - trunk/src/http Message-ID: <20130227132221.A71EA3FAB69@mail.nginx.com> Author: ru Date: 2013-02-27 13:22:20 +0000 (Wed, 27 Feb 2013) New Revision: 5084 URL: http://trac.nginx.org/nginx/changeset/5084/nginx Log: Fixed separator in $sent_http_cache_control. In case multiple "Cache-Control" headers are sent to a client, multiple values in $sent_http_cache_control were incorrectly split by a semicolon. Now they are split by a comma. Modified: trunk/src/http/ngx_http_variables.c Modified: trunk/src/http/ngx_http_variables.c =================================================================== --- trunk/src/http/ngx_http_variables.c 2013-02-23 13:23:48 UTC (rev 5083) +++ trunk/src/http/ngx_http_variables.c 2013-02-27 13:22:20 UTC (rev 5084) @@ -21,8 +21,13 @@ ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); + +static ngx_int_t ngx_http_variable_cookies(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_variable_headers_internal(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data, u_char sep); static ngx_int_t ngx_http_variable_unknown_header_in(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); @@ -160,7 +165,7 @@ offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 }, #endif - { ngx_string("http_cookie"), NULL, ngx_http_variable_headers, + { ngx_string("http_cookie"), NULL, ngx_http_variable_cookies, offsetof(ngx_http_request_t, headers_in.cookies), 0, 0 }, { ngx_string("content_length"), NULL, ngx_http_variable_content_length, @@ -726,9 +731,25 @@ static ngx_int_t -ngx_http_variable_headers(ngx_http_request_t *r, ngx_http_variable_value_t *v, - uintptr_t data) +ngx_http_variable_cookies(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) { + return ngx_http_variable_headers_internal(r, v, data, ';'); +} + + +static ngx_int_t +ngx_http_variable_headers(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + return ngx_http_variable_headers_internal(r, v, data, ','); +} + + +static ngx_int_t +ngx_http_variable_headers_internal(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data, u_char sep) +{ size_t len; u_char *p, *end; ngx_uint_t i, n; @@ -748,7 +769,7 @@ continue; } - len += h[i]->value.len + sizeof("; ") - 1; + len += h[i]->value.len + 2; } if (len == 0) { @@ -756,7 +777,7 @@ return NGX_OK; } - len -= sizeof("; ") - 1; + len -= 2; v->valid = 1; v->no_cacheable = 0; @@ -791,7 +812,7 @@ break; } - *p++ = ';'; *p++ = ' '; + *p++ = sep; *p++ = ' '; } return NGX_OK; From ru at nginx.com Wed Feb 27 13:29:50 2013 From: ru at nginx.com (ru at nginx.com) Date: Wed, 27 Feb 2013 13:29:50 +0000 Subject: [nginx] svn commit: r5085 - in trunk/src/http: . modules Message-ID: <20130227132950.EF4C03FA152@mail.nginx.com> Author: ru Date: 2013-02-27 13:29:50 +0000 (Wed, 27 Feb 2013) New Revision: 5085 URL: http://trac.nginx.org/nginx/changeset/5085/nginx Log: Correctly handle multiple X-Forwarded-For headers (ticket #106). Modified: trunk/src/http/modules/ngx_http_geo_module.c trunk/src/http/modules/ngx_http_geoip_module.c trunk/src/http/modules/ngx_http_proxy_module.c trunk/src/http/modules/ngx_http_realip_module.c trunk/src/http/ngx_http_core_module.c trunk/src/http/ngx_http_core_module.h trunk/src/http/ngx_http_request.c trunk/src/http/ngx_http_request.h trunk/src/http/ngx_http_variables.c Modified: trunk/src/http/modules/ngx_http_geo_module.c =================================================================== --- trunk/src/http/modules/ngx_http_geo_module.c 2013-02-27 13:22:20 UTC (rev 5084) +++ trunk/src/http/modules/ngx_http_geo_module.c 2013-02-27 13:29:50 UTC (rev 5085) @@ -314,18 +314,17 @@ ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx, ngx_addr_t *addr) { - ngx_table_elt_t *xfwd; + ngx_array_t *xfwd; if (ngx_http_geo_real_addr(r, ctx, addr) != NGX_OK) { return NGX_ERROR; } - xfwd = r->headers_in.x_forwarded_for; + xfwd = &r->headers_in.x_forwarded_for; - if (xfwd != NULL && ctx->proxies != NULL) { - (void) ngx_http_get_forwarded_addr(r, addr, xfwd->value.data, - xfwd->value.len, ctx->proxies, - ctx->proxy_recursive); + if (xfwd->nelts > 0 && ctx->proxies != NULL) { + (void) ngx_http_get_forwarded_addr(r, addr, xfwd, NULL, + ctx->proxies, ctx->proxy_recursive); } return NGX_OK; Modified: trunk/src/http/modules/ngx_http_geoip_module.c =================================================================== --- trunk/src/http/modules/ngx_http_geoip_module.c 2013-02-27 13:22:20 UTC (rev 5084) +++ trunk/src/http/modules/ngx_http_geoip_module.c 2013-02-27 13:29:50 UTC (rev 5085) @@ -240,19 +240,18 @@ ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf) { ngx_addr_t addr; - ngx_table_elt_t *xfwd; + ngx_array_t *xfwd; struct sockaddr_in *sin; addr.sockaddr = r->connection->sockaddr; addr.socklen = r->connection->socklen; /* addr.name = r->connection->addr_text; */ - xfwd = r->headers_in.x_forwarded_for; + xfwd = &r->headers_in.x_forwarded_for; - if (xfwd != NULL && gcf->proxies != NULL) { - (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data, - xfwd->value.len, gcf->proxies, - gcf->proxy_recursive); + if (xfwd->nelts > 0 && gcf->proxies != NULL) { + (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL, + gcf->proxies, gcf->proxy_recursive); } #if (NGX_HAVE_INET6) @@ -293,7 +292,7 @@ ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf) { ngx_addr_t addr; - ngx_table_elt_t *xfwd; + ngx_array_t *xfwd; in_addr_t addr4; struct in6_addr addr6; struct sockaddr_in *sin; @@ -303,12 +302,11 @@ addr.socklen = r->connection->socklen; /* addr.name = r->connection->addr_text; */ - xfwd = r->headers_in.x_forwarded_for; + xfwd = &r->headers_in.x_forwarded_for; - if (xfwd != NULL && gcf->proxies != NULL) { - (void) ngx_http_get_forwarded_addr(r, &addr, xfwd->value.data, - xfwd->value.len, gcf->proxies, - gcf->proxy_recursive); + if (xfwd->nelts > 0 && gcf->proxies != NULL) { + (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL, + gcf->proxies, gcf->proxy_recursive); } switch (addr.sockaddr->sa_family) { Modified: trunk/src/http/modules/ngx_http_proxy_module.c =================================================================== --- trunk/src/http/modules/ngx_http_proxy_module.c 2013-02-27 13:22:20 UTC (rev 5084) +++ trunk/src/http/modules/ngx_http_proxy_module.c 2013-02-27 13:29:50 UTC (rev 5085) @@ -2014,33 +2014,45 @@ ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - u_char *p; + size_t len; + u_char *p; + ngx_uint_t i, n; + ngx_table_elt_t **h; v->valid = 1; v->no_cacheable = 0; v->not_found = 0; - if (r->headers_in.x_forwarded_for == NULL) { + n = r->headers_in.x_forwarded_for.nelts; + h = r->headers_in.x_forwarded_for.elts; + + len = 0; + + for (i = 0; i < n; i++) { + len += h[i]->value.len + sizeof(", ") - 1; + } + + if (len == 0) { v->len = r->connection->addr_text.len; v->data = r->connection->addr_text.data; return NGX_OK; } - v->len = r->headers_in.x_forwarded_for->value.len - + sizeof(", ") - 1 + r->connection->addr_text.len; + len += r->connection->addr_text.len; - p = ngx_pnalloc(r->pool, v->len); + p = ngx_pnalloc(r->pool, len); if (p == NULL) { return NGX_ERROR; } + v->len = len; v->data = p; - p = ngx_copy(p, r->headers_in.x_forwarded_for->value.data, - r->headers_in.x_forwarded_for->value.len); + for (i = 0; i < n; i++) { + p = ngx_copy(p, h[i]->value.data, h[i]->value.len); + *p++ = ','; *p++ = ' '; + } - *p++ = ','; *p++ = ' '; - ngx_memcpy(p, r->connection->addr_text.data, r->connection->addr_text.len); return NGX_OK; Modified: trunk/src/http/modules/ngx_http_realip_module.c =================================================================== --- trunk/src/http/modules/ngx_http_realip_module.c 2013-02-27 13:22:20 UTC (rev 5084) +++ trunk/src/http/modules/ngx_http_realip_module.c 2013-02-27 13:29:50 UTC (rev 5085) @@ -107,10 +107,12 @@ static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r) { - u_char *ip, *p; + u_char *p; size_t len; + ngx_str_t *value; ngx_uint_t i, hash; ngx_addr_t addr; + ngx_array_t *xfwd; ngx_list_part_t *part; ngx_table_elt_t *header; ngx_connection_t *c; @@ -137,19 +139,20 @@ return NGX_DECLINED; } - len = r->headers_in.x_real_ip->value.len; - ip = r->headers_in.x_real_ip->value.data; + value = &r->headers_in.x_real_ip->value; + xfwd = NULL; break; case NGX_HTTP_REALIP_XFWD: - if (r->headers_in.x_forwarded_for == NULL) { + xfwd = &r->headers_in.x_forwarded_for; + + if (xfwd->elts == NULL) { return NGX_DECLINED; } - len = r->headers_in.x_forwarded_for->value.len; - ip = r->headers_in.x_forwarded_for->value.data; + value = NULL; break; @@ -178,8 +181,8 @@ && len == header[i].key.len && ngx_strncmp(p, header[i].lowcase_key, len) == 0) { - len = header[i].value.len; - ip = header[i].value.data; + value = &header[i].value; + xfwd = NULL; goto found; } @@ -192,15 +195,13 @@ c = r->connection; - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip); - addr.sockaddr = c->sockaddr; addr.socklen = c->socklen; /* addr.name = c->addr_text; */ - if (ngx_http_get_forwarded_addr(r, &addr, ip, len, rlcf->from, + if (ngx_http_get_forwarded_addr(r, &addr, xfwd, value, rlcf->from, rlcf->recursive) - == NGX_OK) + != NGX_DECLINED) { return ngx_http_realip_set_addr(r, &addr); } Modified: trunk/src/http/ngx_http_core_module.c =================================================================== --- trunk/src/http/ngx_http_core_module.c 2013-02-27 13:22:20 UTC (rev 5084) +++ trunk/src/http/ngx_http_core_module.c 2013-02-27 13:29:50 UTC (rev 5085) @@ -76,6 +76,9 @@ static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); #endif +static ngx_int_t ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, + ngx_addr_t *addr, u_char *xff, size_t xfflen, ngx_array_t *proxies, + int recursive); #if (NGX_HAVE_OPENAT) static char *ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -2747,10 +2750,58 @@ ngx_int_t ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr, + ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies, + int recursive) +{ + ngx_int_t rc; + ngx_uint_t i, found; + ngx_table_elt_t **h; + + if (headers == NULL) { + return ngx_http_get_forwarded_addr_internal(r, addr, value->data, + value->len, proxies, + recursive); + } + + i = headers->nelts; + h = headers->elts; + + rc = NGX_DECLINED; + + found = 0; + + while (i-- > 0) { + rc = ngx_http_get_forwarded_addr_internal(r, addr, h[i]->value.data, + h[i]->value.len, proxies, + recursive); + + if (!recursive) { + break; + } + + if (rc == NGX_DECLINED && found) { + rc = NGX_DONE; + break; + } + + if (rc != NGX_OK) { + break; + } + + found = 1; + } + + return rc; +} + + +static ngx_int_t +ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr, u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive) { u_char *p; in_addr_t inaddr; + ngx_int_t rc; ngx_addr_t paddr; ngx_cidr_t *cidr; ngx_uint_t family, i; @@ -2842,8 +2893,15 @@ *addr = paddr; if (recursive && p > xff) { - (void) ngx_http_get_forwarded_addr(r, addr, xff, p - 1 - xff, - proxies, 1); + rc = ngx_http_get_forwarded_addr_internal(r, addr, xff, p - 1 - xff, + proxies, 1); + + if (rc == NGX_DECLINED) { + return NGX_DONE; + } + + /* rc == NGX_OK || rc == NGX_DONE */ + return rc; } return NGX_OK; Modified: trunk/src/http/ngx_http_core_module.h =================================================================== --- trunk/src/http/ngx_http_core_module.h 2013-02-27 13:22:20 UTC (rev 5084) +++ trunk/src/http/ngx_http_core_module.h 2013-02-27 13:29:50 UTC (rev 5085) @@ -516,7 +516,8 @@ ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of); ngx_int_t ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr, - u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive); + ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies, + int recursive); extern ngx_module_t ngx_http_core_module; Modified: trunk/src/http/ngx_http_request.c =================================================================== --- trunk/src/http/ngx_http_request.c 2013-02-27 13:22:20 UTC (rev 5084) +++ trunk/src/http/ngx_http_request.c 2013-02-27 13:29:50 UTC (rev 5085) @@ -21,14 +21,14 @@ ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); +static ngx_int_t ngx_http_process_multi_header_lines(ngx_http_request_t *r, + ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); -static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r, - ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r); static void ngx_http_process_request(ngx_http_request_t *r); @@ -153,7 +153,7 @@ #if (NGX_HTTP_X_FORWARDED_FOR) { ngx_string("X-Forwarded-For"), offsetof(ngx_http_headers_in_t, x_forwarded_for), - ngx_http_process_header_line }, + ngx_http_process_multi_header_lines }, #endif #if (NGX_HTTP_REALIP) @@ -185,7 +185,8 @@ ngx_http_process_header_line }, #endif - { ngx_string("Cookie"), 0, ngx_http_process_cookie }, + { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookies), + ngx_http_process_multi_header_lines }, { ngx_null_string, 0, NULL } }; @@ -930,15 +931,6 @@ return; } - - if (ngx_array_init(&r->headers_in.cookies, r->pool, 2, - sizeof(ngx_table_elt_t *)) - != NGX_OK) - { - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); - return; - } - c->log->action = "reading client request headers"; rev->handler = ngx_http_process_request_headers; @@ -1535,20 +1527,31 @@ static ngx_int_t -ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h, +ngx_http_process_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - ngx_table_elt_t **cookie; + ngx_array_t *headers; + ngx_table_elt_t **ph; - cookie = ngx_array_push(&r->headers_in.cookies); - if (cookie) { - *cookie = h; - return NGX_OK; + headers = (ngx_array_t *) ((char *) &r->headers_in + offset); + + if (headers->elts == NULL) { + if (ngx_array_init(headers, r->pool, 1, sizeof(ngx_table_elt_t *)) + != NGX_OK) + { + ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_ERROR; + } } - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + ph = ngx_array_push(headers); + if (ph == NULL) { + ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_ERROR; + } - return NGX_ERROR; + *ph = h; + return NGX_OK; } Modified: trunk/src/http/ngx_http_request.h =================================================================== --- trunk/src/http/ngx_http_request.h 2013-02-27 13:22:20 UTC (rev 5084) +++ trunk/src/http/ngx_http_request.h 2013-02-27 13:29:50 UTC (rev 5085) @@ -200,7 +200,7 @@ ngx_table_elt_t *keep_alive; #if (NGX_HTTP_X_FORWARDED_FOR) - ngx_table_elt_t *x_forwarded_for; + ngx_array_t x_forwarded_for; #endif #if (NGX_HTTP_REALIP) Modified: trunk/src/http/ngx_http_variables.c =================================================================== --- trunk/src/http/ngx_http_variables.c 2013-02-27 13:22:20 UTC (rev 5084) +++ trunk/src/http/ngx_http_variables.c 2013-02-27 13:29:50 UTC (rev 5085) @@ -138,8 +138,8 @@ */ /* - * the $http_host, $http_user_agent, $http_referer, $http_via, - * and $http_x_forwarded_for variables may be handled by generic + * the $http_host, $http_user_agent, $http_referer, and $http_via + * variables may be handled by generic * ngx_http_variable_unknown_header_in(), but for performance reasons * they are handled using dedicated entries */ @@ -161,7 +161,7 @@ #endif #if (NGX_HTTP_X_FORWARDED_FOR) - { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_header, + { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_headers, offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 }, #endif From vbart at nginx.com Wed Feb 27 16:53:02 2013 From: vbart at nginx.com (vbart at nginx.com) Date: Wed, 27 Feb 2013 16:53:02 +0000 Subject: [nginx] svn commit: r5086 - trunk/src/http Message-ID: <20130227165303.73C1E3F9C6B@mail.nginx.com> Author: vbart Date: 2013-02-27 16:53:01 +0000 (Wed, 27 Feb 2013) New Revision: 5086 URL: http://trac.nginx.org/nginx/changeset/5086/nginx Log: The default server lookup is now done only once per connection. Previously, it was done for every request in a connection. Modified: trunk/src/http/ngx_http_core_module.h trunk/src/http/ngx_http_request.c trunk/src/http/ngx_http_request.h Modified: trunk/src/http/ngx_http_core_module.h =================================================================== --- trunk/src/http/ngx_http_core_module.h 2013-02-27 13:29:50 UTC (rev 5085) +++ trunk/src/http/ngx_http_core_module.h 2013-02-27 16:53:01 UTC (rev 5086) @@ -209,6 +209,23 @@ typedef struct { +#if (NGX_PCRE) + ngx_http_regex_t *regex; +#endif + ngx_http_core_srv_conf_t *server; /* virtual name server conf */ + ngx_str_t name; +} ngx_http_server_name_t; + + +typedef struct { + ngx_hash_combined_t names; + + ngx_uint_t nregex; + ngx_http_server_name_t *regex; +} ngx_http_virtual_names_t; + + +struct ngx_http_addr_conf_s { /* the default server configuration for this address:port */ ngx_http_core_srv_conf_t *default_server; @@ -217,7 +234,7 @@ #if (NGX_HTTP_SSL) ngx_uint_t ssl; /* unsigned ssl:1; */ #endif -} ngx_http_addr_conf_t; +}; typedef struct { @@ -268,15 +285,6 @@ } ngx_http_conf_addr_t; -struct ngx_http_server_name_s { -#if (NGX_PCRE) - ngx_http_regex_t *regex; -#endif - ngx_http_core_srv_conf_t *server; /* virtual name server conf */ - ngx_str_t name; -}; - - typedef struct { ngx_int_t status; ngx_int_t overwrite; Modified: trunk/src/http/ngx_http_request.c =================================================================== --- trunk/src/http/ngx_http_request.c 2013-02-27 13:29:50 UTC (rev 5085) +++ trunk/src/http/ngx_http_request.c 2013-02-27 16:53:01 UTC (rev 5086) @@ -195,9 +195,100 @@ void ngx_http_init_connection(ngx_connection_t *c) { - ngx_event_t *rev; - ngx_http_log_ctx_t *ctx; + ngx_uint_t i; + ngx_event_t *rev; + struct sockaddr_in *sin; + ngx_http_port_t *port; + ngx_http_in_addr_t *addr; + ngx_http_log_ctx_t *ctx; + ngx_http_connection_t *hc; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; + ngx_http_in6_addr_t *addr6; +#endif + hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t)); + if (hc == NULL) { + ngx_http_close_connection(c); + return; + } + + c->data = hc; + + /* find the server configuration for the address:port */ + + port = c->listening->servers; + + if (port->naddrs > 1) { + + /* + * there are several addresses on this port and one of them + * is an "*:port" wildcard so getsockname() in ngx_http_server_addr() + * is required to determine a server address + */ + + if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) { + ngx_http_close_connection(c); + return; + } + + switch (c->local_sockaddr->sa_family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) c->local_sockaddr; + + addr6 = port->addrs; + + /* the last address is "*" */ + + for (i = 0; i < port->naddrs - 1; i++) { + if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) { + break; + } + } + + hc->addr_conf = &addr6[i].conf; + + break; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) c->local_sockaddr; + + addr = port->addrs; + + /* the last address is "*" */ + + for (i = 0; i < port->naddrs - 1; i++) { + if (addr[i].addr == sin->sin_addr.s_addr) { + break; + } + } + + hc->addr_conf = &addr[i].conf; + + break; + } + + } else { + + switch (c->local_sockaddr->sa_family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + addr6 = port->addrs; + hc->addr_conf = &addr6[0].conf; + break; +#endif + + default: /* AF_INET */ + addr = port->addrs; + hc->addr_conf = &addr[0].conf; + break; + } + } + ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t)); if (ctx == NULL) { ngx_http_close_connection(c); @@ -251,22 +342,13 @@ ngx_http_init_request(ngx_event_t *rev) { ngx_time_t *tp; - ngx_uint_t i; ngx_connection_t *c; ngx_http_request_t *r; - struct sockaddr_in *sin; - ngx_http_port_t *port; - ngx_http_in_addr_t *addr; ngx_http_log_ctx_t *ctx; - ngx_http_addr_conf_t *addr_conf; ngx_http_connection_t *hc; ngx_http_core_srv_conf_t *cscf; ngx_http_core_loc_conf_t *clcf; ngx_http_core_main_conf_t *cmcf; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; - ngx_http_in6_addr_t *addr6; -#endif #if (NGX_STAT_STUB) (void) ngx_atomic_fetch_add(ngx_stat_reading, -1); @@ -285,14 +367,6 @@ hc = c->data; - if (hc == NULL) { - hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t)); - if (hc == NULL) { - ngx_http_close_connection(c); - return; - } - } - r = hc->request; if (r) { @@ -320,86 +394,10 @@ c->sent = 0; r->signature = NGX_HTTP_MODULE; - /* find the server configuration for the address:port */ - - port = c->listening->servers; - r->connection = c; - if (port->naddrs > 1) { - - /* - * there are several addresses on this port and one of them - * is an "*:port" wildcard so getsockname() in ngx_http_server_addr() - * is required to determine a server address - */ - - if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) { - ngx_http_close_connection(c); - return; - } - - switch (c->local_sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) c->local_sockaddr; - - addr6 = port->addrs; - - /* the last address is "*" */ - - for (i = 0; i < port->naddrs - 1; i++) { - if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) { - break; - } - } - - addr_conf = &addr6[i].conf; - - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) c->local_sockaddr; - - addr = port->addrs; - - /* the last address is "*" */ - - for (i = 0; i < port->naddrs - 1; i++) { - if (addr[i].addr == sin->sin_addr.s_addr) { - break; - } - } - - addr_conf = &addr[i].conf; - - break; - } - - } else { - - switch (c->local_sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - addr6 = port->addrs; - addr_conf = &addr6[0].conf; - break; -#endif - - default: /* AF_INET */ - addr = port->addrs; - addr_conf = &addr[0].conf; - break; - } - } - - r->virtual_names = addr_conf->virtual_names; - /* the default server configuration for the address:port */ - cscf = addr_conf->default_server; + cscf = hc->addr_conf->default_server; r->main_conf = cscf->ctx->main_conf; r->srv_conf = cscf->ctx->srv_conf; @@ -414,13 +412,13 @@ ngx_http_ssl_srv_conf_t *sscf; sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); - if (sscf->enable || addr_conf->ssl) { + if (sscf->enable || hc->addr_conf->ssl) { if (c->ssl == NULL) { c->log->action = "SSL handshaking"; - if (addr_conf->ssl && sscf->ssl.ctx == NULL) { + if (hc->addr_conf->ssl && sscf->ssl.ctx == NULL) { ngx_log_error(NGX_LOG_ERR, c->log, 0, "no \"ssl_certificate\" is defined " "in server listening on SSL port"); @@ -1799,12 +1797,15 @@ { ngx_http_core_loc_conf_t *clcf; ngx_http_core_srv_conf_t *cscf; + ngx_http_virtual_names_t *virtual_names; - if (r->virtual_names == NULL) { + virtual_names = r->http_connection->addr_conf->virtual_names; + + if (virtual_names == NULL) { return NGX_DECLINED; } - cscf = ngx_hash_find_combined(&r->virtual_names->names, + cscf = ngx_hash_find_combined(&virtual_names->names, ngx_hash_key(host, len), host, len); if (cscf) { @@ -1813,7 +1814,7 @@ #if (NGX_PCRE) - if (len && r->virtual_names->nregex) { + if (len && virtual_names->nregex) { ngx_int_t n; ngx_uint_t i; ngx_str_t name; @@ -1822,9 +1823,9 @@ name.len = len; name.data = host; - sn = r->virtual_names->regex; + sn = virtual_names->regex; - for (i = 0; i < r->virtual_names->nregex; i++) { + for (i = 0; i < virtual_names->nregex; i++) { n = ngx_http_regex_exec(r, sn[i].regex, &name); Modified: trunk/src/http/ngx_http_request.h =================================================================== --- trunk/src/http/ngx_http_request.h 2013-02-27 13:29:50 UTC (rev 5085) +++ trunk/src/http/ngx_http_request.h 2013-02-27 16:53:01 UTC (rev 5086) @@ -289,7 +289,11 @@ } ngx_http_request_body_t; +typedef struct ngx_http_addr_conf_s ngx_http_addr_conf_t; + typedef struct { + ngx_http_addr_conf_t *addr_conf; + ngx_http_request_t *request; ngx_buf_t **busy; @@ -302,17 +306,6 @@ } ngx_http_connection_t; -typedef struct ngx_http_server_name_s ngx_http_server_name_t; - - -typedef struct { - ngx_hash_combined_t names; - - ngx_uint_t nregex; - ngx_http_server_name_t *regex; -} ngx_http_virtual_names_t; - - typedef void (*ngx_http_cleanup_pt)(void *data); typedef struct ngx_http_cleanup_s ngx_http_cleanup_t; @@ -406,8 +399,6 @@ ngx_http_post_subrequest_t *post_subrequest; ngx_http_posted_request_t *posted_requests; - ngx_http_virtual_names_t *virtual_names; - ngx_int_t phase_handler; ngx_http_handler_pt content_handler; ngx_uint_t access_code; From vbart at nginx.com Wed Feb 27 16:56:48 2013 From: vbart at nginx.com (vbart at nginx.com) Date: Wed, 27 Feb 2013 16:56:48 +0000 Subject: [nginx] svn commit: r5087 - trunk/src/http Message-ID: <20130227165649.7D1D43F9C6B@mail.nginx.com> Author: vbart Date: 2013-02-27 16:56:47 +0000 (Wed, 27 Feb 2013) New Revision: 5087 URL: http://trac.nginx.org/nginx/changeset/5087/nginx Log: Introduced the ngx_http_set_connection_log() macro. No functional changes. Modified: trunk/src/http/ngx_http_core_module.c trunk/src/http/ngx_http_request.c trunk/src/http/ngx_http_request.h Modified: trunk/src/http/ngx_http_core_module.c =================================================================== --- trunk/src/http/ngx_http_core_module.c 2013-02-27 16:53:01 UTC (rev 5086) +++ trunk/src/http/ngx_http_core_module.c 2013-02-27 16:56:47 UTC (rev 5087) @@ -1461,11 +1461,7 @@ } if (r == r->main) { - r->connection->log->file = clcf->error_log->file; - - if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { - r->connection->log->log_level = clcf->error_log->log_level; - } + ngx_http_set_connection_log(r->connection, clcf->error_log); } if ((ngx_io.flags & NGX_IO_SENDFILE) && clcf->sendfile) { Modified: trunk/src/http/ngx_http_request.c =================================================================== --- trunk/src/http/ngx_http_request.c 2013-02-27 16:53:01 UTC (rev 5086) +++ trunk/src/http/ngx_http_request.c 2013-02-27 16:56:47 UTC (rev 5087) @@ -443,11 +443,9 @@ #endif clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - c->log->file = clcf->error_log->file; - if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { - c->log->log_level = clcf->error_log->log_level; - } + ngx_http_set_connection_log(r->connection, clcf->error_log); + if (c->buffer == NULL) { c->buffer = ngx_create_temp_buf(c->pool, cscf->client_header_buffer_size); @@ -1852,11 +1850,8 @@ r->loc_conf = cscf->ctx->loc_conf; clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - r->connection->log->file = clcf->error_log->file; - if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { - r->connection->log->log_level = clcf->error_log->log_level; - } + ngx_http_set_connection_log(r->connection, clcf->error_log); return NGX_OK; } Modified: trunk/src/http/ngx_http_request.h =================================================================== --- trunk/src/http/ngx_http_request.h 2013-02-27 16:53:01 UTC (rev 5086) +++ trunk/src/http/ngx_http_request.h 2013-02-27 16:56:47 UTC (rev 5087) @@ -571,4 +571,12 @@ extern ngx_http_header_out_t ngx_http_headers_out[]; +#define ngx_http_set_connection_log(c, l) \ + \ + c->log->file = l->file; \ + if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { \ + c->log->log_level = l->log_level; \ + } + + #endif /* _NGX_HTTP_REQUEST_H_INCLUDED_ */ From vbart at nginx.com Wed Feb 27 17:03:14 2013 From: vbart at nginx.com (vbart at nginx.com) Date: Wed, 27 Feb 2013 17:03:14 +0000 Subject: [nginx] svn commit: r5088 - trunk/src/http Message-ID: <20130227170315.3D73C3F9FAF@mail.nginx.com> Author: vbart Date: 2013-02-27 17:03:14 +0000 (Wed, 27 Feb 2013) New Revision: 5088 URL: http://trac.nginx.org/nginx/changeset/5088/nginx Log: Changed interface of ngx_http_validate_host(). Modified: trunk/src/http/ngx_http_request.c Modified: trunk/src/http/ngx_http_request.c =================================================================== --- trunk/src/http/ngx_http_request.c 2013-02-27 16:56:47 UTC (rev 5087) +++ trunk/src/http/ngx_http_request.c 2013-02-27 17:03:14 UTC (rev 5088) @@ -32,8 +32,8 @@ static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r); static void ngx_http_process_request(ngx_http_request_t *r); -static ssize_t ngx_http_validate_host(ngx_http_request_t *r, u_char **host, - size_t len, ngx_uint_t alloc); +static ngx_int_t ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, + ngx_uint_t alloc); static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len); @@ -643,8 +643,7 @@ int ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) { - size_t len; - u_char *host; + ngx_str_t host; const char *servername; ngx_connection_t *c; ngx_http_request_t *r; @@ -661,23 +660,21 @@ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL server name: \"%s\"", servername); - len = ngx_strlen(servername); + host.len = ngx_strlen(servername); - if (len == 0) { + if (host.len == 0) { return SSL_TLSEXT_ERR_NOACK; } r = c->data; - host = (u_char *) servername; + host.data = (u_char *) servername; - len = ngx_http_validate_host(r, &host, len, 1); - - if (len <= 0) { + if (ngx_http_validate_host(&host, r->pool, 1) != NGX_OK) { return SSL_TLSEXT_ERR_NOACK; } - if (ngx_http_find_virtual_server(r, host, len) != NGX_OK) { + if (ngx_http_find_virtual_server(r, host.data, host.len) != NGX_OK) { return SSL_TLSEXT_ERR_NOACK; } @@ -716,9 +713,9 @@ static void ngx_http_process_request_line(ngx_event_t *rev) { - u_char *host; ssize_t n; ngx_int_t rc, rv; + ngx_str_t host; ngx_connection_t *c; ngx_http_request_t *r; ngx_http_core_srv_conf_t *cscf; @@ -884,24 +881,24 @@ if (r->host_start && r->host_end) { - host = r->host_start; - n = ngx_http_validate_host(r, &host, - r->host_end - r->host_start, 0); + host.len = r->host_end - r->host_start; + host.data = r->host_start; - if (n == 0) { + rc = ngx_http_validate_host(&host, r->pool, 0); + + if (rc == NGX_DECLINED) { ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent invalid host in request line"); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return; } - if (n < 0) { + if (rc == NGX_ERROR) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } - r->headers_in.server.len = n; - r->headers_in.server.data = host; + r->headers_in.server = host; } if (r->http_version < NGX_HTTP_VERSION_10) { @@ -1401,24 +1398,25 @@ ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - u_char *host; - ssize_t len; + ngx_int_t rc; + ngx_str_t host; if (r->headers_in.host == NULL) { r->headers_in.host = h; } - host = h->value.data; - len = ngx_http_validate_host(r, &host, h->value.len, 0); + host = h->value; - if (len == 0) { + rc = ngx_http_validate_host(&host, r->pool, 0); + + if (rc == NGX_DECLINED) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client sent invalid host header"); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return NGX_ERROR; } - if (len < 0) { + if (rc == NGX_ERROR) { ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_ERROR; } @@ -1427,8 +1425,7 @@ return NGX_OK; } - r->headers_in.server.len = len; - r->headers_in.server.data = host; + r->headers_in.server = host; return NGX_OK; } @@ -1704,9 +1701,8 @@ } -static ssize_t -ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len, - ngx_uint_t alloc) +static ngx_int_t +ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc) { u_char *h, ch; size_t i, dot_pos, host_len; @@ -1717,21 +1713,21 @@ sw_rest } state; - dot_pos = len; - host_len = len; + dot_pos = host->len; + host_len = host->len; - h = *host; + h = host->data; state = sw_usual; - for (i = 0; i < len; i++) { + for (i = 0; i < host->len; i++) { ch = h[i]; switch (ch) { case '.': if (dot_pos == i - 1) { - return 0; + return NGX_DECLINED; } dot_pos = i; break; @@ -1757,12 +1753,12 @@ break; case '\0': - return 0; + return NGX_DECLINED; default: if (ngx_path_separator(ch)) { - return 0; + return NGX_DECLINED; } if (ch >= 'A' && ch <= 'Z') { @@ -1777,16 +1773,22 @@ host_len--; } + if (host_len == 0) { + return NGX_DECLINED; + } + if (alloc) { - *host = ngx_pnalloc(r->pool, host_len); - if (*host == NULL) { - return -1; + host->data = ngx_pnalloc(pool, host_len); + if (host->data == NULL) { + return NGX_ERROR; } - ngx_strlow(*host, h, host_len); + ngx_strlow(host->data, h, host_len); } - return host_len; + host->len = host_len; + + return NGX_OK; } From vbart at nginx.com Wed Feb 27 17:06:52 2013 From: vbart at nginx.com (vbart at nginx.com) Date: Wed, 27 Feb 2013 17:06:52 +0000 Subject: [nginx] svn commit: r5089 - trunk/src/http Message-ID: <20130227170652.BC2E43F9FAF@mail.nginx.com> Author: vbart Date: 2013-02-27 17:06:52 +0000 (Wed, 27 Feb 2013) New Revision: 5089 URL: http://trac.nginx.org/nginx/changeset/5089/nginx Log: SNI: ignore captures in server_name regexes when matching by SNI. This change helps to decouple ngx_http_ssl_servername() from the request object. Note: now we close connection in case of error during server name lookup for request. Previously, we did so only for HTTP/0.9 requests. Modified: trunk/src/http/ngx_http_request.c Modified: trunk/src/http/ngx_http_request.c =================================================================== --- trunk/src/http/ngx_http_request.c 2013-02-27 17:03:14 UTC (rev 5088) +++ trunk/src/http/ngx_http_request.c 2013-02-27 17:06:52 UTC (rev 5089) @@ -34,8 +34,11 @@ static void ngx_http_process_request(ngx_http_request_t *r); static ngx_int_t ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc); -static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r, - u_char *host, size_t len); +static ngx_int_t ngx_http_set_virtual_server(ngx_http_request_t *r, + ngx_str_t *host); +static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c, + ngx_http_virtual_names_t *virtual_names, ngx_str_t *host, + ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp); static void ngx_http_request_handler(ngx_event_t *ev); static void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc); @@ -643,11 +646,14 @@ int ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) { - ngx_str_t host; - const char *servername; - ngx_connection_t *c; - ngx_http_request_t *r; - ngx_http_ssl_srv_conf_t *sscf; + ngx_str_t host; + const char *servername; + ngx_connection_t *c; + ngx_http_request_t *r; + ngx_http_connection_t *hc; + ngx_http_ssl_srv_conf_t *sscf; + ngx_http_core_loc_conf_t *clcf; + ngx_http_core_srv_conf_t *cscf; servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name); @@ -674,10 +680,22 @@ return SSL_TLSEXT_ERR_NOACK; } - if (ngx_http_find_virtual_server(r, host.data, host.len) != NGX_OK) { + hc = r->http_connection; + + if (ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host, + NULL, &cscf) + != NGX_OK) + { return SSL_TLSEXT_ERR_NOACK; } + r->srv_conf = cscf->ctx->srv_conf; + r->loc_conf = cscf->ctx->loc_conf; + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + ngx_http_set_connection_log(c, clcf->error_log); + sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); if (sscf->ssl.ctx) { @@ -903,11 +921,9 @@ if (r->http_version < NGX_HTTP_VERSION_10) { - if (ngx_http_find_virtual_server(r, r->headers_in.server.data, - r->headers_in.server.len) + if (ngx_http_set_virtual_server(r, &r->headers_in.server) == NGX_ERROR) { - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } @@ -1551,11 +1567,7 @@ static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r) { - if (ngx_http_find_virtual_server(r, r->headers_in.server.data, - r->headers_in.server.len) - == NGX_ERROR) - { - ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + if (ngx_http_set_virtual_server(r, &r->headers_in.server) == NGX_ERROR) { return NGX_ERROR; } @@ -1793,69 +1805,117 @@ static ngx_int_t -ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len) +ngx_http_set_virtual_server(ngx_http_request_t *r, ngx_str_t *host) { + ngx_int_t rc; + ngx_http_connection_t *hc; ngx_http_core_loc_conf_t *clcf; ngx_http_core_srv_conf_t *cscf; - ngx_http_virtual_names_t *virtual_names; - virtual_names = r->http_connection->addr_conf->virtual_names; + hc = r->http_connection; + rc = ngx_http_find_virtual_server(r->connection, + hc->addr_conf->virtual_names, + host, r, &cscf); + + if (rc == NGX_ERROR) { + ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_ERROR; + } + + if (rc == NGX_DECLINED) { + return NGX_OK; + } + + r->srv_conf = cscf->ctx->srv_conf; + r->loc_conf = cscf->ctx->loc_conf; + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + ngx_http_set_connection_log(r->connection, clcf->error_log); + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_find_virtual_server(ngx_connection_t *c, + ngx_http_virtual_names_t *virtual_names, ngx_str_t *host, + ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp) +{ + ngx_http_core_srv_conf_t *cscf; + if (virtual_names == NULL) { return NGX_DECLINED; } cscf = ngx_hash_find_combined(&virtual_names->names, - ngx_hash_key(host, len), host, len); + ngx_hash_key(host->data, host->len), + host->data, host->len); if (cscf) { - goto found; + *cscfp = cscf; + return NGX_OK; } #if (NGX_PCRE) - if (len && virtual_names->nregex) { + if (host->len && virtual_names->nregex) { ngx_int_t n; ngx_uint_t i; - ngx_str_t name; ngx_http_server_name_t *sn; - name.len = len; - name.data = host; - sn = virtual_names->regex; - for (i = 0; i < virtual_names->nregex; i++) { +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME - n = ngx_http_regex_exec(r, sn[i].regex, &name); + if (r == NULL) { + for (i = 0; i < virtual_names->nregex; i++) { - if (n == NGX_OK) { - cscf = sn[i].server; - goto found; + n = ngx_regex_exec(sn[i].regex->regex, host, NULL, 0); + + if (n == NGX_REGEX_NO_MATCHED) { + continue; + } + + if (n >= 0) { + *cscfp = sn[i].server; + return NGX_OK; + } + + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + ngx_regex_exec_n " failed: %i " + "on \"%V\" using \"%V\"", + n, host, &sn[i].regex->name); + + return NGX_ERROR; } + return NGX_DECLINED; + } + +#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */ + + for (i = 0; i < virtual_names->nregex; i++) { + + n = ngx_http_regex_exec(r, sn[i].regex, host); + if (n == NGX_DECLINED) { continue; } + if (n == NGX_OK) { + *cscfp = sn[i].server; + return NGX_OK; + } + return NGX_ERROR; } } -#endif +#endif /* NGX_PCRE */ return NGX_DECLINED; - -found: - - r->srv_conf = cscf->ctx->srv_conf; - r->loc_conf = cscf->ctx->loc_conf; - - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - - ngx_http_set_connection_log(r->connection, clcf->error_log); - - return NGX_OK; } From vbart at nginx.com Wed Feb 27 17:12:48 2013 From: vbart at nginx.com (vbart at nginx.com) Date: Wed, 27 Feb 2013 17:12:48 +0000 Subject: [nginx] svn commit: r5090 - trunk/src/http Message-ID: <20130227171248.B988C3F9C0C@mail.nginx.com> Author: vbart Date: 2013-02-27 17:12:48 +0000 (Wed, 27 Feb 2013) New Revision: 5090 URL: http://trac.nginx.org/nginx/changeset/5090/nginx Log: SNI: reuse selected configuration for all requests in a connection. Previously, only the first request in a connection was assigned the configuration selected by SNI. All subsequent requests initially used the default server's configuration, ignoring SNI, which was wrong. Now all subsequent requests in a connection will initially use the configuration selected by SNI. This is done by storing a pointer to configuration in http connection object. It points to default server's configuration initially, but changed upon receipt of SNI. (The request's configuration can be further refined when parsing the request line and Host: header.) This change was not made specific to SNI as it also allows slightly faster access to configuration without the request object. Modified: trunk/src/http/ngx_http.h trunk/src/http/ngx_http_request.c trunk/src/http/ngx_http_request.h Modified: trunk/src/http/ngx_http.h =================================================================== --- trunk/src/http/ngx_http.h 2013-02-27 17:06:52 UTC (rev 5089) +++ trunk/src/http/ngx_http.h 2013-02-27 17:12:48 UTC (rev 5090) @@ -27,11 +27,11 @@ #include +#include #include #include #include #include -#include #include #include Modified: trunk/src/http/ngx_http_request.c =================================================================== --- trunk/src/http/ngx_http_request.c 2013-02-27 17:06:52 UTC (rev 5089) +++ trunk/src/http/ngx_http_request.c 2013-02-27 17:12:48 UTC (rev 5090) @@ -292,6 +292,9 @@ } } + /* the default server configuration for the address:port */ + hc->conf_ctx = hc->addr_conf->default_server->ctx; + ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t)); if (ctx == NULL) { ngx_http_close_connection(c); @@ -399,13 +402,10 @@ r->connection = c; - /* the default server configuration for the address:port */ - cscf = hc->addr_conf->default_server; + r->main_conf = hc->conf_ctx->main_conf; + r->srv_conf = hc->conf_ctx->srv_conf; + r->loc_conf = hc->conf_ctx->loc_conf; - r->main_conf = cscf->ctx->main_conf; - r->srv_conf = cscf->ctx->srv_conf; - r->loc_conf = cscf->ctx->loc_conf; - rev->handler = ngx_http_process_request_line; r->read_event_handler = ngx_http_block_reading; @@ -449,6 +449,8 @@ ngx_http_set_connection_log(r->connection, clcf->error_log); + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); + if (c->buffer == NULL) { c->buffer = ngx_create_temp_buf(c->pool, cscf->client_header_buffer_size); @@ -689,6 +691,8 @@ return SSL_TLSEXT_ERR_NOACK; } + hc->conf_ctx = cscf->ctx; + r->srv_conf = cscf->ctx->srv_conf; r->loc_conf = cscf->ctx->loc_conf; Modified: trunk/src/http/ngx_http_request.h =================================================================== --- trunk/src/http/ngx_http_request.h 2013-02-27 17:06:52 UTC (rev 5089) +++ trunk/src/http/ngx_http_request.h 2013-02-27 17:12:48 UTC (rev 5090) @@ -293,6 +293,7 @@ typedef struct { ngx_http_addr_conf_t *addr_conf; + ngx_http_conf_ctx_t *conf_ctx; ngx_http_request_t *request; From vbart at nginx.com Wed Feb 27 17:16:53 2013 From: vbart at nginx.com (vbart at nginx.com) Date: Wed, 27 Feb 2013 17:16:53 +0000 Subject: [nginx] svn commit: r5091 - trunk/src/http Message-ID: <20130227171653.2DCE13F9C0C@mail.nginx.com> Author: vbart Date: 2013-02-27 17:16:51 +0000 (Wed, 27 Feb 2013) New Revision: 5091 URL: http://trac.nginx.org/nginx/changeset/5091/nginx Log: Status: do not count connection as reading right after accept(). Before we receive the first bytes, the connection is counted as waiting. This change simplifies further code changes. Modified: trunk/src/http/ngx_http_request.c Modified: trunk/src/http/ngx_http_request.c =================================================================== --- trunk/src/http/ngx_http_request.c 2013-02-27 17:12:48 UTC (rev 5090) +++ trunk/src/http/ngx_http_request.c 2013-02-27 17:16:51 UTC (rev 5091) @@ -316,10 +316,6 @@ rev->handler = ngx_http_init_request; c->write->handler = ngx_http_empty_handler; -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_reading, 1); -#endif - if (rev->ready) { /* the deferred accept(), rtsig, aio, iocp */ @@ -335,9 +331,6 @@ ngx_add_timer(rev, c->listening->post_accept_timeout); if (ngx_handle_read_event(rev, 0) != NGX_OK) { -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_reading, -1); -#endif ngx_http_close_connection(c); return; } @@ -356,10 +349,6 @@ ngx_http_core_loc_conf_t *clcf; ngx_http_core_main_conf_t *cmcf; -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_reading, -1); -#endif - c = rev->data; if (rev->timedout) { @@ -2613,10 +2602,6 @@ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request"); -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_reading, 1); -#endif - hc->pipeline = 1; c->log->action = "reading client pipelined request line"; @@ -2859,10 +2844,6 @@ b->last += n; -#if (NGX_STAT_STUB) - (void) ngx_atomic_fetch_add(ngx_stat_reading, 1); -#endif - c->log->handler = ngx_http_log_error; c->log->action = "reading client request line"; From vbart at nginx.com Wed Feb 27 17:21:22 2013 From: vbart at nginx.com (vbart at nginx.com) Date: Wed, 27 Feb 2013 17:21:22 +0000 Subject: [nginx] svn commit: r5092 - trunk/src/http Message-ID: <20130227172122.CDC893F9DC4@mail.nginx.com> Author: vbart Date: 2013-02-27 17:21:21 +0000 (Wed, 27 Feb 2013) New Revision: 5092 URL: http://trac.nginx.org/nginx/changeset/5092/nginx Log: SSL: do not treat SSL handshake as request. The request object will not be created until SSL handshake is complete. This simplifies adding another connection handler that does not need request object right after handshake (e.g., SPDY). There are also a few more intentional effects: - the "client_header_buffer_size" directive will be taken from the server configuration that was negotiated by SNI; - SSL handshake errors and timeouts are not logged into access log as bad requests; - ngx_ssl_create_connection() is not called until the first byte of ClientHello message was received. This also decreases memory consumption if plain HTTP request is sent to SSL socket. Modified: trunk/src/http/ngx_http_request.c trunk/src/http/ngx_http_request.h Modified: trunk/src/http/ngx_http_request.c =================================================================== --- trunk/src/http/ngx_http_request.c 2013-02-27 17:16:51 UTC (rev 5091) +++ trunk/src/http/ngx_http_request.c 2013-02-27 17:21:21 UTC (rev 5092) @@ -316,6 +316,31 @@ rev->handler = ngx_http_init_request; c->write->handler = ngx_http_empty_handler; +#if (NGX_HTTP_SSL) + { + ngx_http_ssl_srv_conf_t *sscf; + + sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); + + if (sscf->enable || hc->addr_conf->ssl) { + + c->log->action = "SSL handshaking"; + + if (hc->addr_conf->ssl && sscf->ssl.ctx == NULL) { + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "no \"ssl_certificate\" is defined " + "in server listening on SSL port"); + ngx_http_close_connection(c); + return; + } + + hc->ssl = 1; + + rev->handler = ngx_http_ssl_handshake; + } + } +#endif + if (rev->ready) { /* the deferred accept(), rtsig, aio, iocp */ @@ -324,7 +349,7 @@ return; } - ngx_http_init_request(rev); + rev->handler(rev); return; } @@ -395,45 +420,8 @@ r->srv_conf = hc->conf_ctx->srv_conf; r->loc_conf = hc->conf_ctx->loc_conf; - rev->handler = ngx_http_process_request_line; r->read_event_handler = ngx_http_block_reading; -#if (NGX_HTTP_SSL) - - { - ngx_http_ssl_srv_conf_t *sscf; - - sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); - if (sscf->enable || hc->addr_conf->ssl) { - - if (c->ssl == NULL) { - - c->log->action = "SSL handshaking"; - - if (hc->addr_conf->ssl && sscf->ssl.ctx == NULL) { - ngx_log_error(NGX_LOG_ERR, c->log, 0, - "no \"ssl_certificate\" is defined " - "in server listening on SSL port"); - ngx_http_close_connection(c); - return; - } - - if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER) - != NGX_OK) - { - ngx_http_close_connection(c); - return; - } - - rev->handler = ngx_http_ssl_handshake; - } - - r->main_filter_need_in_memory = 1; - } - } - -#endif - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); ngx_http_set_connection_log(r->connection, clcf->error_log); @@ -489,6 +477,12 @@ c->single_connection = 1; c->destroyed = 0; +#if (NGX_HTTP_SSL) + if (c->ssl) { + r->main_filter_need_in_memory = 1; + } +#endif + r->main = r; r->count = 1; @@ -519,7 +513,8 @@ (void) ngx_atomic_fetch_add(ngx_stat_requests, 1); #endif - rev->handler(rev); + rev->handler = ngx_http_process_request_line; + ngx_http_process_request_line(rev); } @@ -528,37 +523,48 @@ static void ngx_http_ssl_handshake(ngx_event_t *rev) { - u_char buf[1]; - ssize_t n; - ngx_int_t rc; - ngx_connection_t *c; - ngx_http_request_t *r; + u_char buf[1]; + ssize_t n; + ngx_err_t err; + ngx_int_t rc; + ngx_connection_t *c; + ngx_http_connection_t *hc; + ngx_http_ssl_srv_conf_t *sscf; c = rev->data; - r = c->data; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http check ssl handshake"); if (rev->timedout) { ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); - c->timedout = 1; - ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT); + ngx_http_close_connection(c); return; } n = recv(c->fd, (char *) buf, 1, MSG_PEEK); - if (n == -1 && ngx_socket_errno == NGX_EAGAIN) { + err = ngx_socket_errno; - if (!rev->timer_set) { - ngx_add_timer(rev, c->listening->post_accept_timeout); - } + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http recv(): %d", n); - if (ngx_handle_read_event(rev, 0) != NGX_OK) { - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + if (n == -1) { + if (err == NGX_EAGAIN) { + + if (!rev->timer_set) { + ngx_add_timer(rev, c->listening->post_accept_timeout); + } + + if (ngx_handle_read_event(rev, 0) != NGX_OK) { + ngx_http_close_connection(c); + } + + return; } + ngx_connection_error(c, err, "recv() failed"); + ngx_http_close_connection(c); + return; } @@ -567,6 +573,17 @@ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "https ssl handshake: 0x%02Xd", buf[0]); + hc = c->data; + sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, + ngx_http_ssl_module); + + if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER) + != NGX_OK) + { + ngx_http_close_connection(c); + return; + } + rc = ngx_ssl_handshake(c); if (rc == NGX_AGAIN) { @@ -582,27 +599,26 @@ ngx_http_ssl_handshake_handler(c); return; + } - } else { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, - "plain http"); + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "plain http"); - r->plain_http = 1; - } + c->log->action = "reading client request line"; + + rev->handler = ngx_http_init_request; + ngx_http_init_request(rev); + + return; } - c->log->action = "reading client request line"; - - rev->handler = ngx_http_process_request_line; - ngx_http_process_request_line(rev); + ngx_log_error(NGX_LOG_INFO, c->log, 0, "client closed connection"); + ngx_http_close_connection(c); } static void ngx_http_ssl_handshake_handler(ngx_connection_t *c) { - ngx_http_request_t *r; - if (c->ssl->handshaked) { /* @@ -617,19 +633,19 @@ c->log->action = "reading client request line"; - c->read->handler = ngx_http_process_request_line; + c->read->handler = ngx_http_init_request; /* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler; - ngx_http_process_request_line(c->read); + ngx_http_init_request(c->read); return; } - r = c->data; + if (c->read->timedout) { + ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out"); + } - ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST); - - return; + ngx_http_close_connection(c); } #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME @@ -640,7 +656,6 @@ ngx_str_t host; const char *servername; ngx_connection_t *c; - ngx_http_request_t *r; ngx_http_connection_t *hc; ngx_http_ssl_srv_conf_t *sscf; ngx_http_core_loc_conf_t *clcf; @@ -663,15 +678,13 @@ return SSL_TLSEXT_ERR_NOACK; } - r = c->data; - host.data = (u_char *) servername; - if (ngx_http_validate_host(&host, r->pool, 1) != NGX_OK) { + if (ngx_http_validate_host(&host, c->pool, 1) != NGX_OK) { return SSL_TLSEXT_ERR_NOACK; } - hc = r->http_connection; + hc = c->data; if (ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host, NULL, &cscf) @@ -682,14 +695,11 @@ hc->conf_ctx = cscf->ctx; - r->srv_conf = cscf->ctx->srv_conf; - r->loc_conf = cscf->ctx->loc_conf; + clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module); - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - ngx_http_set_connection_log(c, clcf->error_log); - sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); + sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); if (sscf->ssl.ctx) { SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx); @@ -1631,20 +1641,20 @@ c = r->connection; - if (r->plain_http) { - ngx_log_error(NGX_LOG_INFO, c->log, 0, - "client sent plain HTTP request to HTTPS port"); - ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS); - return; - } - #if (NGX_HTTP_SSL) - if (c->ssl) { + if (r->http_connection->ssl) { long rc; X509 *cert; ngx_http_ssl_srv_conf_t *sscf; + if (c->ssl == NULL) { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client sent plain HTTP request to HTTPS port"); + ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS); + return; + } + sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); if (sscf->verify) { Modified: trunk/src/http/ngx_http_request.h =================================================================== --- trunk/src/http/ngx_http_request.h 2013-02-27 17:16:51 UTC (rev 5091) +++ trunk/src/http/ngx_http_request.h 2013-02-27 17:21:21 UTC (rev 5092) @@ -303,7 +303,8 @@ ngx_buf_t **free; ngx_int_t nfree; - ngx_uint_t pipeline; /* unsigned pipeline:1; */ + unsigned pipeline:1; + unsigned ssl:1; } ngx_http_connection_t; @@ -492,7 +493,6 @@ #endif unsigned pipeline:1; - unsigned plain_http:1; unsigned chunked:1; unsigned header_only:1; unsigned keepalive:1; From vbart at nginx.com Wed Feb 27 17:27:16 2013 From: vbart at nginx.com (vbart at nginx.com) Date: Wed, 27 Feb 2013 17:27:16 +0000 Subject: [nginx] svn commit: r5093 - trunk/src/http Message-ID: <20130227172717.155523FA158@mail.nginx.com> Author: vbart Date: 2013-02-27 17:27:15 +0000 (Wed, 27 Feb 2013) New Revision: 5093 URL: http://trac.nginx.org/nginx/changeset/5093/nginx Log: Apply server configuration as soon as host is known. Previously, this was done only after the whole request header was parsed, and if an error occurred earlier then the request was processed in the default server (or server chosen by SNI), while r->headers_in.server might be set to the value from the Host: header or host from request line. r->headers_in.server is in turn used for $host variable and in HTTP redirects if "server_name_in_redirect" is disabled. Without the change, configurations that rely on this during error handling are potentially unsafe if SNI is used. This change also allows to use server specific settings of "underscores_in_headers", "ignore_invalid_headers", and "large_client_header_buffers" directives for HTTP requests and HTTPS requests without SNI. Modified: trunk/src/http/ngx_http_request.c Modified: trunk/src/http/ngx_http_request.c =================================================================== --- trunk/src/http/ngx_http_request.c 2013-02-27 17:21:21 UTC (rev 5092) +++ trunk/src/http/ngx_http_request.c 2013-02-27 17:27:15 UTC (rev 5093) @@ -919,13 +919,18 @@ return; } + if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) { + return; + } + r->headers_in.server = host; } if (r->http_version < NGX_HTTP_VERSION_10) { - if (ngx_http_set_virtual_server(r, &r->headers_in.server) - == NGX_ERROR) + if (r->headers_in.server.len == 0 + && ngx_http_set_virtual_server(r, &r->headers_in.server) + == NGX_ERROR) { return; } @@ -1014,7 +1019,6 @@ } cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); rc = NGX_AGAIN; @@ -1068,6 +1072,9 @@ } } + /* the host header could change the server configuration context */ + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); + rc = ngx_http_parse_header_line(r, r->header_in, cscf->underscores_in_headers); @@ -1444,6 +1451,10 @@ return NGX_OK; } + if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) { + return NGX_ERROR; + } + r->headers_in.server = host; return NGX_OK; @@ -1570,7 +1581,10 @@ static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r) { - if (ngx_http_set_virtual_server(r, &r->headers_in.server) == NGX_ERROR) { + if (r->headers_in.server.len == 0 + && ngx_http_set_virtual_server(r, &r->headers_in.server) + == NGX_ERROR) + { return NGX_ERROR; } From vbart at nginx.com Wed Feb 27 17:34:00 2013 From: vbart at nginx.com (vbart at nginx.com) Date: Wed, 27 Feb 2013 17:34:00 +0000 Subject: [nginx] svn commit: r5094 - trunk/src/http Message-ID: <20130227173400.3809C3FA036@mail.nginx.com> Author: vbart Date: 2013-02-27 17:33:59 +0000 (Wed, 27 Feb 2013) New Revision: 5094 URL: http://trac.nginx.org/nginx/changeset/5094/nginx Log: SNI: avoid surplus lookup of virtual server if SNI was used. Modified: trunk/src/http/ngx_http_request.c trunk/src/http/ngx_http_request.h Modified: trunk/src/http/ngx_http_request.c =================================================================== --- trunk/src/http/ngx_http_request.c 2013-02-27 17:27:15 UTC (rev 5093) +++ trunk/src/http/ngx_http_request.c 2013-02-27 17:33:59 UTC (rev 5094) @@ -693,6 +693,13 @@ return SSL_TLSEXT_ERR_NOACK; } + hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t)); + if (hc->ssl_servername == NULL) { + return SSL_TLSEXT_ERR_NOACK; + } + + *hc->ssl_servername = host; + hc->conf_ctx = cscf->ctx; clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module); @@ -1831,6 +1838,28 @@ hc = r->http_connection; +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + + if (hc->ssl_servername) { + if (hc->ssl_servername->len == host->len + && ngx_strncmp(hc->ssl_servername->data, + host->data, host->len) == 0) + { +#if (NGX_PCRE) + if (hc->ssl_servername_regex + && ngx_http_regex_exec(r, hc->ssl_servername_regex, + hc->ssl_servername) != NGX_OK) + { + ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_ERROR; + } +#endif + return NGX_OK; + } + } + +#endif + rc = ngx_http_find_virtual_server(r->connection, hc->addr_conf->virtual_names, host, r, &cscf); @@ -1887,6 +1916,8 @@ #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME if (r == NULL) { + ngx_http_connection_t *hc; + for (i = 0; i < virtual_names->nregex; i++) { n = ngx_regex_exec(sn[i].regex->regex, host, NULL, 0); @@ -1896,6 +1927,9 @@ } if (n >= 0) { + hc = c->data; + hc->ssl_servername_regex = sn[i].regex; + *cscfp = sn[i].server; return NGX_OK; } Modified: trunk/src/http/ngx_http_request.h =================================================================== --- trunk/src/http/ngx_http_request.h 2013-02-27 17:27:15 UTC (rev 5093) +++ trunk/src/http/ngx_http_request.h 2013-02-27 17:33:59 UTC (rev 5094) @@ -295,6 +295,13 @@ ngx_http_addr_conf_t *addr_conf; ngx_http_conf_ctx_t *conf_ctx; +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + ngx_str_t *ssl_servername; +#if (NGX_PCRE) + ngx_http_regex_t *ssl_servername_regex; +#endif +#endif + ngx_http_request_t *request; ngx_buf_t **busy; From vbart at nginx.com Wed Feb 27 17:38:55 2013 From: vbart at nginx.com (vbart at nginx.com) Date: Wed, 27 Feb 2013 17:38:55 +0000 Subject: [nginx] svn commit: r5095 - trunk/src/http Message-ID: <20130227173855.3CAEF3FAA81@mail.nginx.com> Author: vbart Date: 2013-02-27 17:38:54 +0000 (Wed, 27 Feb 2013) New Revision: 5095 URL: http://trac.nginx.org/nginx/changeset/5095/nginx Log: SNI: reset to default server if requested host was not found. Not only this is consistent with a case without SNI, but this also prevents abusing configurations that assume that the $host variable is limited to one of the configured names for a server. An example of potentially unsafe configuration: server { listen 443 ssl default_server; ... } server { listen 443; server_name example.com; location / { proxy_pass http://$host; } } Note: it is possible to negotiate "example.com" by SNI, and to request arbitrary host name that does not exist in the configuration above. Modified: trunk/src/http/ngx_http_request.c Modified: trunk/src/http/ngx_http_request.c =================================================================== --- trunk/src/http/ngx_http_request.c 2013-02-27 17:33:59 UTC (rev 5094) +++ trunk/src/http/ngx_http_request.c 2013-02-27 17:38:54 UTC (rev 5095) @@ -1869,6 +1869,17 @@ return NGX_ERROR; } +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + + if (hc->ssl_servername) { + if (rc == NGX_DECLINED) { + cscf = hc->addr_conf->default_server; + rc = NGX_OK; + } + } + +#endif + if (rc == NGX_DECLINED) { return NGX_OK; } From vbart at nginx.com Wed Feb 27 17:41:34 2013 From: vbart at nginx.com (vbart at nginx.com) Date: Wed, 27 Feb 2013 17:41:34 +0000 Subject: [nginx] svn commit: r5096 - trunk/src/http Message-ID: <20130227174135.119263FAA81@mail.nginx.com> Author: vbart Date: 2013-02-27 17:41:34 +0000 (Wed, 27 Feb 2013) New Revision: 5096 URL: http://trac.nginx.org/nginx/changeset/5096/nginx Log: SNI: added restriction on requesting host other than negotiated. According to RFC 6066, client is not supposed to request a different server name at the application layer. Server implementations that rely upon these names being equal must validate that a client did not send a different name in HTTP request. Current versions of Apache HTTP server always return 400 "Bad Request" in such cases. There exist implementations however (e.g., SPDY) that rely on being able to request different host names in one connection. Given this, we only reject requests with differing host names if verification of client certificates is enabled in a corresponding server configuration. An example of configuration that might not work as expected: server { listen 433 ssl default; return 404; } server { listen 433 ssl; server_name example.org; ssl_client_certificate org.cert; ssl_verify_client on; } server { listen 433 ssl; server_name example.com; ssl_client_certificate com.cert; ssl_verify_client on; } Previously, a client was able to request example.com by presenting a certificate for example.org, and vice versa. Modified: trunk/src/http/ngx_http_request.c Modified: trunk/src/http/ngx_http_request.c =================================================================== --- trunk/src/http/ngx_http_request.c 2013-02-27 17:38:54 UTC (rev 5095) +++ trunk/src/http/ngx_http_request.c 2013-02-27 17:41:34 UTC (rev 5096) @@ -1872,10 +1872,22 @@ #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME if (hc->ssl_servername) { + ngx_http_ssl_srv_conf_t *sscf; + if (rc == NGX_DECLINED) { cscf = hc->addr_conf->default_server; rc = NGX_OK; } + + sscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_ssl_module); + + if (sscf->verify) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client attempted to request the server name " + "different from that one was negotiated"); + ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); + return NGX_ERROR; + } } #endif