Mercurial > hg > nginx-ranges
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 |