summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2007-07-09 06:57:23 +0000
committerJonathan Kolb <jon@b0g.us>2007-07-09 06:57:23 +0000
commit8aa92bfd2642d24b664564c39290185efe1ed670 (patch)
tree1a0c4d752006601faea51aee6a588b247464033c
parent373100239c2731609f7198bbe37d972052fe03be (diff)
downloadnginx-8aa92bfd2642d24b664564c39290185efe1ed670.tar.gz
Changes with nginx 0.6.2 09 Jul 2007v0.6.2
*) Bugfix: if the FastCGI header was split in records, then nginx passed garbage in the header to a client.
-rw-r--r--CHANGES6
-rw-r--r--CHANGES.ru6
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c115
-rw-r--r--src/http/modules/ngx_http_log_module.c5
-rw-r--r--src/http/modules/perl/nginx.pm2
6 files changed, 113 insertions, 23 deletions
diff --git a/CHANGES b/CHANGES
index f8eab2f8d..d053b0e20 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,10 @@
+Changes with nginx 0.6.2 09 Jul 2007
+
+ *) Bugfix: if the FastCGI header was split in records, then nginx
+ passed garbage in the header to a client.
+
+
Changes with nginx 0.6.1 17 Jun 2007
*) Bugfix: in SSI parsing.
diff --git a/CHANGES.ru b/CHANGES.ru
index c2e14f312..356178611 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,10 @@
+Изменения в nginx 0.6.2 09.07.2007
+
+ *) Исправление: если заголовок ответа был разделён в FastCGI-записях,
+ то nginx передавал клиенту мусор в таких заголовках.
+
+
Изменения в nginx 0.6.1 17.06.2007
*) Исправление: в парсинге SSI.
diff --git a/src/core/nginx.h b/src/core/nginx.h
index b76532874..8a99384e8 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.6.1"
+#define NGINX_VERSION "0.6.2"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 6daf6ce39..246574b13 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -38,6 +38,12 @@ typedef enum {
typedef struct {
+ u_char *start;
+ u_char *end;
+} ngx_http_fastcgi_split_part_t;
+
+
+typedef struct {
ngx_http_fastcgi_state_e state;
u_char *pos;
u_char *last;
@@ -45,7 +51,9 @@ typedef struct {
size_t length;
size_t padding;
- ngx_uint_t fastcgi_stdout;
+ ngx_uint_t fastcgi_stdout; /* unsigned :1 */
+
+ ngx_array_t *split_parts;
} ngx_http_fastcgi_ctx_t;
@@ -840,15 +848,18 @@ ngx_http_fastcgi_reinit_request(ngx_http_request_t *r)
static ngx_int_t
ngx_http_fastcgi_process_header(ngx_http_request_t *r)
{
- u_char *start, *last;
+ u_char *p, *start, *last, *part_start;
+ size_t size;
ngx_str_t *status_line, line, *pattern;
ngx_int_t rc, status;
+ ngx_buf_t buf;
ngx_uint_t i;
ngx_table_elt_t *h;
ngx_http_upstream_t *u;
ngx_http_fastcgi_ctx_t *f;
ngx_http_upstream_header_t *hh;
ngx_http_fastcgi_loc_conf_t *flcf;
+ ngx_http_fastcgi_split_part_t *part;
ngx_http_upstream_main_conf_t *umcf;
f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
@@ -1017,6 +1028,8 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
for ( ;; ) {
+ part_start = u->buffer.pos;
+
rc = ngx_http_parse_header_line(r, &u->buffer);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -1035,23 +1048,71 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- h->hash = r->header_hash;
+ if (f->split_parts && f->split_parts->nelts) {
- h->key.len = r->header_name_end - r->header_name_start;
- h->value.len = r->header_end - r->header_start;
+ part = f->split_parts->elts;
+ size = u->buffer.pos - part_start;
- h->key.data = ngx_palloc(r->pool,
- h->key.len + 1 + h->value.len + 1 + h->key.len);
- if (h->key.data == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
+ for (i = 0; i < f->split_parts->nelts; i++) {
+ size += part[i].end - part[i].start;
+ }
+
+ p = ngx_palloc(r->pool, size);
+ if (p == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ buf.pos = p;
+
+ for (i = 0; i < f->split_parts->nelts; i++) {
+ p = ngx_cpymem(p, part[i].start,
+ part[i].end - part[i].start);
+ }
+
+ p = ngx_cpymem(p, part_start, u->buffer.pos - part_start);
+
+ buf.last = p;
+
+ f->split_parts->nelts = 0;
+
+ rc = ngx_http_parse_header_line(r, &buf);
+
+ h->key.len = r->header_name_end - r->header_name_start;
+ h->key.data = r->header_name_start;
+ h->key.data[h->key.len] = '\0';
- h->value.data = h->key.data + h->key.len + 1;
- h->lowcase_key = h->key.data + h->key.len + 1
- + h->value.len + 1;
+ h->value.len = r->header_end - r->header_start;
+ h->value.data = r->header_start;
+ h->value.data[h->value.len] = '\0';
- ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
- ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
+ h->lowcase_key = ngx_palloc(r->pool, h->key.len);
+ if (h->lowcase_key == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ } else {
+
+ h->key.len = r->header_name_end - r->header_name_start;
+ h->value.len = r->header_end - r->header_start;
+
+ h->key.data = ngx_palloc(r->pool,
+ h->key.len + 1 + h->value.len + 1
+ + h->key.len);
+ if (h->key.data == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ h->value.data = h->key.data + h->key.len + 1;
+ h->lowcase_key = h->key.data + h->key.len + 1
+ + h->value.len + 1;
+
+ ngx_cpystrn(h->key.data, r->header_name_start,
+ h->key.len + 1);
+ ngx_cpystrn(h->value.data, r->header_start,
+ h->value.len + 1);
+ }
+
+ h->hash = r->header_hash;
if (h->key.len == r->lowcase_index) {
ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
@@ -1123,7 +1184,6 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
"upstream sent invalid header");
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
-
}
if (last) {
@@ -1144,16 +1204,29 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
return NGX_OK;
}
- if (u->buffer.pos == u->buffer.last) {
+ if (rc == NGX_OK) {
return NGX_AGAIN;
}
- if (rc == NGX_AGAIN) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- "upstream split a header line in FastCGI records");
+ /* rc == NGX_AGAIN */
- return NGX_HTTP_UPSTREAM_INVALID_HEADER;
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "upstream split a header line in FastCGI records");
+
+ if (f->split_parts == NULL) {
+ f->split_parts = ngx_array_create(r->pool, 1,
+ sizeof(ngx_http_fastcgi_split_part_t));
+ if (f->split_parts == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
}
+
+ part = ngx_array_push(f->split_parts);
+
+ part->start = part_start;
+ part->end = u->buffer.last;
+
+ return NGX_AGAIN;
}
}
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
index d3ebca4f1..c06e556e4 100644
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -423,6 +423,11 @@ ngx_http_log_bytes_sent(ngx_http_request_t *r, u_char *buf,
}
+/*
+ * although there is a real $body_bytes_sent variable,
+ * this log operation code function is more optimized for logging
+ */
+
static u_char *
ngx_http_log_body_bytes_sent(ngx_http_request_t *r, u_char *buf,
ngx_http_log_op_t *op)
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 51002d1dc..5cab67d3a 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '0.6.1';
+our $VERSION = '0.6.2';
require XSLoader;
XSLoader::load('nginx', $VERSION);