summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2006-10-31 15:28:55 +0000
committerJonathan Kolb <jon@b0g.us>2006-10-31 15:28:55 +0000
commitb60d32b68e395bca2de29fb9de41e13f173d6b2b (patch)
tree813d84976b554dc3464ea51ec6cd3bf8a8e648e8
parentf93a68b72b7aecd45263df647c742e36399a145e (diff)
downloadnginx-b60d32b68e395bca2de29fb9de41e13f173d6b2b.tar.gz
Changes with nginx 0.4.12 31 Oct 2006v0.4.12
*) Feature: the ngx_http_perl_module supports the $r->variable method. *) Bugfix: if a big static file was included using SSI in a response, then the response may be transferred incomplete. *) Bugfix: nginx did not omit the "#fragment" part in URI.
-rw-r--r--CHANGES10
-rw-r--r--CHANGES.ru11
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_connection.h6
-rw-r--r--src/core/ngx_output_chain.c2
-rw-r--r--src/core/ngx_string.c124
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c7
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/modules/perl/nginx.xs83
-rw-r--r--src/http/ngx_http_copy_filter_module.c12
-rw-r--r--src/http/ngx_http_parse.c180
-rw-r--r--src/http/ngx_http_request.c2
-rw-r--r--src/http/ngx_http_request.h12
13 files changed, 338 insertions, 115 deletions
diff --git a/CHANGES b/CHANGES
index 1cd55cc2b..20a3ec9ff 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,14 @@
+Changes with nginx 0.4.12 31 Oct 2006
+
+ *) Feature: the ngx_http_perl_module supports the $r->variable method.
+
+ *) Bugfix: if a big static file was included using SSI in a response,
+ then the response may be transferred incomplete.
+
+ *) Bugfix: nginx did not omit the "#fragment" part in URI.
+
+
Changes with nginx 0.4.11 25 Oct 2006
*) Feature: the POP3 proxy supports the AUTH LOGIN PLAIN and CRAM-MD5.
diff --git a/CHANGES.ru b/CHANGES.ru
index 4a79103d0..2ab4ec22f 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,15 @@
+Изменения в nginx 0.4.12 31.10.2006
+
+ *) Добавление: модуль ngx_http_perl_module поддерживает метод
+ $r->variable.
+
+ *) Исправление: при включении в ответ большого статического файла с
+ помощью SSI ответ мог передаваться не полностью.
+
+ *) Исправление: nginx не убирал "#fragment" в URI.
+
+
Изменения в nginx 0.4.11 25.10.2006
*) Добавление: POP3 прокси поддерживает AUTH LOIGN PLAIN и CRAM-MD5.
diff --git a/src/core/nginx.h b/src/core/nginx.h
index c151098a4..d3e298721 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.4.11"
+#define NGINX_VERSION "0.4.12"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h
index 2c694fa27..1694dd451 100644
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -92,8 +92,8 @@ typedef enum {
} ngx_connection_tcp_nopush_e;
-#define NGX_LOWLEVEL_BUFFERED 0x0000000f
-#define NGX_SSL_BUFFERED 0x00000001
+#define NGX_LOWLEVEL_BUFFERED 0x0f
+#define NGX_SSL_BUFFERED 0x01
struct ngx_connection_s {
@@ -133,7 +133,7 @@ struct ngx_connection_s {
ngx_atomic_uint_t number;
- ngx_uint_t buffered;
+ unsigned buffered:8;
unsigned log_error:2; /* ngx_connection_log_error_e */
diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c
index 4b8364a69..4479edacc 100644
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -445,7 +445,7 @@ ngx_chain_writer(void *data, ngx_chain_t *in)
size += ngx_buf_size(in->buf);
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->connection->log, 0,
- "chain writer buf size: %uz", ngx_buf_size(in->buf));
+ "chain writer buf size: %uO", ngx_buf_size(in->buf));
cl = ngx_alloc_chain_link(ctx->pool);
if (cl == NULL) {
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 886fe00c6..ad2c9d8c8 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -688,24 +688,25 @@ ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src)
{
size_t len;
u_char *d, *s;
- static u_char basis64[] =
- { 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 62, 77, 77, 77, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 77, 77, 77, 77, 77, 77,
- 77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 77, 77, 77, 77, 77,
- 77, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 77, 77, 77, 77, 77,
-
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77 };
+ static u_char basis64[] = {
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 62, 77, 77, 77, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 77, 77, 77, 77, 77, 77,
+ 77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 77, 77, 77, 77, 77,
+ 77, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 77, 77, 77, 77, 77,
+
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77
+ };
for (len = 0; len < src->len; len++) {
if (src->data[len] == '=') {
@@ -887,66 +888,69 @@ ngx_utf_cpystrn(u_char *dst, u_char *src, size_t n)
uintptr_t
ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
{
- ngx_uint_t i, n;
- uint32_t *escape;
- static u_char hex[] = "0123456789abcdef";
+ ngx_uint_t i, n;
+ uint32_t *escape;
+ static u_char hex[] = "0123456789abcdef";
- /* " ", "#", "%", "?", %00-%1F, %7F-%FF */
+ /* " ", "#", "%", "?", %00-%1F, %7F-%FF */
- static uint32_t uri[] =
- { 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ static uint32_t uri[] = {
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
- 0x80000029, /* 1000 0000 0000 0000 0000 0000 0010 1001 */
+ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
+ 0x80000029, /* 1000 0000 0000 0000 0000 0000 0010 1001 */
- /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
- 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
+ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
- /* ~}| {zyx wvut srqp onml kjih gfed cba` */
- 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
+ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
+ 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ };
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ };
- /* " ", "#", "%", "+", "?", %00-%1F, %7F-%FF */
+ /* " ", "#", "%", "+", "?", %00-%1F, %7F-%FF */
- static uint32_t args[] =
- { 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ static uint32_t args[] = {
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
- 0x80000829, /* 1000 0000 0000 0000 0000 1000 0010 1001 */
+ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
+ 0x80000829, /* 1000 0000 0000 0000 0000 1000 0010 1001 */
- /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
- 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
+ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
- /* ~}| {zyx wvut srqp onml kjih gfed cba` */
- 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
+ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
+ 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ };
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ };
- /* " ", """, "%", "'", %00-%1F, %7F-%FF */
+ /* " ", """, "%", "'", %00-%1F, %7F-%FF */
- static uint32_t html[] =
- { 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ static uint32_t html[] = {
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
- 0x800000ad, /* 0000 0000 0000 0000 0000 0000 1010 1101 */
+ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
+ 0x800000ad, /* 0000 0000 0000 0000 0000 0000 1010 1101 */
- /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
- 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
+ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
- /* ~}| {zyx wvut srqp onml kjih gfed cba` */
- 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
+ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
+ 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
- 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ };
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ };
switch (type) {
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index dc0249867..1ee34db00 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -973,6 +973,13 @@ ngx_http_ssi_output(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
}
}
+ if (ctx->in || ctx->buf) {
+ r->buffered |= NGX_HTTP_SSI_BUFFERED;
+
+ } else {
+ r->buffered &= ~NGX_HTTP_SSI_BUFFERED;
+ }
+
return rc;
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 5f329493b..036ca699e 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -17,7 +17,7 @@ our @EXPORT = qw(
HTTP_SERVER_ERROR
);
-our $VERSION = '0.4.11';
+our $VERSION = '0.4.12';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index d337edbd8..90b4c57a9 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -763,3 +763,86 @@ unescape(r, text, type = 0)
ngx_http_perl_set_targ(p, dst - p, 1);
ST(0) = TARG;
+
+
+void
+variable(r, name, value = NULL)
+ CODE:
+
+ dXSTARG;
+ ngx_http_request_t *r;
+ SV *name, *value;
+ u_char *p, *lowcase;
+ STRLEN len;
+ ngx_str_t var, val;
+ ngx_uint_t i, hash;
+ ngx_http_variable_value_t *vv;
+
+ ngx_http_perl_set_request(r);
+
+ name = ST(1);
+
+ if (SvROK(name) && SvTYPE(SvRV(name)) == SVt_PV) {
+ name = SvRV(name);
+ }
+
+ if (items == 2) {
+ value = NULL;
+
+ } else {
+ value = ST(2);
+
+ if (SvROK(value) && SvTYPE(SvRV(value)) == SVt_PV) {
+ value = SvRV(value);
+ }
+
+ if (ngx_http_perl_sv2str(aTHX_ r, &val, value) != NGX_OK) {
+ XSRETURN_UNDEF;
+ }
+ }
+
+ p = (u_char *) SvPV(name, len);
+
+ lowcase = ngx_palloc(r->pool, len);
+ if (lowcase == NULL) {
+ XSRETURN_UNDEF;
+ }
+
+ hash = 0;
+ for (i = 0; i < len; i++) {
+ lowcase[i] = ngx_tolower(p[i]);
+ hash = ngx_hash(hash, lowcase[i]);
+ }
+
+ var.len = len;
+ var.data = lowcase;
+
+ vv = ngx_http_get_variable(r, &var, hash, 1);
+ if (vv == NULL) {
+ XSRETURN_UNDEF;
+ }
+
+ if (vv->not_found) {
+ if (value == NULL) {
+ XSRETURN_UNDEF;
+ }
+
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "variable \"%V\" not found", &var);
+
+ XSRETURN_UNDEF;
+ }
+
+ if (value) {
+ vv->len = val.len;
+ vv->valid = 1;
+ vv->no_cachable = 0;
+ vv->not_found = 0;
+ vv->data = val.data;
+
+ XSRETURN_UNDEF;
+ }
+
+ ngx_http_perl_set_targ(vv->data, vv->len, 0);
+
+ ST(0) = TARG;
diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c
index 311c195b9..c96dbfa76 100644
--- a/src/http/ngx_http_copy_filter_module.c
+++ b/src/http/ngx_http_copy_filter_module.c
@@ -109,13 +109,21 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
rc = ngx_output_chain(ctx, in);
-#if (NGX_DEBUG)
if (!c->destroyed) {
+
+ if (ctx->in == NULL) {
+ r->buffered &= ~NGX_HTTP_COPY_BUFFERED;
+ } else {
+ r->buffered |= NGX_HTTP_COPY_BUFFERED;
+ }
+
+#if (NGX_DEBUG)
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args);
- }
#endif
+ }
+
return rc;
}
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index bbda9ecd8..3151304a9 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -9,6 +9,29 @@
#include <ngx_http.h>
+static uint32_t usual[] = {
+ 0xffffdbfe, /* 1111 1111 1111 1111 1101 1011 1111 1110 */
+
+ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
+ 0x7fff37d6, /* 0111 1111 1111 1111 0011 0111 1101 0110 */
+
+ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
+#if (NGX_WIN32)
+ 0xefffffff, /* 1110 1111 1111 1111 1111 1111 1111 1111 */
+#else
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+#endif
+
+ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+};
+
+
/* gcc, icc, msvc and others compile these switches as an jump table */
ngx_int_t
@@ -18,7 +41,6 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
enum {
sw_start = 0,
sw_method,
- sw_space_after_method,
sw_spaces_before_uri,
sw_schema,
sw_schema_slash,
@@ -118,20 +140,15 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
break;
- /* single space after method */
- case sw_space_after_method:
- switch (ch) {
- case ' ':
- state = sw_spaces_before_uri;
- break;
- default:
- return NGX_HTTP_PARSE_INVALID_METHOD;
- }
- break;
-
/* space* before URI */
case sw_spaces_before_uri:
+ if (ch == '/' ){
+ r->uri_start = p;
+ state = sw_after_slash_in_uri;
+ break;
+ }
+
c = (u_char) (ch | 0x20);
if (c >= 'a' && c <= 'z') {
r->schema_start = p;
@@ -140,10 +157,6 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
}
switch (ch) {
- case '/':
- r->uri_start = p;
- state = sw_after_slash_in_uri;
- break;
case ' ':
break;
default:
@@ -196,8 +209,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
break;
}
- if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '-')
- {
+ if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '-') {
break;
}
@@ -235,13 +247,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
/* check "/.", "//", "%", and "\" (Win32) in URI */
case sw_after_slash_in_uri:
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'z') {
- state = sw_check_uri;
- break;
- }
-
- if (ch >= '0' && ch <= '9') {
+ if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
state = sw_check_uri;
break;
}
@@ -282,6 +288,10 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
r->args_start = p + 1;
state = sw_uri;
break;
+ case '#':
+ r->complex_uri = 1;
+ state = sw_uri;
+ break;
case '+':
r->plus_in_uri = 1;
break;
@@ -297,12 +307,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
/* check "/", "%" and "\" (Win32) in URI */
case sw_check_uri:
- c = (u_char) (ch | 0x20);
- if (c >= 'a' && c <= 'z') {
- break;
- }
-
- if (ch >= '0' && ch <= '9') {
+ if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
break;
}
@@ -341,6 +346,10 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
r->args_start = p + 1;
state = sw_uri;
break;
+ case '#':
+ r->complex_uri = 1;
+ state = sw_uri;
+ break;
case '+':
r->plus_in_uri = 1;
break;
@@ -352,6 +361,11 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
/* URI */
case sw_uri:
+
+ if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ break;
+ }
+
switch (ch) {
case ' ':
r->uri_end = p;
@@ -366,6 +380,9 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
r->uri_end = p;
r->http_minor = 9;
goto done;
+ case '#':
+ r->complex_uri = 1;
+ break;
case '\0':
r->zero_in_uri = 1;
break;
@@ -792,6 +809,13 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
switch (state) {
case sw_usual:
+
+ if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ *u++ = ch;
+ ch = *p++;
+ break;
+ }
+
switch(ch) {
#if (NGX_WIN32)
case '\\':
@@ -822,6 +846,8 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
break;
case '?':
r->args_start = p;
+ goto args;
+ case '#':
goto done;
case '.':
r->uri_ext = u + 1;
@@ -833,10 +859,19 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
*u++ = ch;
break;
}
+
ch = *p++;
break;
case sw_slash:
+
+ if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ state = sw_usual;
+ *u++ = ch;
+ ch = *p++;
+ break;
+ }
+
switch(ch) {
#if (NGX_WIN32)
case '\\':
@@ -853,6 +888,8 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
break;
case '?':
r->args_start = p;
+ goto args;
+ case '#':
goto done;
case '+':
r->plus_in_uri = 1;
@@ -861,10 +898,19 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
*u++ = ch;
break;
}
+
ch = *p++;
break;
case sw_dot:
+
+ if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ state = sw_usual;
+ *u++ = ch;
+ ch = *p++;
+ break;
+ }
+
switch(ch) {
#if (NGX_WIN32)
case '\\':
@@ -883,6 +929,8 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
break;
case '?':
r->args_start = p;
+ goto args;
+ case '#':
goto done;
case '+':
r->plus_in_uri = 1;
@@ -891,10 +939,19 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
*u++ = ch;
break;
}
+
ch = *p++;
break;
case sw_dot_dot:
+
+ if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ state = sw_usual;
+ *u++ = ch;
+ ch = *p++;
+ break;
+ }
+
switch(ch) {
#if (NGX_WIN32)
case '\\':
@@ -915,6 +972,8 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
break;
case '?':
r->args_start = p;
+ goto args;
+ case '#':
goto done;
#if (NGX_WIN32)
case '.':
@@ -929,11 +988,20 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
*u++ = ch;
break;
}
+
ch = *p++;
break;
#if (NGX_WIN32)
case sw_dot_dot_dot:
+
+ if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ state = sw_usual;
+ *u++ = ch;
+ ch = *p++;
+ break;
+ }
+
switch(ch) {
case '\\':
case '/':
@@ -958,6 +1026,8 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
break;
case '?':
r->args_start = p;
+ goto args;
+ case '#':
goto done;
case '+':
r->plus_in_uri = 1;
@@ -966,6 +1036,7 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
*u++ = ch;
break;
}
+
ch = *p++;
break;
#endif
@@ -1001,7 +1072,11 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
break;
}
- if (ch == '\0') {
+ if (ch == '#') {
+ *u++ = ch;
+ ch = *p++;
+
+ } else if (ch == '\0') {
r->zero_in_uri = 1;
}
@@ -1032,7 +1107,31 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r)
done:
r->uri.len = u - r->uri.data;
- r->uri.data[r->uri.len] = '\0';
+
+ if (r->uri_ext) {
+ r->exten.len = u - r->uri_ext;
+ r->exten.data = r->uri_ext;
+ }
+
+ r->uri_ext = NULL;
+
+ return NGX_OK;
+
+args:
+
+ while (p < r->uri_end) {
+ if (*p++ != '#') {
+ continue;
+ }
+
+ r->args.len = p - 1 - r->args_start;
+ r->args.data = r->args_start;
+ r->args_start = NULL;
+
+ break;
+ }
+
+ r->uri.len = u - r->uri.data;
if (r->uri_ext) {
r->exten.len = u - r->uri_ext;
@@ -1072,6 +1171,10 @@ ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
ch = *p++;
+ if (usual[ch >> 5] & (1 << (ch & 0x1f))) {
+ continue;
+ }
+
if (ch == '?') {
args->len = len - 1;
args->data = p;
@@ -1085,17 +1188,12 @@ ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
continue;
}
- if (ch != '/'
+ if ((ch == '/'
#if (NGX_WIN32)
- && ch != '\\'
+ || ch == '\\'
#endif
- )
+ ) && len > 2)
{
- continue;
- }
-
- if (len > 2) {
-
/* detect "/../" */
if (p[0] == '.' && p[1] == '.' && p[2] == '/') {
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index a7bbcddd5..951db75e4 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1736,7 +1736,7 @@ ngx_http_writer(ngx_http_request_t *r)
ngx_http_close_request(r, 0);
}
- if (r == r->main) {
+ if (r == r->main || r->buffered) {
return;
}
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 1e98b2df0..57ffe4c77 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -111,11 +111,11 @@
#define NGX_HTTP_INSUFFICIENT_STORAGE 507
-#define NGX_HTTP_LOWLEVEL_BUFFERED 0x000000f0
-#define NGX_HTTP_WRITE_BUFFERED 0x00000010
-#define NGX_HTTP_GZIP_BUFFERED 0x00000020
-#define NGX_HTTP_SSI_BUFFERED 0x00000100
-#define NGX_HTTP_COPY_BUFFERED 0x00000200
+#define NGX_HTTP_LOWLEVEL_BUFFERED 0xf0
+#define NGX_HTTP_WRITE_BUFFERED 0x10
+#define NGX_HTTP_GZIP_BUFFERED 0x20
+#define NGX_HTTP_SSI_BUFFERED 0x01
+#define NGX_HTTP_COPY_BUFFERED 0x02
typedef enum {
@@ -452,6 +452,8 @@ struct ngx_http_request_s {
unsigned done:1;
unsigned utf8:1;
+ unsigned buffered:4;
+
unsigned main_filter_need_in_memory:1;
unsigned filter_need_in_memory:1;
unsigned filter_need_temporary:1;