mirror of
https://github.com/nginx/nginx.git
synced 2025-06-07 17:52:38 +08:00
fix cached FastCGI response with large stderr output before header
This commit is contained in:
parent
750a65ef84
commit
593dec8b35
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user