71 unsigned fastcgi_stdout:1;
72 unsigned large_stderr:1;
81 #define NGX_HTTP_FASTCGI_RESPONDER 1
83 #define NGX_HTTP_FASTCGI_KEEP_CONN 1
85 #define NGX_HTTP_FASTCGI_BEGIN_REQUEST 1
86 #define NGX_HTTP_FASTCGI_ABORT_REQUEST 2
87 #define NGX_HTTP_FASTCGI_END_REQUEST 3
88 #define NGX_HTTP_FASTCGI_PARAMS 4
89 #define NGX_HTTP_FASTCGI_STDIN 5
90 #define NGX_HTTP_FASTCGI_STDOUT 6
91 #define NGX_HTTP_FASTCGI_STDERR 7
92 #define NGX_HTTP_FASTCGI_DATA 8
138 static ngx_int_t ngx_http_fastcgi_input_filter_init(
void *data);
148 static void *ngx_http_fastcgi_create_loc_conf(
ngx_conf_t *cf);
149 static char *ngx_http_fastcgi_merge_loc_conf(
ngx_conf_t *cf,
150 void *parent,
void *child);
163 static char *ngx_http_fastcgi_split_path_info(
ngx_conf_t *cf,
174 static char *ngx_http_fastcgi_lowat_check(
ngx_conf_t *cf,
void *post,
179 { ngx_http_fastcgi_lowat_check };
202 ngx_http_fastcgi_pass,
216 ngx_http_fastcgi_split_path_info,
223 ngx_http_fastcgi_store,
268 &ngx_http_fastcgi_lowat_post },
323 ngx_http_fastcgi_cache,
330 ngx_http_fastcgi_cache_key,
340 &ngx_http_fastcgi_module },
375 &ngx_http_fastcgi_next_upstream_masks },
426 &ngx_http_fastcgi_next_upstream_masks },
475 ngx_http_fastcgi_add_variables,
484 ngx_http_fastcgi_create_loc_conf,
485 ngx_http_fastcgi_merge_loc_conf
491 &ngx_http_fastcgi_module_ctx,
492 ngx_http_fastcgi_commands,
531 ngx_http_fastcgi_script_name_variable, 0,
535 ngx_http_fastcgi_path_info_variable, 0,
542 static ngx_str_t ngx_http_fastcgi_hide_headers[] = {
555 static ngx_keyval_t ngx_http_fastcgi_cache_headers[] = {
583 "ngx_http_fastcgi_module does not support "
584 "subrequest in memory");
602 if (ngx_http_fastcgi_eval(r, flcf) !=
NGX_OK) {
615 u->create_key = ngx_http_fastcgi_create_key;
627 if (u->
pipe == NULL) {
666 "%s in upstream \"%V\"", url.
err, &url.
url);
724 u_char ch, *pos, *lowcase_key;
725 size_t size, len, key_len, val_len, padding,
727 ngx_uint_t i, n, next, hash, skip_empty, header_params;
753 while (*(uintptr_t *) le.
ip) {
756 key_len = lcode(&le);
759 skip_empty = lcode(&le);
761 for (val_len = 0; *(uintptr_t *) le.
ip; val_len += lcode(&le)) {
764 le.
ip +=
sizeof(uintptr_t);
766 if (skip_empty && val_len == 0) {
770 len += 1 + key_len + ((val_len > 127) ? 4 : 1) + val_len;
789 if (ignored == NULL) {
799 if (i >= part->
nelts) {
800 if (part->
next == NULL) {
810 if (allocated < header[i].key.
len) {
811 allocated = header[
i].
key.
len + 16;
813 if (lowcase_key == NULL) {
820 for (n = 0; n < header[
i].
key.
len; n++) {
823 if (ch >=
'A' && ch <=
'Z') {
826 }
else if (ch ==
'-') {
835 ignored[header_params++] = &header[
i];
839 n +=
sizeof(
"HTTP_") - 1;
842 n =
sizeof(
"HTTP_") - 1 + header[i].key.
len;
845 len += ((n > 127) ? 4 : 1) + ((header[
i].
value.
len > 127) ? 4 : 1)
853 "fastcgi request record is too big: %uz", len);
858 padding = 8 - len % 8;
859 padding = (padding == 8) ? 0 : padding;
884 ngx_http_fastcgi_request_start.
br.
flags =
914 while (*(uintptr_t *) le.
ip) {
917 key_len = (u_char) lcode(&le);
920 skip_empty = lcode(&le);
922 for (val_len = 0; *(uintptr_t *) le.
ip; val_len += lcode(&le)) {
925 le.
ip +=
sizeof(uintptr_t);
927 if (skip_empty && val_len == 0) {
930 while (*(uintptr_t *) e.
ip) {
934 e.
ip +=
sizeof(uintptr_t);
941 *e.
pos++ = (u_char) key_len;
944 *e.
pos++ = (u_char) (((val_len >> 24) & 0x7f) | 0x80);
945 *e.
pos++ = (u_char) ((val_len >> 16) & 0xff);
946 *e.
pos++ = (u_char) ((val_len >> 8) & 0xff);
947 *e.
pos++ = (u_char) (val_len & 0xff);
950 *e.
pos++ = (u_char) val_len;
953 while (*(uintptr_t *) e.
ip) {
957 e.
ip +=
sizeof(uintptr_t);
960 "fastcgi param: \"%*s: %*s\"",
961 key_len, e.
pos - (key_len + val_len),
962 val_len, e.
pos - val_len);
976 if (i >= part->
nelts) {
977 if (part->
next == NULL) {
986 for (n = 0; n < header_params; n++) {
987 if (&header[i] == ignored[n]) {
992 key_len =
sizeof(
"HTTP_") - 1 + header[i].key.
len;
994 *b->
last++ = (u_char) (((key_len >> 24) & 0x7f) | 0x80);
995 *b->
last++ = (u_char) ((key_len >> 16) & 0xff);
996 *b->
last++ = (u_char) ((key_len >> 8) & 0xff);
997 *b->
last++ = (u_char) (key_len & 0xff);
1000 *b->
last++ = (u_char) key_len;
1004 if (val_len > 127) {
1005 *b->
last++ = (u_char) (((val_len >> 24) & 0x7f) | 0x80);
1006 *b->
last++ = (u_char) ((val_len >> 16) & 0xff);
1007 *b->
last++ = (u_char) ((val_len >> 8) & 0xff);
1008 *b->
last++ = (u_char) (val_len & 0xff);
1011 *b->
last++ = (u_char) val_len;
1016 for (n = 0; n < header[
i].
key.
len; n++) {
1019 if (ch >=
'a' && ch <=
'z') {
1022 }
else if (ch ==
'-') {
1032 "fastcgi param: \"%*s: %*s\"",
1033 key_len, b->
last - (key_len + val_len),
1034 val_len, b->
last - val_len);
1067 #if (NGX_SUPPRESS_WARN)
1093 file_pos += 32 * 1024;
1116 padding = 8 - len % 8;
1117 padding = (padding == 8) ? 0 : padding;
1129 if (cl->
next == NULL) {
1152 if (cl->
next == NULL) {
1207 u_char *p, *msg, *start, *last,
1208 *part_start, *part_end;
1235 rc = ngx_http_fastcgi_process_record(r, f);
1252 "upstream sent unexpected FastCGI record: %d",
1260 "upstream prematurely closed FastCGI stdout");
1306 for (p = u->
buffer.
pos - 1; msg < p; p--) {
1307 if (*p !=
LF && *p !=
CR && *p !=
'.' && *p !=
' ') {
1315 "FastCGI sent in stderr: \"%*s\"", p - msg, msg);
1341 #if (NGX_HTTP_CACHE)
1368 #if (NGX_HTTP_CACHE)
1434 "http fastcgi parser: %d", rc);
1467 part[i].end - part[i].start);
1530 "http fastcgi header: \"%V: %V\"",
1547 "http fastcgi header done");
1556 "upstream sent invalid status \"%V\"",
1567 "302 Moved Temporarily");
1584 "upstream sent invalid header");
1610 "upstream split a header line in FastCGI records");
1625 part->
start = part_start;
1626 part->
end = part_end;
1638 ngx_http_fastcgi_input_filter_init(
void *data)
1680 rc = ngx_http_fastcgi_process_record(r, f);
1698 "http fastcgi closed stdout");
1706 "http fastcgi sent end request");
1779 for (m = f->
pos - 1; msg < m; m--) {
1780 if (*m !=
LF && *m !=
CR && *m !=
'.' && *m !=
' ') {
1786 "FastCGI sent in stderr: \"%*s\"",
1861 "input buf #%d %p", b->
num, b->
pos);
1901 "input buf %p %z", b->
pos, b->
last - b->
pos);
1925 for (p = f->
pos; p < f->last; p++) {
1930 "http fastcgi record byte: %02Xd", ch);
1937 "upstream sent unsupported FastCGI "
1938 "protocol version: %d", ch);
1953 "upstream sent invalid FastCGI "
1954 "record type: %d", ch);
1966 "upstream sent unexpected FastCGI "
1967 "request id high byte: %d", ch);
1976 "upstream sent unexpected FastCGI "
1977 "request id low byte: %d", ch);
1989 f->
length |= (size_t) ch;
2002 "http fastcgi record length: %z", f->
length);
2026 "abort http fastcgi request");
2036 "finalize http fastcgi request");
2043 ngx_http_fastcgi_add_variables(
ngx_conf_t *cf)
2047 for (v = ngx_http_fastcgi_vars; v->
name.
len; v++) {
2062 ngx_http_fastcgi_create_loc_conf(
ngx_conf_t *cf)
2110 #if (NGX_HTTP_CACHE)
2139 ngx_http_fastcgi_merge_loc_conf(
ngx_conf_t *cf,
void *parent,
void *child)
2192 "there must be at least 2 \"fastcgi_buffers\"");
2198 if (size < conf->upstream.bufs.size) {
2216 "\"fastcgi_busy_buffers_size\" must be equal to or greater than "
2217 "the maximum of the value of \"fastcgi_buffer_size\" and "
2218 "one of the \"fastcgi_buffers\"");
2227 "\"fastcgi_busy_buffers_size\" must be less than "
2228 "the size of all \"fastcgi_buffers\" minus one buffer");
2247 "\"fastcgi_temp_file_write_size\" must be equal to or greater "
2248 "than the maximum of the value of \"fastcgi_buffer_size\" and "
2249 "one of the \"fastcgi_buffers\"");
2270 "\"fastcgi_max_temp_file_size\" must be equal to zero to disable "
2271 "temporary files usage or must be equal to or greater than "
2272 "the maximum of the value of \"fastcgi_buffer_size\" and "
2273 "one of the \"fastcgi_buffers\"");
2297 &ngx_http_fastcgi_temp_path)
2303 #if (NGX_HTTP_CACHE)
2314 "\"fastcgi_cache\" zone \"%V\" is unknown",
2337 if (conf->
upstream.cache_methods == 0) {
2344 prev->
upstream.cache_bypass, NULL);
2351 "\"fastcgi_no_cache\" functionality has been changed in 0.8.46, "
2352 "now it should be used together with \"fastcgi_cache_bypass\"");
2358 if (conf->cache_key.value.data == NULL) {
2359 conf->cache_key = prev->cache_key;
2366 prev->
upstream.cache_lock_timeout, 5000);
2387 hash.
name =
"fastcgi_hide_headers_hash";
2390 &prev->
upstream, ngx_http_fastcgi_hide_headers, &hash)
2408 clcf->
handler = ngx_http_fastcgi_handler;
2413 if (conf->split_regex == NULL) {
2414 conf->split_regex = prev->split_regex;
2415 conf->split_name = prev->split_name;
2419 if (ngx_http_fastcgi_merge_params(cf, conf, prev) !=
NGX_OK) {
2428 ngx_http_fastcgi_merge_params(
ngx_conf_t *cf,
2436 #if (NGX_HTTP_CACHE)
2481 if (conf->
params == NULL) {
2500 #if (NGX_HTTP_CACHE)
2506 if (ngx_array_init(¶ms_merged, cf->
temp_pool, 4,
2513 for (i = 0; i < nsrc; i++) {
2523 h = ngx_http_fastcgi_cache_headers;
2527 src = params_merged.
elts;
2528 nsrc = params_merged.
nelts;
2530 for (i = 0; i < nsrc; i++) {
2550 src = params_merged.
elts;
2551 nsrc = params_merged.
nelts;
2556 for (i = 0; i < nsrc; i++) {
2558 if (src[i].key.
len >
sizeof(
"HTTP_") - 1
2569 hk->
value = (
void *) 1;
2571 if (src[i].value.len == 0) {
2596 + src[i].key.
len +
sizeof(uintptr_t) - 1)
2597 & ~(
sizeof(uintptr_t) - 1);
2628 *code = (uintptr_t) NULL;
2636 *code = (uintptr_t) NULL;
2644 *code = (uintptr_t) NULL;
2652 hash.
name =
"fastcgi_params_hash";
2670 f = ngx_http_fastcgi_split(r, flcf);
2691 if (v->
data == NULL) {
2711 f = ngx_http_fastcgi_split(r, flcf);
2733 int captures[(1 + 2) * 3];
2746 if (f->script_name.len) {
2750 if (flcf->split_regex == NULL) {
2751 f->script_name = r->
uri;
2758 f->script_name.len = captures[3] - captures[2];
2759 f->script_name.data = r->
uri.
data + captures[2];
2761 f->path_info.len = captures[5] - captures[4];
2762 f->path_info.data = r->
uri.
data + captures[4];
2768 f->script_name = r->
uri;
2774 n, &r->
uri, &flcf->split_name);
2790 f->script_name = r->
uri;
2810 return "is duplicate";
2815 clcf->
handler = ngx_http_fastcgi_handler;
2872 flcf->split_name = value[1];
2888 "pattern \"%V\" must have 2 captures", &value[1]);
2892 flcf->split_regex = rc.
regex;
2899 "\"%V\" requires PCRE library", &cmd->
name);
2917 return "is duplicate";
2927 #if (NGX_HTTP_CACHE)
2932 return "is incompatible with \"fastcgi_cache\"";
2963 #if (NGX_HTTP_CACHE)
2975 return "is duplicate";
2984 return "is incompatible with \"fastcgi_store\"";
2988 &ngx_http_fastcgi_module);
2989 if (flcf->
upstream.cache == NULL) {
3007 if (flcf->cache_key.value.data) {
3008 return "is duplicate";
3014 ccv.
value = &value[1];
3028 ngx_http_fastcgi_lowat_check(
ngx_conf_t *cf,
void *post,
void *data)
3035 "\"fastcgi_send_lowat\" must be less than %d "
3036 "(sysctl net.inet.tcp.sendspace)",
3042 #elif !(NGX_HAVE_SO_SNDLOWAT)
3046 "\"fastcgi_send_lowat\" is not supported, ignored");