comparison src/http/modules/ngx_http_fastcgi_module.c @ 578:f3a9e57d2e17

Merge with current.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 11 Mar 2010 21:27:17 +0300
parents da3c99095432
children be4f34123024
comparison
equal deleted inserted replaced
539:5f4de8cf0d9d 578:f3a9e57d2e17
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;
238 ngx_conf_set_flag_slot, 239 ngx_conf_set_flag_slot,
239 NGX_HTTP_LOC_CONF_OFFSET, 240 NGX_HTTP_LOC_CONF_OFFSET,
240 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.ignore_client_abort), 241 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.ignore_client_abort),
241 NULL }, 242 NULL },
242 243
244 { ngx_string("fastcgi_bind"),
245 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
246 ngx_http_upstream_bind_set_slot,
247 NGX_HTTP_LOC_CONF_OFFSET,
248 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.local),
249 NULL },
250
243 { ngx_string("fastcgi_connect_timeout"), 251 { ngx_string("fastcgi_connect_timeout"),
244 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 252 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
245 ngx_conf_set_msec_slot, 253 ngx_conf_set_msec_slot,
246 NGX_HTTP_LOC_CONF_OFFSET, 254 NGX_HTTP_LOC_CONF_OFFSET,
247 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.connect_timeout), 255 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.connect_timeout),
519 ngx_string("X-Accel-Limit-Rate"), 527 ngx_string("X-Accel-Limit-Rate"),
520 ngx_string("X-Accel-Buffering"), 528 ngx_string("X-Accel-Buffering"),
521 ngx_string("X-Accel-Charset"), 529 ngx_string("X-Accel-Charset"),
522 ngx_null_string 530 ngx_null_string
523 }; 531 };
532
533
534 #if (NGX_HTTP_CACHE)
535
536 static ngx_str_t ngx_http_fastcgi_hide_cache_headers[] = {
537 ngx_string("Status"),
538 ngx_string("X-Accel-Expires"),
539 ngx_string("X-Accel-Redirect"),
540 ngx_string("X-Accel-Limit-Rate"),
541 ngx_string("X-Accel-Buffering"),
542 ngx_string("X-Accel-Charset"),
543 ngx_string("Set-Cookie"),
544 ngx_string("P3P"),
545 ngx_null_string
546 };
547
548 #endif
524 549
525 550
526 static ngx_path_init_t ngx_http_fastcgi_temp_path = { 551 static ngx_path_init_t ngx_http_fastcgi_temp_path = {
527 ngx_string(NGX_HTTP_FASTCGI_TEMP_PATH), { 1, 2, 0 } 552 ngx_string(NGX_HTTP_FASTCGI_TEMP_PATH), { 1, 2, 0 }
528 }; 553 };
1055 return NGX_OK; 1080 return NGX_OK;
1056 } 1081 }
1057 1082
1058 f->state = ngx_http_fastcgi_st_version; 1083 f->state = ngx_http_fastcgi_st_version;
1059 f->fastcgi_stdout = 0; 1084 f->fastcgi_stdout = 0;
1085 f->large_stderr = 0;
1060 1086
1061 return NGX_OK; 1087 return NGX_OK;
1062 } 1088 }
1063 1089
1064 1090
1073 ngx_buf_t buf; 1099 ngx_buf_t buf;
1074 ngx_uint_t i; 1100 ngx_uint_t i;
1075 ngx_table_elt_t *h; 1101 ngx_table_elt_t *h;
1076 ngx_http_upstream_t *u; 1102 ngx_http_upstream_t *u;
1077 ngx_http_fastcgi_ctx_t *f; 1103 ngx_http_fastcgi_ctx_t *f;
1104 ngx_http_fastcgi_header_t *fh;
1078 ngx_http_upstream_header_t *hh; 1105 ngx_http_upstream_header_t *hh;
1079 ngx_http_fastcgi_loc_conf_t *flcf; 1106 ngx_http_fastcgi_loc_conf_t *flcf;
1080 ngx_http_fastcgi_split_part_t *part; 1107 ngx_http_fastcgi_split_part_t *part;
1081 ngx_http_upstream_main_conf_t *umcf; 1108 ngx_http_upstream_main_conf_t *umcf;
1082 1109
1197 /* 1224 /*
1198 * the special handling the large number 1225 * the special handling the large number
1199 * of the PHP warnings to not allocate memory 1226 * of the PHP warnings to not allocate memory
1200 */ 1227 */
1201 1228
1202 u->buffer.pos = u->buffer.start; 1229 #if (NGX_HTTP_CACHE)
1203 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;
1204 } 1240 }
1205 1241
1206 return NGX_AGAIN; 1242 return NGX_AGAIN;
1207 } 1243 }
1208 1244
1213 continue; 1249 continue;
1214 } 1250 }
1215 1251
1216 1252
1217 /* 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
1218 1293
1219 f->fastcgi_stdout = 1; 1294 f->fastcgi_stdout = 1;
1220 1295
1221 start = u->buffer.pos; 1296 start = u->buffer.pos;
1222 1297
1897 ngx_http_fastcgi_loc_conf_t *conf = child; 1972 ngx_http_fastcgi_loc_conf_t *conf = child;
1898 1973
1899 u_char *p; 1974 u_char *p;
1900 size_t size; 1975 size_t size;
1901 uintptr_t *code; 1976 uintptr_t *code;
1977 ngx_str_t *h;
1902 ngx_uint_t i; 1978 ngx_uint_t i;
1903 ngx_keyval_t *src; 1979 ngx_keyval_t *src;
1904 ngx_hash_init_t hash; 1980 ngx_hash_init_t hash;
1905 ngx_http_script_compile_t sc; 1981 ngx_http_script_compile_t sc;
1906 ngx_http_script_copy_code_t *copy; 1982 ngx_http_script_copy_code_t *copy;
2117 2193
2118 hash.max_size = 512; 2194 hash.max_size = 512;
2119 hash.bucket_size = ngx_align(64, ngx_cacheline_size); 2195 hash.bucket_size = ngx_align(64, ngx_cacheline_size);
2120 hash.name = "fastcgi_hide_headers_hash"; 2196 hash.name = "fastcgi_hide_headers_hash";
2121 2197
2198 #if (NGX_HTTP_CACHE)
2199
2200 h = conf->upstream.cache ? ngx_http_fastcgi_hide_cache_headers:
2201 ngx_http_fastcgi_hide_headers;
2202 #else
2203
2204 h = ngx_http_fastcgi_hide_headers;
2205
2206 #endif
2207
2122 if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream, 2208 if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
2123 &prev->upstream, 2209 &prev->upstream, h, &hash)
2124 ngx_http_fastcgi_hide_headers,
2125 &hash)
2126 != NGX_OK) 2210 != NGX_OK)
2127 { 2211 {
2128 return NGX_CONF_ERROR; 2212 return NGX_CONF_ERROR;
2129 } 2213 }
2130 2214
2372 return f; 2456 return f;
2373 } 2457 }
2374 2458
2375 n = ngx_regex_exec(flcf->split_regex, &r->uri, captures, (1 + 2) * 3); 2459 n = ngx_regex_exec(flcf->split_regex, &r->uri, captures, (1 + 2) * 3);
2376 2460
2461 if (n >= 0) { /* match */
2462 f->script_name.len = captures[3] - captures[2];
2463 f->script_name.data = r->uri.data;
2464
2465 f->path_info.len = captures[5] - captures[4];
2466 f->path_info.data = r->uri.data + f->script_name.len;
2467
2468 return f;
2469 }
2470
2377 if (n == NGX_REGEX_NO_MATCHED) { 2471 if (n == NGX_REGEX_NO_MATCHED) {
2378 f->script_name = r->uri; 2472 f->script_name = r->uri;
2379 return f; 2473 return f;
2380 } 2474 }
2381 2475
2382 if (n < 0) { 2476 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
2383 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, 2477 ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
2384 ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"", 2478 n, &r->uri, &flcf->split_name);
2385 n, &r->uri, &flcf->split_name); 2479 return NULL;
2386 return NULL;
2387 }
2388
2389 /* match */
2390
2391 f->script_name.len = captures[3] - captures[2];
2392 f->script_name.data = r->uri.data;
2393
2394 f->path_info.len = captures[5] - captures[4];
2395 f->path_info.data = r->uri.data + f->script_name.len;
2396
2397 return f;
2398 2480
2399 #else 2481 #else
2400 2482
2401 f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); 2483 f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
2402 2484
2483 ngx_http_fastcgi_split_path_info(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 2565 ngx_http_fastcgi_split_path_info(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2484 { 2566 {
2485 #if (NGX_PCRE) 2567 #if (NGX_PCRE)
2486 ngx_http_fastcgi_loc_conf_t *flcf = conf; 2568 ngx_http_fastcgi_loc_conf_t *flcf = conf;
2487 2569
2488 ngx_int_t n; 2570 ngx_str_t *value;
2489 ngx_str_t *value, err; 2571 ngx_regex_compile_t rc;
2490 u_char errstr[NGX_MAX_CONF_ERRSTR]; 2572 u_char errstr[NGX_MAX_CONF_ERRSTR];
2491 2573
2492 value = cf->args->elts; 2574 value = cf->args->elts;
2493 2575
2494 flcf->split_name = value[1]; 2576 flcf->split_name = value[1];
2495 2577
2496 err.len = NGX_MAX_CONF_ERRSTR; 2578 ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
2497 err.data = errstr; 2579
2498 2580 rc.pattern = value[1];
2499 flcf->split_regex = ngx_regex_compile(&value[1], 0, cf->pool, &err); 2581 rc.pool = cf->pool;
2500 2582 rc.err.len = NGX_MAX_CONF_ERRSTR;
2501 if (flcf->split_regex == NULL) { 2583 rc.err.data = errstr;
2502 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); 2584
2585 if (ngx_regex_compile(&rc) != NGX_OK) {
2586 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
2503 return NGX_CONF_ERROR; 2587 return NGX_CONF_ERROR;
2504 } 2588 }
2505 2589
2506 n = ngx_regex_capture_count(flcf->split_regex); 2590 if (rc.captures != 2) {
2507
2508 if (n < 0) {
2509 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2510 ngx_regex_capture_count_n " failed for "
2511 "pattern \"%V\"", &value[1]);
2512 return NGX_CONF_ERROR;
2513 }
2514
2515 if (n != 2) {
2516 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 2591 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2517 "pattern \"%V\" must have 2 captures", &value[1]); 2592 "pattern \"%V\" must have 2 captures", &value[1]);
2518 return NGX_CONF_ERROR; 2593 return NGX_CONF_ERROR;
2519 } 2594 }
2595
2596 flcf->split_regex = rc.regex;
2520 2597
2521 return NGX_CONF_OK; 2598 return NGX_CONF_OK;
2522 2599
2523 #else 2600 #else
2524 2601