Klaus Demo nginx / 593dec8
fix cached FastCGI response with large stderr output before header Igor Sysoev 10 years ago
2 changed file(s) with 56 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
6161 size_t length;
6262 size_t padding;
6363
64 ngx_uint_t fastcgi_stdout; /* unsigned :1 */
64 unsigned fastcgi_stdout:1;
65 unsigned large_stderr:1;
6566
6667 ngx_array_t *split_parts;
6768
10801081
10811082 f->state = ngx_http_fastcgi_st_version;
10821083 f->fastcgi_stdout = 0;
1084 f->large_stderr = 0;
10831085
10841086 return NGX_OK;
10851087 }
10981100 ngx_table_elt_t *h;
10991101 ngx_http_upstream_t *u;
11001102 ngx_http_fastcgi_ctx_t *f;
1103 ngx_http_fastcgi_header_t *fh;
11011104 ngx_http_upstream_header_t *hh;
11021105 ngx_http_fastcgi_loc_conf_t *flcf;
11031106 ngx_http_fastcgi_split_part_t *part;
12221225 * of the PHP warnings to not allocate memory
12231226 */
12241227
1225 u->buffer.pos = u->buffer.start;
1226 u->buffer.last = u->buffer.start;
1228 #if (NGX_HTTP_CACHE)
1229 if (r->cache) {
1230 u->buffer.pos = u->buffer.start
1231 + r->cache->header_start;
1232 } else {
1233 u->buffer.pos = u->buffer.start;
1234 }
1235 #endif
1236
1237 u->buffer.last = u->buffer.pos;
1238 f->large_stderr = 1;
12271239 }
12281240
12291241 return NGX_AGAIN;
12381250
12391251
12401252 /* f->type == NGX_HTTP_FASTCGI_STDOUT */
1253
1254 #if (NGX_HTTP_CACHE)
1255
1256 if (f->large_stderr) {
1257 u_char *start;
1258 ssize_t len;
1259
1260 start = u->buffer.start + r->cache->header_start;
1261
1262 len = u->buffer.pos - start - 2 * sizeof(ngx_http_fastcgi_header_t);
1263
1264 /*
1265 * A tail of large stderr output before HTTP header is placed
1266 * in a cache file without a FastCGI record header.
1267 * To workaround it we put a dummy FastCGI record header at the
1268 * start of the stderr output or update r->cache_header_start,
1269 * if there is no enough place for the record header.
1270 */
1271
1272 if (len >= 0) {
1273 fh = (ngx_http_fastcgi_header_t *) start;
1274 fh->version = 1;
1275 fh->type = NGX_HTTP_FASTCGI_STDERR;
1276 fh->request_id_hi = 0;
1277 fh->request_id_lo = 1;
1278 fh->content_length_hi = (u_char) ((len >> 8) & 0xff);
1279 fh->content_length_lo = (u_char) (len & 0xff);
1280 fh->padding_length = 0;
1281 fh->reserved = 0;
1282
1283 } else {
1284 r->cache->header_start += u->buffer.pos - start
1285 - sizeof(ngx_http_fastcgi_header_t);
1286 }
1287
1288 f->large_stderr = 0;
1289 }
1290
1291 #endif
12411292
12421293 f->fastcgi_stdout = 1;
12431294
345345
346346 h = (ngx_http_file_cache_header_t *) c->buf->pos;
347347
348 if (h->crc32 != c->crc32 || (size_t) h->header_start != c->header_start) {
348 if (h->crc32 != c->crc32) {
349349 ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
350350 "cache file \"%s\" has md5 collision", c->file.name.data);
351351 return NGX_DECLINED;
357357 c->last_modified = h->last_modified;
358358 c->date = h->date;
359359 c->valid_msec = h->valid_msec;
360 c->header_start = h->header_start;
360361 c->body_start = h->body_start;
361362
362363 r->cached = 1;