Mercurial > hg > nginx-quic
diff src/http/modules/ngx_http_fastcgi_module.c @ 3460:bbea0b19b608
fix cached FastCGI response with large stderr output before header
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 03 Mar 2010 10:43:38 +0000 |
parents | ac9c0380337d |
children | 08a66ba99191 |
line wrap: on
line diff
--- 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 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 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 * 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 /* 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;