aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2010-03-03 10:43:38 +0000
committerIgor Sysoev <igor@sysoev.ru>2010-03-03 10:43:38 +0000
commit593dec8b35e3997a18592e678845dedea28a57ef (patch)
treebba75c65db6a9751b8cec23ce7e9fb59e3826461 /src
parent750a65ef84bdf407127fccf86640639223518b26 (diff)
downloadnginx-593dec8b35e3997a18592e678845dedea28a57ef.tar.gz
nginx-593dec8b35e3997a18592e678845dedea28a57ef.zip
fix cached FastCGI response with large stderr output before header
Diffstat (limited to 'src')
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c57
-rw-r--r--src/http/ngx_http_file_cache.c3
2 files changed, 56 insertions, 4 deletions
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 710b98db7..845dd5f5e 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -62,7 +62,8 @@ typedef struct {
size_t length;
size_t padding;
- ngx_uint_t fastcgi_stdout; /* unsigned :1 */
+ unsigned fastcgi_stdout:1;
+ unsigned large_stderr:1;
ngx_array_t *split_parts;
@@ -1081,6 +1082,7 @@ ngx_http_fastcgi_reinit_request(ngx_http_request_t *r)
f->state = ngx_http_fastcgi_st_version;
f->fastcgi_stdout = 0;
+ f->large_stderr = 0;
return NGX_OK;
}
@@ -1099,6 +1101,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
ngx_table_elt_t *h;
ngx_http_upstream_t *u;
ngx_http_fastcgi_ctx_t *f;
+ ngx_http_fastcgi_header_t *fh;
ngx_http_upstream_header_t *hh;
ngx_http_fastcgi_loc_conf_t *flcf;
ngx_http_fastcgi_split_part_t *part;
@@ -1223,8 +1226,17 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
* of the PHP warnings to not allocate memory
*/
- u->buffer.pos = u->buffer.start;
- u->buffer.last = u->buffer.start;
+#if (NGX_HTTP_CACHE)
+ if (r->cache) {
+ u->buffer.pos = u->buffer.start
+ + r->cache->header_start;
+ } else {
+ u->buffer.pos = u->buffer.start;
+ }
+#endif
+
+ u->buffer.last = u->buffer.pos;
+ f->large_stderr = 1;
}
return NGX_AGAIN;
@@ -1240,6 +1252,45 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
/* f->type == NGX_HTTP_FASTCGI_STDOUT */
+#if (NGX_HTTP_CACHE)
+
+ if (f->large_stderr) {
+ u_char *start;
+ ssize_t len;
+
+ start = u->buffer.start + r->cache->header_start;
+
+ len = u->buffer.pos - start - 2 * sizeof(ngx_http_fastcgi_header_t);
+
+ /*
+ * A tail of large stderr output before HTTP header is placed
+ * in a cache file without a FastCGI record header.
+ * To workaround it we put a dummy FastCGI record header at the
+ * start of the stderr output or update r->cache_header_start,
+ * if there is no enough place for the record header.
+ */
+
+ if (len >= 0) {
+ fh = (ngx_http_fastcgi_header_t *) start;
+ fh->version = 1;
+ fh->type = NGX_HTTP_FASTCGI_STDERR;
+ fh->request_id_hi = 0;
+ fh->request_id_lo = 1;
+ fh->content_length_hi = (u_char) ((len >> 8) & 0xff);
+ fh->content_length_lo = (u_char) (len & 0xff);
+ fh->padding_length = 0;
+ fh->reserved = 0;
+
+ } else {
+ r->cache->header_start += u->buffer.pos - start
+ - sizeof(ngx_http_fastcgi_header_t);
+ }
+
+ f->large_stderr = 0;
+ }
+
+#endif
+
f->fastcgi_stdout = 1;
start = u->buffer.pos;
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index fd605276a..bd315eaa2 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -346,7 +346,7 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
h = (ngx_http_file_cache_header_t *) c->buf->pos;
- if (h->crc32 != c->crc32 || (size_t) h->header_start != c->header_start) {
+ if (h->crc32 != c->crc32) {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
"cache file \"%s\" has md5 collision", c->file.name.data);
return NGX_DECLINED;
@@ -358,6 +358,7 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
c->last_modified = h->last_modified;
c->date = h->date;
c->valid_msec = h->valid_msec;
+ c->header_start = h->header_start;
c->body_start = h->body_start;
r->cached = 1;