comparison 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
comparison
equal deleted inserted replaced
3459:958f8de0c45f 3460:bbea0b19b608
60 u_char *last; 60 u_char *last;
61 ngx_uint_t type; 61 ngx_uint_t type;
62 size_t length; 62 size_t length;
63 size_t padding; 63 size_t padding;
64 64
65 ngx_uint_t fastcgi_stdout; /* unsigned :1 */ 65 unsigned fastcgi_stdout:1;
66 unsigned large_stderr:1;
66 67
67 ngx_array_t *split_parts; 68 ngx_array_t *split_parts;
68 69
69 ngx_str_t script_name; 70 ngx_str_t script_name;
70 ngx_str_t path_info; 71 ngx_str_t path_info;
1079 return NGX_OK; 1080 return NGX_OK;
1080 } 1081 }
1081 1082
1082 f->state = ngx_http_fastcgi_st_version; 1083 f->state = ngx_http_fastcgi_st_version;
1083 f->fastcgi_stdout = 0; 1084 f->fastcgi_stdout = 0;
1085 f->large_stderr = 0;
1084 1086
1085 return NGX_OK; 1087 return NGX_OK;
1086 } 1088 }
1087 1089
1088 1090
1097 ngx_buf_t buf; 1099 ngx_buf_t buf;
1098 ngx_uint_t i; 1100 ngx_uint_t i;
1099 ngx_table_elt_t *h; 1101 ngx_table_elt_t *h;
1100 ngx_http_upstream_t *u; 1102 ngx_http_upstream_t *u;
1101 ngx_http_fastcgi_ctx_t *f; 1103 ngx_http_fastcgi_ctx_t *f;
1104 ngx_http_fastcgi_header_t *fh;
1102 ngx_http_upstream_header_t *hh; 1105 ngx_http_upstream_header_t *hh;
1103 ngx_http_fastcgi_loc_conf_t *flcf; 1106 ngx_http_fastcgi_loc_conf_t *flcf;
1104 ngx_http_fastcgi_split_part_t *part; 1107 ngx_http_fastcgi_split_part_t *part;
1105 ngx_http_upstream_main_conf_t *umcf; 1108 ngx_http_upstream_main_conf_t *umcf;
1106 1109
1221 /* 1224 /*
1222 * the special handling the large number 1225 * the special handling the large number
1223 * of the PHP warnings to not allocate memory 1226 * of the PHP warnings to not allocate memory
1224 */ 1227 */
1225 1228
1226 u->buffer.pos = u->buffer.start; 1229 #if (NGX_HTTP_CACHE)
1227 u->buffer.last = u->buffer.start; 1230 if (r->cache) {
1231 u->buffer.pos = u->buffer.start
1232 + r->cache->header_start;
1233 } else {
1234 u->buffer.pos = u->buffer.start;
1235 }
1236 #endif
1237
1238 u->buffer.last = u->buffer.pos;
1239 f->large_stderr = 1;
1228 } 1240 }
1229 1241
1230 return NGX_AGAIN; 1242 return NGX_AGAIN;
1231 } 1243 }
1232 1244
1237 continue; 1249 continue;
1238 } 1250 }
1239 1251
1240 1252
1241 /* f->type == NGX_HTTP_FASTCGI_STDOUT */ 1253 /* f->type == NGX_HTTP_FASTCGI_STDOUT */
1254
1255 #if (NGX_HTTP_CACHE)
1256
1257 if (f->large_stderr) {
1258 u_char *start;
1259 ssize_t len;
1260
1261 start = u->buffer.start + r->cache->header_start;
1262
1263 len = u->buffer.pos - start - 2 * sizeof(ngx_http_fastcgi_header_t);
1264
1265 /*
1266 * A tail of large stderr output before HTTP header is placed
1267 * in a cache file without a FastCGI record header.
1268 * To workaround it we put a dummy FastCGI record header at the
1269 * start of the stderr output or update r->cache_header_start,
1270 * if there is no enough place for the record header.
1271 */
1272
1273 if (len >= 0) {
1274 fh = (ngx_http_fastcgi_header_t *) start;
1275 fh->version = 1;
1276 fh->type = NGX_HTTP_FASTCGI_STDERR;
1277 fh->request_id_hi = 0;
1278 fh->request_id_lo = 1;
1279 fh->content_length_hi = (u_char) ((len >> 8) & 0xff);
1280 fh->content_length_lo = (u_char) (len & 0xff);
1281 fh->padding_length = 0;
1282 fh->reserved = 0;
1283
1284 } else {
1285 r->cache->header_start += u->buffer.pos - start
1286 - sizeof(ngx_http_fastcgi_header_t);
1287 }
1288
1289 f->large_stderr = 0;
1290 }
1291
1292 #endif
1242 1293
1243 f->fastcgi_stdout = 1; 1294 f->fastcgi_stdout = 1;
1244 1295
1245 start = u->buffer.pos; 1296 start = u->buffer.pos;
1246 1297