Mercurial > hg > nginx-mail
comparison src/http/modules/ngx_http_fastcgi_module.c @ 665:0b460e61bdcd default tip
Merge with nginx 1.0.0.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 25 Apr 2011 04:22:17 +0400 |
parents | b9763778e212 |
children |
comparison
equal
deleted
inserted
replaced
572:06419a2298a9 | 665:0b460e61bdcd |
---|---|
20 ngx_array_t *params_source; | 20 ngx_array_t *params_source; |
21 ngx_array_t *catch_stderr; | 21 ngx_array_t *catch_stderr; |
22 | 22 |
23 ngx_array_t *fastcgi_lengths; | 23 ngx_array_t *fastcgi_lengths; |
24 ngx_array_t *fastcgi_values; | 24 ngx_array_t *fastcgi_values; |
25 | |
26 ngx_hash_t headers_hash; | |
27 ngx_uint_t header_params; | |
25 | 28 |
26 #if (NGX_HTTP_CACHE) | 29 #if (NGX_HTTP_CACHE) |
27 ngx_http_complex_value_t cache_key; | 30 ngx_http_complex_value_t cache_key; |
28 #endif | 31 #endif |
29 | 32 |
60 u_char *last; | 63 u_char *last; |
61 ngx_uint_t type; | 64 ngx_uint_t type; |
62 size_t length; | 65 size_t length; |
63 size_t padding; | 66 size_t padding; |
64 | 67 |
65 ngx_uint_t fastcgi_stdout; /* unsigned :1 */ | 68 unsigned fastcgi_stdout:1; |
69 unsigned large_stderr:1; | |
66 | 70 |
67 ngx_array_t *split_parts; | 71 ngx_array_t *split_parts; |
68 | 72 |
69 ngx_str_t script_name; | 73 ngx_str_t script_name; |
70 ngx_str_t path_info; | 74 ngx_str_t path_info; |
159 #endif | 163 #endif |
160 | 164 |
161 static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post, | 165 static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post, |
162 void *data); | 166 void *data); |
163 | 167 |
164 static char *ngx_http_fastcgi_upstream_max_fails_unsupported(ngx_conf_t *cf, | |
165 ngx_command_t *cmd, void *conf); | |
166 static char *ngx_http_fastcgi_upstream_fail_timeout_unsupported(ngx_conf_t *cf, | |
167 ngx_command_t *cmd, void *conf); | |
168 | |
169 | 168 |
170 static ngx_conf_post_t ngx_http_fastcgi_lowat_post = | 169 static ngx_conf_post_t ngx_http_fastcgi_lowat_post = |
171 { ngx_http_fastcgi_lowat_check }; | 170 { ngx_http_fastcgi_lowat_check }; |
172 | 171 |
173 | 172 |
182 { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, | 181 { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, |
183 { ngx_null_string, 0 } | 182 { ngx_null_string, 0 } |
184 }; | 183 }; |
185 | 184 |
186 | 185 |
187 static ngx_conf_bitmask_t ngx_http_fastcgi_ignore_headers_masks[] = { | |
188 { ngx_string("X-Accel-Redirect"), NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT }, | |
189 { ngx_string("X-Accel-Expires"), NGX_HTTP_UPSTREAM_IGN_XA_EXPIRES }, | |
190 { ngx_string("Expires"), NGX_HTTP_UPSTREAM_IGN_EXPIRES }, | |
191 { ngx_string("Cache-Control"), NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL }, | |
192 { ngx_null_string, 0 } | |
193 }; | |
194 | |
195 | |
196 ngx_module_t ngx_http_fastcgi_module; | 186 ngx_module_t ngx_http_fastcgi_module; |
197 | 187 |
198 | 188 |
199 static ngx_command_t ngx_http_fastcgi_commands[] = { | 189 static ngx_command_t ngx_http_fastcgi_commands[] = { |
200 | 190 |
238 ngx_conf_set_flag_slot, | 228 ngx_conf_set_flag_slot, |
239 NGX_HTTP_LOC_CONF_OFFSET, | 229 NGX_HTTP_LOC_CONF_OFFSET, |
240 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.ignore_client_abort), | 230 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.ignore_client_abort), |
241 NULL }, | 231 NULL }, |
242 | 232 |
233 { ngx_string("fastcgi_bind"), | |
234 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
235 ngx_http_upstream_bind_set_slot, | |
236 NGX_HTTP_LOC_CONF_OFFSET, | |
237 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.local), | |
238 NULL }, | |
239 | |
243 { ngx_string("fastcgi_connect_timeout"), | 240 { ngx_string("fastcgi_connect_timeout"), |
244 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | 241 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
245 ngx_conf_set_msec_slot, | 242 ngx_conf_set_msec_slot, |
246 NGX_HTTP_LOC_CONF_OFFSET, | 243 NGX_HTTP_LOC_CONF_OFFSET, |
247 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.connect_timeout), | 244 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.connect_timeout), |
311 NULL }, | 308 NULL }, |
312 | 309 |
313 #if (NGX_HTTP_CACHE) | 310 #if (NGX_HTTP_CACHE) |
314 | 311 |
315 { ngx_string("fastcgi_cache"), | 312 { ngx_string("fastcgi_cache"), |
316 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | 313 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
317 ngx_http_fastcgi_cache, | 314 ngx_http_fastcgi_cache, |
318 NGX_HTTP_LOC_CONF_OFFSET, | 315 NGX_HTTP_LOC_CONF_OFFSET, |
319 0, | 316 0, |
320 NULL }, | 317 NULL }, |
321 | 318 |
322 { ngx_string("fastcgi_cache_key"), | 319 { ngx_string("fastcgi_cache_key"), |
323 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | 320 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
324 ngx_http_fastcgi_cache_key, | 321 ngx_http_fastcgi_cache_key, |
325 NGX_HTTP_LOC_CONF_OFFSET, | 322 NGX_HTTP_LOC_CONF_OFFSET, |
326 0, | 323 0, |
327 NULL }, | 324 NULL }, |
328 | 325 |
331 ngx_http_file_cache_set_slot, | 328 ngx_http_file_cache_set_slot, |
332 0, | 329 0, |
333 0, | 330 0, |
334 &ngx_http_fastcgi_module }, | 331 &ngx_http_fastcgi_module }, |
335 | 332 |
333 { ngx_string("fastcgi_cache_bypass"), | |
334 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
335 ngx_http_set_predicate_slot, | |
336 NGX_HTTP_LOC_CONF_OFFSET, | |
337 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_bypass), | |
338 NULL }, | |
339 | |
340 { ngx_string("fastcgi_no_cache"), | |
341 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
342 ngx_http_set_predicate_slot, | |
343 NGX_HTTP_LOC_CONF_OFFSET, | |
344 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.no_cache), | |
345 NULL }, | |
346 | |
336 { ngx_string("fastcgi_cache_valid"), | 347 { ngx_string("fastcgi_cache_valid"), |
337 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | 348 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
338 ngx_http_file_cache_valid_set_slot, | 349 ngx_http_file_cache_valid_set_slot, |
339 NGX_HTTP_LOC_CONF_OFFSET, | 350 NGX_HTTP_LOC_CONF_OFFSET, |
340 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_valid), | 351 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_valid), |
389 ngx_conf_set_bitmask_slot, | 400 ngx_conf_set_bitmask_slot, |
390 NGX_HTTP_LOC_CONF_OFFSET, | 401 NGX_HTTP_LOC_CONF_OFFSET, |
391 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.next_upstream), | 402 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.next_upstream), |
392 &ngx_http_fastcgi_next_upstream_masks }, | 403 &ngx_http_fastcgi_next_upstream_masks }, |
393 | 404 |
394 { ngx_string("fastcgi_upstream_max_fails"), | |
395 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
396 ngx_http_fastcgi_upstream_max_fails_unsupported, | |
397 0, | |
398 0, | |
399 NULL }, | |
400 | |
401 { ngx_string("fastcgi_upstream_fail_timeout"), | |
402 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
403 ngx_http_fastcgi_upstream_fail_timeout_unsupported, | |
404 0, | |
405 0, | |
406 NULL }, | |
407 | |
408 { ngx_string("fastcgi_param"), | 405 { ngx_string("fastcgi_param"), |
409 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, | 406 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, |
410 ngx_conf_set_keyval_slot, | 407 ngx_conf_set_keyval_slot, |
411 NGX_HTTP_LOC_CONF_OFFSET, | 408 NGX_HTTP_LOC_CONF_OFFSET, |
412 offsetof(ngx_http_fastcgi_loc_conf_t, params_source), | 409 offsetof(ngx_http_fastcgi_loc_conf_t, params_source), |
413 NULL }, | 410 NULL }, |
414 | 411 |
415 { ngx_string("fastcgi_pass_header"), | 412 { ngx_string("fastcgi_pass_header"), |
416 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | 413 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
417 ngx_conf_set_str_array_slot, | 414 ngx_conf_set_str_array_slot, |
418 NGX_HTTP_LOC_CONF_OFFSET, | 415 NGX_HTTP_LOC_CONF_OFFSET, |
419 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.pass_headers), | 416 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.pass_headers), |
420 NULL }, | 417 NULL }, |
421 | 418 |
422 { ngx_string("fastcgi_hide_header"), | 419 { ngx_string("fastcgi_hide_header"), |
423 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | 420 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
424 ngx_conf_set_str_array_slot, | 421 ngx_conf_set_str_array_slot, |
425 NGX_HTTP_LOC_CONF_OFFSET, | 422 NGX_HTTP_LOC_CONF_OFFSET, |
426 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.hide_headers), | 423 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.hide_headers), |
427 NULL }, | 424 NULL }, |
428 | 425 |
429 { ngx_string("fastcgi_ignore_headers"), | 426 { ngx_string("fastcgi_ignore_headers"), |
430 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | 427 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
431 ngx_conf_set_bitmask_slot, | 428 ngx_conf_set_bitmask_slot, |
432 NGX_HTTP_LOC_CONF_OFFSET, | 429 NGX_HTTP_LOC_CONF_OFFSET, |
433 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.ignore_headers), | 430 offsetof(ngx_http_fastcgi_loc_conf_t, upstream.ignore_headers), |
434 &ngx_http_fastcgi_ignore_headers_masks }, | 431 &ngx_http_upstream_ignore_headers_masks }, |
435 | 432 |
436 { ngx_string("fastcgi_catch_stderr"), | 433 { ngx_string("fastcgi_catch_stderr"), |
437 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | 434 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
438 ngx_conf_set_str_array_slot, | 435 ngx_conf_set_str_array_slot, |
439 NGX_HTTP_LOC_CONF_OFFSET, | 436 NGX_HTTP_LOC_CONF_OFFSET, |
521 ngx_string("X-Accel-Charset"), | 518 ngx_string("X-Accel-Charset"), |
522 ngx_null_string | 519 ngx_null_string |
523 }; | 520 }; |
524 | 521 |
525 | 522 |
523 #if (NGX_HTTP_CACHE) | |
524 | |
525 static ngx_keyval_t ngx_http_fastcgi_cache_headers[] = { | |
526 { ngx_string("HTTP_IF_MODIFIED_SINCE"), ngx_string("") }, | |
527 { ngx_string("HTTP_IF_UNMODIFIED_SINCE"), ngx_string("") }, | |
528 { ngx_string("HTTP_IF_NONE_MATCH"), ngx_string("") }, | |
529 { ngx_string("HTTP_IF_MATCH"), ngx_string("") }, | |
530 { ngx_string("HTTP_RANGE"), ngx_string("") }, | |
531 { ngx_string("HTTP_IF_RANGE"), ngx_string("") }, | |
532 { ngx_null_string, ngx_null_string } | |
533 }; | |
534 | |
535 #endif | |
536 | |
537 | |
526 static ngx_path_init_t ngx_http_fastcgi_temp_path = { | 538 static ngx_path_init_t ngx_http_fastcgi_temp_path = { |
527 ngx_string(NGX_HTTP_FASTCGI_TEMP_PATH), { 1, 2, 0 } | 539 ngx_string(NGX_HTTP_FASTCGI_TEMP_PATH), { 1, 2, 0 } |
528 }; | 540 }; |
529 | 541 |
530 | 542 |
562 } | 574 } |
563 } | 575 } |
564 | 576 |
565 u = r->upstream; | 577 u = r->upstream; |
566 | 578 |
567 u->schema.len = sizeof("fastcgi://") - 1; | 579 ngx_str_set(&u->schema, "fastcgi://"); |
568 u->schema.data = (u_char *) "fastcgi://"; | |
569 | |
570 u->output.tag = (ngx_buf_tag_t) &ngx_http_fastcgi_module; | 580 u->output.tag = (ngx_buf_tag_t) &ngx_http_fastcgi_module; |
571 | 581 |
572 u->conf = &flcf->upstream; | 582 u->conf = &flcf->upstream; |
573 | 583 |
574 #if (NGX_HTTP_CACHE) | 584 #if (NGX_HTTP_CACHE) |
601 | 611 |
602 | 612 |
603 static ngx_int_t | 613 static ngx_int_t |
604 ngx_http_fastcgi_eval(ngx_http_request_t *r, ngx_http_fastcgi_loc_conf_t *flcf) | 614 ngx_http_fastcgi_eval(ngx_http_request_t *r, ngx_http_fastcgi_loc_conf_t *flcf) |
605 { | 615 { |
606 ngx_url_t u; | 616 ngx_url_t url; |
607 | 617 ngx_http_upstream_t *u; |
608 ngx_memzero(&u, sizeof(ngx_url_t)); | 618 |
609 | 619 ngx_memzero(&url, sizeof(ngx_url_t)); |
610 if (ngx_http_script_run(r, &u.url, flcf->fastcgi_lengths->elts, 0, | 620 |
621 if (ngx_http_script_run(r, &url.url, flcf->fastcgi_lengths->elts, 0, | |
611 flcf->fastcgi_values->elts) | 622 flcf->fastcgi_values->elts) |
612 == NULL) | 623 == NULL) |
613 { | 624 { |
614 return NGX_ERROR; | 625 return NGX_ERROR; |
615 } | 626 } |
616 | 627 |
617 u.no_resolve = 1; | 628 url.no_resolve = 1; |
618 | 629 |
619 if (ngx_parse_url(r->pool, &u) != NGX_OK) { | 630 if (ngx_parse_url(r->pool, &url) != NGX_OK) { |
620 if (u.err) { | 631 if (url.err) { |
621 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 632 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
622 "%s in upstream \"%V\"", u.err, &u.url); | 633 "%s in upstream \"%V\"", url.err, &url.url); |
623 } | 634 } |
624 | 635 |
625 return NGX_ERROR; | 636 return NGX_ERROR; |
626 } | 637 } |
627 | 638 |
628 if (u.no_port) { | 639 u = r->upstream; |
629 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 640 |
630 "no port in upstream \"%V\"", &u.url); | 641 u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t)); |
642 if (u->resolved == NULL) { | |
631 return NGX_ERROR; | 643 return NGX_ERROR; |
632 } | 644 } |
633 | 645 |
634 r->upstream->resolved = ngx_pcalloc(r->pool, | 646 if (url.addrs && url.addrs[0].sockaddr) { |
635 sizeof(ngx_http_upstream_resolved_t)); | 647 u->resolved->sockaddr = url.addrs[0].sockaddr; |
636 if (r->upstream->resolved == NULL) { | 648 u->resolved->socklen = url.addrs[0].socklen; |
637 return NGX_ERROR; | 649 u->resolved->naddrs = 1; |
638 } | 650 u->resolved->host = url.addrs[0].name; |
639 | |
640 if (u.addrs && u.addrs[0].sockaddr) { | |
641 r->upstream->resolved->sockaddr = u.addrs[0].sockaddr; | |
642 r->upstream->resolved->socklen = u.addrs[0].socklen; | |
643 r->upstream->resolved->naddrs = 1; | |
644 r->upstream->resolved->host = u.addrs[0].name; | |
645 | 651 |
646 } else { | 652 } else { |
647 r->upstream->resolved->host = u.host; | 653 u->resolved->host = url.host; |
648 r->upstream->resolved->port = u.port; | 654 u->resolved->port = url.port; |
655 u->resolved->no_port = url.no_port; | |
649 } | 656 } |
650 | 657 |
651 return NGX_OK; | 658 return NGX_OK; |
652 } | 659 } |
653 | 660 |
679 | 686 |
680 static ngx_int_t | 687 static ngx_int_t |
681 ngx_http_fastcgi_create_request(ngx_http_request_t *r) | 688 ngx_http_fastcgi_create_request(ngx_http_request_t *r) |
682 { | 689 { |
683 off_t file_pos; | 690 off_t file_pos; |
684 u_char ch, *pos; | 691 u_char ch, *pos, *lowcase_key; |
685 size_t size, len, key_len, val_len, padding; | 692 size_t size, len, key_len, val_len, padding, |
686 ngx_uint_t i, n, next; | 693 allocated; |
694 ngx_uint_t i, n, next, hash, header_params; | |
687 ngx_buf_t *b; | 695 ngx_buf_t *b; |
688 ngx_chain_t *cl, *body; | 696 ngx_chain_t *cl, *body; |
689 ngx_list_part_t *part; | 697 ngx_list_part_t *part; |
690 ngx_table_elt_t *header; | 698 ngx_table_elt_t *header, **ignored; |
691 ngx_http_script_code_pt code; | 699 ngx_http_script_code_pt code; |
692 ngx_http_script_engine_t e, le; | 700 ngx_http_script_engine_t e, le; |
693 ngx_http_fastcgi_header_t *h; | 701 ngx_http_fastcgi_header_t *h; |
694 ngx_http_fastcgi_loc_conf_t *flcf; | 702 ngx_http_fastcgi_loc_conf_t *flcf; |
695 ngx_http_script_len_code_pt lcode; | 703 ngx_http_script_len_code_pt lcode; |
696 | 704 |
697 len = 0; | 705 len = 0; |
706 header_params = 0; | |
707 ignored = NULL; | |
698 | 708 |
699 flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module); | 709 flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module); |
700 | 710 |
701 if (flcf->params_len) { | 711 if (flcf->params_len) { |
702 ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); | 712 ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); |
720 len += 1 + key_len + ((val_len > 127) ? 4 : 1) + val_len; | 730 len += 1 + key_len + ((val_len > 127) ? 4 : 1) + val_len; |
721 } | 731 } |
722 } | 732 } |
723 | 733 |
724 if (flcf->upstream.pass_request_headers) { | 734 if (flcf->upstream.pass_request_headers) { |
735 | |
736 allocated = 0; | |
737 lowcase_key = NULL; | |
738 | |
739 if (flcf->header_params) { | |
740 ignored = ngx_palloc(r->pool, flcf->header_params * sizeof(void *)); | |
741 if (ignored == NULL) { | |
742 return NGX_ERROR; | |
743 } | |
744 } | |
725 | 745 |
726 part = &r->headers_in.headers.part; | 746 part = &r->headers_in.headers.part; |
727 header = part->elts; | 747 header = part->elts; |
728 | 748 |
729 for (i = 0; /* void */; i++) { | 749 for (i = 0; /* void */; i++) { |
736 part = part->next; | 756 part = part->next; |
737 header = part->elts; | 757 header = part->elts; |
738 i = 0; | 758 i = 0; |
739 } | 759 } |
740 | 760 |
741 len += ((sizeof("HTTP_") - 1 + header[i].key.len > 127) ? 4 : 1) | 761 if (flcf->header_params) { |
742 + ((header[i].value.len > 127) ? 4 : 1) | 762 if (allocated < header[i].key.len) { |
743 + sizeof("HTTP_") - 1 + header[i].key.len + header[i].value.len; | 763 allocated = header[i].key.len + 16; |
764 lowcase_key = ngx_pnalloc(r->pool, allocated); | |
765 if (lowcase_key == NULL) { | |
766 return NGX_ERROR; | |
767 } | |
768 } | |
769 | |
770 hash = 0; | |
771 | |
772 for (n = 0; n < header[i].key.len; n++) { | |
773 ch = header[i].key.data[n]; | |
774 | |
775 if (ch >= 'A' && ch <= 'Z') { | |
776 ch |= 0x20; | |
777 | |
778 } else if (ch == '-') { | |
779 ch = '_'; | |
780 } | |
781 | |
782 hash = ngx_hash(hash, ch); | |
783 lowcase_key[n] = ch; | |
784 } | |
785 | |
786 if (ngx_hash_find(&flcf->headers_hash, hash, lowcase_key, n)) { | |
787 ignored[header_params++] = &header[i]; | |
788 continue; | |
789 } | |
790 | |
791 n += sizeof("HTTP_") - 1; | |
792 | |
793 } else { | |
794 n = sizeof("HTTP_") - 1 + header[i].key.len; | |
795 } | |
796 | |
797 len += ((n > 127) ? 4 : 1) + ((header[i].value.len > 127) ? 4 : 1) | |
798 + n + header[i].value.len; | |
744 } | 799 } |
745 } | 800 } |
746 | 801 |
747 | 802 |
748 if (len > 65535) { | 803 if (len > 65535) { |
858 part = part->next; | 913 part = part->next; |
859 header = part->elts; | 914 header = part->elts; |
860 i = 0; | 915 i = 0; |
861 } | 916 } |
862 | 917 |
863 len = sizeof("HTTP_") - 1 + header[i].key.len; | 918 for (n = 0; n < header_params; n++) { |
864 if (len > 127) { | 919 if (&header[i] == ignored[n]) { |
865 *b->last++ = (u_char) (((len >> 24) & 0x7f) | 0x80); | 920 goto next; |
866 *b->last++ = (u_char) ((len >> 16) & 0xff); | 921 } |
867 *b->last++ = (u_char) ((len >> 8) & 0xff); | 922 } |
868 *b->last++ = (u_char) (len & 0xff); | 923 |
924 key_len = sizeof("HTTP_") - 1 + header[i].key.len; | |
925 if (key_len > 127) { | |
926 *b->last++ = (u_char) (((key_len >> 24) & 0x7f) | 0x80); | |
927 *b->last++ = (u_char) ((key_len >> 16) & 0xff); | |
928 *b->last++ = (u_char) ((key_len >> 8) & 0xff); | |
929 *b->last++ = (u_char) (key_len & 0xff); | |
869 | 930 |
870 } else { | 931 } else { |
871 *b->last++ = (u_char) len; | 932 *b->last++ = (u_char) key_len; |
872 } | 933 } |
873 | 934 |
874 len = header[i].value.len; | 935 val_len = header[i].value.len; |
875 if (len > 127) { | 936 if (val_len > 127) { |
876 *b->last++ = (u_char) (((len >> 24) & 0x7f) | 0x80); | 937 *b->last++ = (u_char) (((val_len >> 24) & 0x7f) | 0x80); |
877 *b->last++ = (u_char) ((len >> 16) & 0xff); | 938 *b->last++ = (u_char) ((val_len >> 16) & 0xff); |
878 *b->last++ = (u_char) ((len >> 8) & 0xff); | 939 *b->last++ = (u_char) ((val_len >> 8) & 0xff); |
879 *b->last++ = (u_char) (len & 0xff); | 940 *b->last++ = (u_char) (val_len & 0xff); |
880 | 941 |
881 } else { | 942 } else { |
882 *b->last++ = (u_char) len; | 943 *b->last++ = (u_char) val_len; |
883 } | 944 } |
884 | 945 |
885 b->last = ngx_cpymem(b->last, "HTTP_", sizeof("HTTP_") - 1); | 946 b->last = ngx_cpymem(b->last, "HTTP_", sizeof("HTTP_") - 1); |
886 | 947 |
887 for (n = 0; n < header[i].key.len; n++) { | 948 for (n = 0; n < header[i].key.len; n++) { |
895 } | 956 } |
896 | 957 |
897 *b->last++ = ch; | 958 *b->last++ = ch; |
898 } | 959 } |
899 | 960 |
900 b->last = ngx_copy(b->last, header[i].value.data, | 961 b->last = ngx_copy(b->last, header[i].value.data, val_len); |
901 header[i].value.len); | 962 |
963 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
964 "fastcgi param: \"%*s: %*s\"", | |
965 key_len, b->last - (key_len + val_len), | |
966 val_len, b->last - val_len); | |
967 next: | |
968 | |
969 continue; | |
902 } | 970 } |
903 } | 971 } |
904 | 972 |
905 | 973 |
906 if (padding) { | 974 if (padding) { |
1055 return NGX_OK; | 1123 return NGX_OK; |
1056 } | 1124 } |
1057 | 1125 |
1058 f->state = ngx_http_fastcgi_st_version; | 1126 f->state = ngx_http_fastcgi_st_version; |
1059 f->fastcgi_stdout = 0; | 1127 f->fastcgi_stdout = 0; |
1128 f->large_stderr = 0; | |
1060 | 1129 |
1061 return NGX_OK; | 1130 return NGX_OK; |
1062 } | 1131 } |
1063 | 1132 |
1064 | 1133 |
1197 /* | 1266 /* |
1198 * the special handling the large number | 1267 * the special handling the large number |
1199 * of the PHP warnings to not allocate memory | 1268 * of the PHP warnings to not allocate memory |
1200 */ | 1269 */ |
1201 | 1270 |
1271 #if (NGX_HTTP_CACHE) | |
1272 if (r->cache) { | |
1273 u->buffer.pos = u->buffer.start | |
1274 + r->cache->header_start; | |
1275 } else { | |
1276 u->buffer.pos = u->buffer.start; | |
1277 } | |
1278 #else | |
1202 u->buffer.pos = u->buffer.start; | 1279 u->buffer.pos = u->buffer.start; |
1203 u->buffer.last = u->buffer.start; | 1280 #endif |
1281 u->buffer.last = u->buffer.pos; | |
1282 f->large_stderr = 1; | |
1204 } | 1283 } |
1205 | 1284 |
1206 return NGX_AGAIN; | 1285 return NGX_AGAIN; |
1207 } | 1286 } |
1208 | 1287 |
1213 continue; | 1292 continue; |
1214 } | 1293 } |
1215 | 1294 |
1216 | 1295 |
1217 /* f->type == NGX_HTTP_FASTCGI_STDOUT */ | 1296 /* f->type == NGX_HTTP_FASTCGI_STDOUT */ |
1297 | |
1298 #if (NGX_HTTP_CACHE) | |
1299 | |
1300 if (f->large_stderr && r->cache) { | |
1301 u_char *start; | |
1302 ssize_t len; | |
1303 ngx_http_fastcgi_header_t *fh; | |
1304 | |
1305 start = u->buffer.start + r->cache->header_start; | |
1306 | |
1307 len = u->buffer.pos - start - 2 * sizeof(ngx_http_fastcgi_header_t); | |
1308 | |
1309 /* | |
1310 * A tail of large stderr output before HTTP header is placed | |
1311 * in a cache file without a FastCGI record header. | |
1312 * To workaround it we put a dummy FastCGI record header at the | |
1313 * start of the stderr output or update r->cache_header_start, | |
1314 * if there is no enough place for the record header. | |
1315 */ | |
1316 | |
1317 if (len >= 0) { | |
1318 fh = (ngx_http_fastcgi_header_t *) start; | |
1319 fh->version = 1; | |
1320 fh->type = NGX_HTTP_FASTCGI_STDERR; | |
1321 fh->request_id_hi = 0; | |
1322 fh->request_id_lo = 1; | |
1323 fh->content_length_hi = (u_char) ((len >> 8) & 0xff); | |
1324 fh->content_length_lo = (u_char) (len & 0xff); | |
1325 fh->padding_length = 0; | |
1326 fh->reserved = 0; | |
1327 | |
1328 } else { | |
1329 r->cache->header_start += u->buffer.pos - start | |
1330 - sizeof(ngx_http_fastcgi_header_t); | |
1331 } | |
1332 | |
1333 f->large_stderr = 0; | |
1334 } | |
1335 | |
1336 #endif | |
1218 | 1337 |
1219 f->fastcgi_stdout = 1; | 1338 f->fastcgi_stdout = 1; |
1220 | 1339 |
1221 start = u->buffer.pos; | 1340 start = u->buffer.pos; |
1222 | 1341 |
1372 u->headers_in.status_n = status; | 1491 u->headers_in.status_n = status; |
1373 u->headers_in.status_line = *status_line; | 1492 u->headers_in.status_line = *status_line; |
1374 | 1493 |
1375 } else if (u->headers_in.location) { | 1494 } else if (u->headers_in.location) { |
1376 u->headers_in.status_n = 302; | 1495 u->headers_in.status_n = 302; |
1377 u->headers_in.status_line.len = | 1496 ngx_str_set(&u->headers_in.status_line, |
1378 sizeof("302 Moved Temporarily") - 1; | 1497 "302 Moved Temporarily"); |
1379 u->headers_in.status_line.data = | |
1380 (u_char *) "302 Moved Temporarily"; | |
1381 | 1498 |
1382 } else { | 1499 } else { |
1383 u->headers_in.status_n = 200; | 1500 u->headers_in.status_n = 200; |
1384 u->headers_in.status_line.len = sizeof("200 OK") - 1; | 1501 ngx_str_set(&u->headers_in.status_line, "200 OK"); |
1385 u->headers_in.status_line.data = (u_char *) "200 OK"; | |
1386 } | 1502 } |
1387 | 1503 |
1388 if (u->state) { | 1504 if (u->state) { |
1389 u->state->status = u->headers_in.status_n; | 1505 u->state->status = u->headers_in.status_n; |
1390 } | 1506 } |
1845 * conf->upstream.uri = { 0, NULL }; | 1961 * conf->upstream.uri = { 0, NULL }; |
1846 * conf->upstream.location = NULL; | 1962 * conf->upstream.location = NULL; |
1847 * conf->upstream.store_lengths = NULL; | 1963 * conf->upstream.store_lengths = NULL; |
1848 * conf->upstream.store_values = NULL; | 1964 * conf->upstream.store_values = NULL; |
1849 * | 1965 * |
1850 * conf->index.len = 0; | 1966 * conf->index.len = { 0, NULL }; |
1851 * conf->index.data = NULL; | |
1852 */ | 1967 */ |
1853 | 1968 |
1854 conf->upstream.store = NGX_CONF_UNSET; | 1969 conf->upstream.store = NGX_CONF_UNSET; |
1855 conf->upstream.store_access = NGX_CONF_UNSET_UINT; | 1970 conf->upstream.store_access = NGX_CONF_UNSET_UINT; |
1856 conf->upstream.buffering = NGX_CONF_UNSET; | 1971 conf->upstream.buffering = NGX_CONF_UNSET; |
1871 conf->upstream.pass_request_body = NGX_CONF_UNSET; | 1986 conf->upstream.pass_request_body = NGX_CONF_UNSET; |
1872 | 1987 |
1873 #if (NGX_HTTP_CACHE) | 1988 #if (NGX_HTTP_CACHE) |
1874 conf->upstream.cache = NGX_CONF_UNSET_PTR; | 1989 conf->upstream.cache = NGX_CONF_UNSET_PTR; |
1875 conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; | 1990 conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; |
1991 conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR; | |
1992 conf->upstream.no_cache = NGX_CONF_UNSET_PTR; | |
1876 conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; | 1993 conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; |
1877 #endif | 1994 #endif |
1878 | 1995 |
1879 conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; | 1996 conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; |
1880 conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; | 1997 conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; |
1898 | 2015 |
1899 u_char *p; | 2016 u_char *p; |
1900 size_t size; | 2017 size_t size; |
1901 uintptr_t *code; | 2018 uintptr_t *code; |
1902 ngx_uint_t i; | 2019 ngx_uint_t i; |
2020 ngx_array_t headers_names; | |
1903 ngx_keyval_t *src; | 2021 ngx_keyval_t *src; |
2022 ngx_hash_key_t *hk; | |
1904 ngx_hash_init_t hash; | 2023 ngx_hash_init_t hash; |
2024 ngx_http_core_loc_conf_t *clcf; | |
1905 ngx_http_script_compile_t sc; | 2025 ngx_http_script_compile_t sc; |
1906 ngx_http_script_copy_code_t *copy; | 2026 ngx_http_script_copy_code_t *copy; |
1907 | 2027 |
1908 if (conf->upstream.store != 0) { | 2028 if (conf->upstream.store != 0) { |
1909 ngx_conf_merge_value(conf->upstream.store, | 2029 ngx_conf_merge_value(conf->upstream.store, |
2091 conf->upstream.cache_methods = prev->upstream.cache_methods; | 2211 conf->upstream.cache_methods = prev->upstream.cache_methods; |
2092 } | 2212 } |
2093 | 2213 |
2094 conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD; | 2214 conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD; |
2095 | 2215 |
2216 ngx_conf_merge_ptr_value(conf->upstream.cache_bypass, | |
2217 prev->upstream.cache_bypass, NULL); | |
2218 | |
2219 ngx_conf_merge_ptr_value(conf->upstream.no_cache, | |
2220 prev->upstream.no_cache, NULL); | |
2221 | |
2222 if (conf->upstream.no_cache && conf->upstream.cache_bypass == NULL) { | |
2223 ngx_log_error(NGX_LOG_WARN, cf->log, 0, | |
2224 "\"fastcgi_no_cache\" functionality has been changed in 0.8.46, " | |
2225 "now it should be used together with \"fastcgi_cache_bypass\""); | |
2226 } | |
2227 | |
2096 ngx_conf_merge_ptr_value(conf->upstream.cache_valid, | 2228 ngx_conf_merge_ptr_value(conf->upstream.cache_valid, |
2097 prev->upstream.cache_valid, NULL); | 2229 prev->upstream.cache_valid, NULL); |
2098 | 2230 |
2099 if (conf->cache_key.value.data == NULL) { | 2231 if (conf->cache_key.value.data == NULL) { |
2100 conf->cache_key = prev->cache_key; | 2232 conf->cache_key = prev->cache_key; |
2118 hash.max_size = 512; | 2250 hash.max_size = 512; |
2119 hash.bucket_size = ngx_align(64, ngx_cacheline_size); | 2251 hash.bucket_size = ngx_align(64, ngx_cacheline_size); |
2120 hash.name = "fastcgi_hide_headers_hash"; | 2252 hash.name = "fastcgi_hide_headers_hash"; |
2121 | 2253 |
2122 if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream, | 2254 if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream, |
2123 &prev->upstream, | 2255 &prev->upstream, ngx_http_fastcgi_hide_headers, &hash) |
2124 ngx_http_fastcgi_hide_headers, | |
2125 &hash) | |
2126 != NGX_OK) | 2256 != NGX_OK) |
2127 { | 2257 { |
2128 return NGX_CONF_ERROR; | 2258 return NGX_CONF_ERROR; |
2129 } | 2259 } |
2130 | 2260 |
2133 } | 2263 } |
2134 | 2264 |
2135 if (conf->fastcgi_lengths == NULL) { | 2265 if (conf->fastcgi_lengths == NULL) { |
2136 conf->fastcgi_lengths = prev->fastcgi_lengths; | 2266 conf->fastcgi_lengths = prev->fastcgi_lengths; |
2137 conf->fastcgi_values = prev->fastcgi_values; | 2267 conf->fastcgi_values = prev->fastcgi_values; |
2268 } | |
2269 | |
2270 if (conf->upstream.upstream || conf->fastcgi_lengths) { | |
2271 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); | |
2272 if (clcf->handler == NULL && clcf->lmt_excpt) { | |
2273 clcf->handler = ngx_http_fastcgi_handler; | |
2274 } | |
2138 } | 2275 } |
2139 | 2276 |
2140 #if (NGX_PCRE) | 2277 #if (NGX_PCRE) |
2141 if (conf->split_regex == NULL) { | 2278 if (conf->split_regex == NULL) { |
2142 conf->split_regex = prev->split_regex; | 2279 conf->split_regex = prev->split_regex; |
2147 if (conf->params_source == NULL) { | 2284 if (conf->params_source == NULL) { |
2148 conf->flushes = prev->flushes; | 2285 conf->flushes = prev->flushes; |
2149 conf->params_len = prev->params_len; | 2286 conf->params_len = prev->params_len; |
2150 conf->params = prev->params; | 2287 conf->params = prev->params; |
2151 conf->params_source = prev->params_source; | 2288 conf->params_source = prev->params_source; |
2289 conf->headers_hash = prev->headers_hash; | |
2290 | |
2291 #if (NGX_HTTP_CACHE) | |
2292 | |
2293 if (conf->params_source == NULL) { | |
2294 | |
2295 if ((conf->upstream.cache == NULL) | |
2296 == (prev->upstream.cache == NULL)) | |
2297 { | |
2298 return NGX_CONF_OK; | |
2299 } | |
2300 | |
2301 /* 6 is a number of ngx_http_fastcgi_cache_headers entries */ | |
2302 conf->params_source = ngx_array_create(cf->pool, 6, | |
2303 sizeof(ngx_keyval_t)); | |
2304 if (conf->params_source == NULL) { | |
2305 return NGX_CONF_ERROR; | |
2306 } | |
2307 } | |
2308 #else | |
2152 | 2309 |
2153 if (conf->params_source == NULL) { | 2310 if (conf->params_source == NULL) { |
2154 return NGX_CONF_OK; | 2311 return NGX_CONF_OK; |
2155 } | 2312 } |
2313 | |
2314 #endif | |
2156 } | 2315 } |
2157 | 2316 |
2158 conf->params_len = ngx_array_create(cf->pool, 64, 1); | 2317 conf->params_len = ngx_array_create(cf->pool, 64, 1); |
2159 if (conf->params_len == NULL) { | 2318 if (conf->params_len == NULL) { |
2160 return NGX_CONF_ERROR; | 2319 return NGX_CONF_ERROR; |
2163 conf->params = ngx_array_create(cf->pool, 512, 1); | 2322 conf->params = ngx_array_create(cf->pool, 512, 1); |
2164 if (conf->params == NULL) { | 2323 if (conf->params == NULL) { |
2165 return NGX_CONF_ERROR; | 2324 return NGX_CONF_ERROR; |
2166 } | 2325 } |
2167 | 2326 |
2327 if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) | |
2328 != NGX_OK) | |
2329 { | |
2330 return NGX_CONF_ERROR; | |
2331 } | |
2332 | |
2168 src = conf->params_source->elts; | 2333 src = conf->params_source->elts; |
2334 | |
2335 #if (NGX_HTTP_CACHE) | |
2336 | |
2337 if (conf->upstream.cache) { | |
2338 ngx_keyval_t *h, *s; | |
2339 | |
2340 for (h = ngx_http_fastcgi_cache_headers; h->key.len; h++) { | |
2341 | |
2342 for (i = 0; i < conf->params_source->nelts; i++) { | |
2343 if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) { | |
2344 goto next; | |
2345 } | |
2346 } | |
2347 | |
2348 s = ngx_array_push(conf->params_source); | |
2349 if (s == NULL) { | |
2350 return NGX_CONF_ERROR; | |
2351 } | |
2352 | |
2353 *s = *h; | |
2354 | |
2355 src = conf->params_source->elts; | |
2356 | |
2357 next: | |
2358 | |
2359 h++; | |
2360 } | |
2361 } | |
2362 | |
2363 #endif | |
2364 | |
2169 for (i = 0; i < conf->params_source->nelts; i++) { | 2365 for (i = 0; i < conf->params_source->nelts; i++) { |
2170 | 2366 |
2171 if (ngx_http_script_variables_count(&src[i].value) == 0) { | 2367 if (src[i].key.len > sizeof("HTTP_") - 1 |
2172 copy = ngx_array_push_n(conf->params_len, | 2368 && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0) |
2173 sizeof(ngx_http_script_copy_code_t)); | 2369 { |
2174 if (copy == NULL) { | 2370 hk = ngx_array_push(&headers_names); |
2371 if (hk == NULL) { | |
2175 return NGX_CONF_ERROR; | 2372 return NGX_CONF_ERROR; |
2176 } | 2373 } |
2177 | 2374 |
2178 copy->code = (ngx_http_script_code_pt) | 2375 hk->key.len = src[i].key.len - 5; |
2179 ngx_http_script_copy_len_code; | 2376 hk->key.data = src[i].key.data + 5; |
2180 copy->len = src[i].key.len; | 2377 hk->key_hash = ngx_hash_key_lc(hk->key.data, hk->key.len); |
2181 | 2378 hk->value = (void *) 1; |
2182 | 2379 |
2183 copy = ngx_array_push_n(conf->params_len, | 2380 if (src[i].value.len == 0) { |
2184 sizeof(ngx_http_script_copy_code_t)); | 2381 continue; |
2185 if (copy == NULL) { | 2382 } |
2186 return NGX_CONF_ERROR; | 2383 } |
2187 } | 2384 |
2188 | 2385 copy = ngx_array_push_n(conf->params_len, |
2189 copy->code = (ngx_http_script_code_pt) | 2386 sizeof(ngx_http_script_copy_code_t)); |
2190 ngx_http_script_copy_len_code; | 2387 if (copy == NULL) { |
2191 copy->len = src[i].value.len; | 2388 return NGX_CONF_ERROR; |
2192 | 2389 } |
2193 | 2390 |
2194 size = (sizeof(ngx_http_script_copy_code_t) | 2391 copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code; |
2195 + src[i].key.len + src[i].value.len | 2392 copy->len = src[i].key.len; |
2196 + sizeof(uintptr_t) - 1) | 2393 |
2197 & ~(sizeof(uintptr_t) - 1); | 2394 |
2198 | 2395 size = (sizeof(ngx_http_script_copy_code_t) |
2199 copy = ngx_array_push_n(conf->params, size); | 2396 + src[i].key.len + sizeof(uintptr_t) - 1) |
2200 if (copy == NULL) { | 2397 & ~(sizeof(uintptr_t) - 1); |
2201 return NGX_CONF_ERROR; | 2398 |
2202 } | 2399 copy = ngx_array_push_n(conf->params, size); |
2203 | 2400 if (copy == NULL) { |
2204 copy->code = ngx_http_script_copy_code; | 2401 return NGX_CONF_ERROR; |
2205 copy->len = src[i].key.len + src[i].value.len; | 2402 } |
2206 | 2403 |
2207 p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); | 2404 copy->code = ngx_http_script_copy_code; |
2208 | 2405 copy->len = src[i].key.len; |
2209 p = ngx_cpymem(p, src[i].key.data, src[i].key.len); | 2406 |
2210 ngx_memcpy(p, src[i].value.data, src[i].value.len); | 2407 p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); |
2211 | 2408 ngx_memcpy(p, src[i].key.data, src[i].key.len); |
2212 } else { | 2409 |
2213 copy = ngx_array_push_n(conf->params_len, | 2410 |
2214 sizeof(ngx_http_script_copy_code_t)); | 2411 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
2215 if (copy == NULL) { | 2412 |
2216 return NGX_CONF_ERROR; | 2413 sc.cf = cf; |
2217 } | 2414 sc.source = &src[i].value; |
2218 | 2415 sc.flushes = &conf->flushes; |
2219 copy->code = (ngx_http_script_code_pt) | 2416 sc.lengths = &conf->params_len; |
2220 ngx_http_script_copy_len_code; | 2417 sc.values = &conf->params; |
2221 copy->len = src[i].key.len; | 2418 |
2222 | 2419 if (ngx_http_script_compile(&sc) != NGX_OK) { |
2223 | 2420 return NGX_CONF_ERROR; |
2224 size = (sizeof(ngx_http_script_copy_code_t) | |
2225 + src[i].key.len + sizeof(uintptr_t) - 1) | |
2226 & ~(sizeof(uintptr_t) - 1); | |
2227 | |
2228 copy = ngx_array_push_n(conf->params, size); | |
2229 if (copy == NULL) { | |
2230 return NGX_CONF_ERROR; | |
2231 } | |
2232 | |
2233 copy->code = ngx_http_script_copy_code; | |
2234 copy->len = src[i].key.len; | |
2235 | |
2236 p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); | |
2237 ngx_memcpy(p, src[i].key.data, src[i].key.len); | |
2238 | |
2239 | |
2240 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); | |
2241 | |
2242 sc.cf = cf; | |
2243 sc.source = &src[i].value; | |
2244 sc.flushes = &conf->flushes; | |
2245 sc.lengths = &conf->params_len; | |
2246 sc.values = &conf->params; | |
2247 | |
2248 if (ngx_http_script_compile(&sc) != NGX_OK) { | |
2249 return NGX_CONF_ERROR; | |
2250 } | |
2251 } | 2421 } |
2252 | 2422 |
2253 code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t)); | 2423 code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t)); |
2254 if (code == NULL) { | 2424 if (code == NULL) { |
2255 return NGX_CONF_ERROR; | 2425 return NGX_CONF_ERROR; |
2270 if (code == NULL) { | 2440 if (code == NULL) { |
2271 return NGX_CONF_ERROR; | 2441 return NGX_CONF_ERROR; |
2272 } | 2442 } |
2273 | 2443 |
2274 *code = (uintptr_t) NULL; | 2444 *code = (uintptr_t) NULL; |
2445 | |
2446 | |
2447 conf->header_params = headers_names.nelts; | |
2448 | |
2449 hash.hash = &conf->headers_hash; | |
2450 hash.key = ngx_hash_key_lc; | |
2451 hash.max_size = 512; | |
2452 hash.bucket_size = 64; | |
2453 hash.name = "fastcgi_params_hash"; | |
2454 hash.pool = cf->pool; | |
2455 hash.temp_pool = NULL; | |
2456 | |
2457 if (ngx_hash_init(&hash, headers_names.elts, headers_names.nelts) != NGX_OK) | |
2458 { | |
2459 return NGX_CONF_ERROR; | |
2460 } | |
2275 | 2461 |
2276 return NGX_CONF_OK; | 2462 return NGX_CONF_OK; |
2277 } | 2463 } |
2278 | 2464 |
2279 | 2465 |
2372 return f; | 2558 return f; |
2373 } | 2559 } |
2374 | 2560 |
2375 n = ngx_regex_exec(flcf->split_regex, &r->uri, captures, (1 + 2) * 3); | 2561 n = ngx_regex_exec(flcf->split_regex, &r->uri, captures, (1 + 2) * 3); |
2376 | 2562 |
2563 if (n >= 0) { /* match */ | |
2564 f->script_name.len = captures[3] - captures[2]; | |
2565 f->script_name.data = r->uri.data + captures[2]; | |
2566 | |
2567 f->path_info.len = captures[5] - captures[4]; | |
2568 f->path_info.data = r->uri.data + captures[4]; | |
2569 | |
2570 return f; | |
2571 } | |
2572 | |
2377 if (n == NGX_REGEX_NO_MATCHED) { | 2573 if (n == NGX_REGEX_NO_MATCHED) { |
2378 f->script_name = r->uri; | 2574 f->script_name = r->uri; |
2379 return f; | 2575 return f; |
2380 } | 2576 } |
2381 | 2577 |
2382 if (n < 0) { | 2578 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, |
2383 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | 2579 ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"", |
2384 ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"", | 2580 n, &r->uri, &flcf->split_name); |
2385 n, &r->uri, &flcf->split_name); | 2581 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 | 2582 |
2399 #else | 2583 #else |
2400 | 2584 |
2401 f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); | 2585 f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); |
2402 | 2586 |
2483 ngx_http_fastcgi_split_path_info(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 2667 ngx_http_fastcgi_split_path_info(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
2484 { | 2668 { |
2485 #if (NGX_PCRE) | 2669 #if (NGX_PCRE) |
2486 ngx_http_fastcgi_loc_conf_t *flcf = conf; | 2670 ngx_http_fastcgi_loc_conf_t *flcf = conf; |
2487 | 2671 |
2488 ngx_int_t n; | 2672 ngx_str_t *value; |
2489 ngx_str_t *value, err; | 2673 ngx_regex_compile_t rc; |
2490 u_char errstr[NGX_MAX_CONF_ERRSTR]; | 2674 u_char errstr[NGX_MAX_CONF_ERRSTR]; |
2491 | 2675 |
2492 value = cf->args->elts; | 2676 value = cf->args->elts; |
2493 | 2677 |
2494 flcf->split_name = value[1]; | 2678 flcf->split_name = value[1]; |
2495 | 2679 |
2496 err.len = NGX_MAX_CONF_ERRSTR; | 2680 ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); |
2497 err.data = errstr; | 2681 |
2498 | 2682 rc.pattern = value[1]; |
2499 flcf->split_regex = ngx_regex_compile(&value[1], 0, cf->pool, &err); | 2683 rc.pool = cf->pool; |
2500 | 2684 rc.err.len = NGX_MAX_CONF_ERRSTR; |
2501 if (flcf->split_regex == NULL) { | 2685 rc.err.data = errstr; |
2502 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | 2686 |
2687 if (ngx_regex_compile(&rc) != NGX_OK) { | |
2688 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err); | |
2503 return NGX_CONF_ERROR; | 2689 return NGX_CONF_ERROR; |
2504 } | 2690 } |
2505 | 2691 |
2506 n = ngx_regex_capture_count(flcf->split_regex); | 2692 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, | 2693 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
2517 "pattern \"%V\" must have 2 captures", &value[1]); | 2694 "pattern \"%V\" must have 2 captures", &value[1]); |
2518 return NGX_CONF_ERROR; | 2695 return NGX_CONF_ERROR; |
2519 } | 2696 } |
2697 | |
2698 flcf->split_regex = rc.regex; | |
2520 | 2699 |
2521 return NGX_CONF_OK; | 2700 return NGX_CONF_OK; |
2522 | 2701 |
2523 #else | 2702 #else |
2524 | 2703 |
2676 | 2855 |
2677 #endif | 2856 #endif |
2678 | 2857 |
2679 return NGX_CONF_OK; | 2858 return NGX_CONF_OK; |
2680 } | 2859 } |
2681 | |
2682 | |
2683 static char * | |
2684 ngx_http_fastcgi_upstream_max_fails_unsupported(ngx_conf_t *cf, | |
2685 ngx_command_t *cmd, void *conf) | |
2686 { | |
2687 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
2688 "\"fastcgi_upstream_max_fails\" is not supported, " | |
2689 "use the \"max_fails\" parameter of the \"server\" directive ", | |
2690 "inside the \"upstream\" block"); | |
2691 | |
2692 return NGX_CONF_ERROR; | |
2693 } | |
2694 | |
2695 | |
2696 static char * | |
2697 ngx_http_fastcgi_upstream_fail_timeout_unsupported(ngx_conf_t *cf, | |
2698 ngx_command_t *cmd, void *conf) | |
2699 { | |
2700 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
2701 "\"fastcgi_upstream_fail_timeout\" is not supported, " | |
2702 "use the \"fail_timeout\" parameter of the \"server\" directive ", | |
2703 "inside the \"upstream\" block"); | |
2704 | |
2705 return NGX_CONF_ERROR; | |
2706 } |