~ubuntu-branches/ubuntu/hardy/nginx/hardy-backports

« back to all changes in this revision

Viewing changes to src/http/modules/ngx_http_fastcgi_module.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Casadevall
  • Date: 2008-12-21 22:25:43 UTC
  • mfrom: (11.1.10 jaunty)
  • Revision ID: james.westby@ubuntu.com-20081221222543-44yu0i65ni6evses
Tags: 0.6.34-2ubuntu1~hardy1
* Source-level backport from jaunty to hardy of nginx (LP: #260640)
* debian/control:
  - Lowered lsb dependency to 3.2-4ubuntu1
* debian/init.d:
  - Removed usage of status_of_proc() to suite lower lsb

Show diffs side-by-side

added added

removed removed

Lines of Context:
135
135
    ngx_command_t *cmd, void *conf);
136
136
 
137
137
 
138
 
static ngx_http_fastcgi_request_start_t  ngx_http_fastcgi_request_start = {
139
 
    { 1,                                               /* version */
140
 
      NGX_HTTP_FASTCGI_BEGIN_REQUEST,                  /* type */
141
 
      0,                                               /* request_id_hi */
142
 
      1,                                               /* request_id_lo */
143
 
      0,                                               /* content_length_hi */
144
 
      sizeof(ngx_http_fastcgi_begin_request_t),        /* content_length_lo */
145
 
      0,                                               /* padding_length */
146
 
      0 },                                             /* reserved */
147
 
 
148
 
    { 0,                                               /* role_hi */
149
 
      NGX_HTTP_FASTCGI_RESPONDER,                      /* role_lo */
150
 
      0, /* NGX_HTTP_FASTCGI_KEEP_CONN */              /* flags */
151
 
      { 0, 0, 0, 0, 0 } },                             /* reserved[5] */
152
 
 
153
 
    { 1,                                               /* version */
154
 
      NGX_HTTP_FASTCGI_PARAMS,                         /* type */
155
 
      0,                                               /* request_id_hi */
156
 
      1 },                                             /* request_id_lo */
157
 
 
158
 
};
159
 
 
160
 
 
161
 
static ngx_str_t  ngx_http_fastcgi_script_name =
162
 
    ngx_string("fastcgi_script_name");
163
 
 
164
 
 
165
138
static ngx_conf_post_t  ngx_http_fastcgi_lowat_post =
166
139
    { ngx_http_fastcgi_lowat_check };
167
140
 
412
385
};
413
386
 
414
387
 
 
388
static ngx_http_fastcgi_request_start_t  ngx_http_fastcgi_request_start = {
 
389
    { 1,                                               /* version */
 
390
      NGX_HTTP_FASTCGI_BEGIN_REQUEST,                  /* type */
 
391
      0,                                               /* request_id_hi */
 
392
      1,                                               /* request_id_lo */
 
393
      0,                                               /* content_length_hi */
 
394
      sizeof(ngx_http_fastcgi_begin_request_t),        /* content_length_lo */
 
395
      0,                                               /* padding_length */
 
396
      0 },                                             /* reserved */
 
397
 
 
398
    { 0,                                               /* role_hi */
 
399
      NGX_HTTP_FASTCGI_RESPONDER,                      /* role_lo */
 
400
      0, /* NGX_HTTP_FASTCGI_KEEP_CONN */              /* flags */
 
401
      { 0, 0, 0, 0, 0 } },                             /* reserved[5] */
 
402
 
 
403
    { 1,                                               /* version */
 
404
      NGX_HTTP_FASTCGI_PARAMS,                         /* type */
 
405
      0,                                               /* request_id_hi */
 
406
      1 },                                             /* request_id_lo */
 
407
 
 
408
};
 
409
 
 
410
 
 
411
static ngx_str_t  ngx_http_fastcgi_script_name =
 
412
    ngx_string("fastcgi_script_name");
 
413
 
 
414
 
415
415
static ngx_str_t  ngx_http_fastcgi_hide_headers[] = {
416
416
    ngx_string("Status"),
417
417
    ngx_string("X-Accel-Expires"),
418
418
    ngx_string("X-Accel-Redirect"),
419
419
    ngx_string("X-Accel-Limit-Rate"),
420
 
    ngx_string("X-Accel-Buffer"),
 
420
    ngx_string("X-Accel-Buffering"),
 
421
    ngx_string("X-Accel-Charset"),
421
422
    ngx_null_string
422
423
};
423
424
 
432
433
    if (r->subrequest_in_memory) {
433
434
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
434
435
                      "ngx_http_fastcgi_module does not support "
435
 
                      "subrequest in memeory");
 
436
                      "subrequest in memory");
436
437
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
437
438
    }
438
439
 
443
444
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
444
445
    }
445
446
 
 
447
    u->schema = flcf->upstream.schema;
 
448
 
446
449
    u->peer.log = r->connection->log;
447
450
    u->peer.log_error = NGX_ERROR_ERR;
448
451
#if (NGX_THREADS)
505
508
    if (flcf->params_len) {
506
509
        ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
507
510
 
508
 
        ngx_http_script_flush_no_cachable_variables(r, flcf->flushes);
 
511
        ngx_http_script_flush_no_cacheable_variables(r, flcf->flushes);
509
512
        le.flushed = 1;
510
513
 
511
514
        le.ip = flcf->params_len->elts;
551
554
 
552
555
    if (len > 65535) {
553
556
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
554
 
                      "fastcgi: the request record is too big");
 
557
                      "fastcgi request record is too big: %uz", len);
555
558
        return NGX_ERROR;
556
559
    }
557
560
 
636
639
                code((ngx_http_script_engine_t *) &e);
637
640
            }
638
641
            e.ip += sizeof(uintptr_t);
 
642
 
 
643
            ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
 
644
                           "fastcgi param: \"%*s: %*s\"",
 
645
                           key_len, e.pos - (key_len + val_len),
 
646
                           val_len, e.pos - val_len);
639
647
        }
640
648
 
641
649
        b->last = e.pos;
885
893
    if (f == NULL) {
886
894
        f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
887
895
        if (f == NULL) {
888
 
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
896
            return NGX_ERROR;
889
897
        }
890
898
 
891
899
        ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
993
1001
 
994
1002
                    for (i = 0; i < flcf->catch_stderr->nelts; i++) {
995
1003
                        if (ngx_strstr(line.data, pattern[i].data)) {
996
 
                            return NGX_HTTP_BAD_GATEWAY;
 
1004
                            return NGX_HTTP_UPSTREAM_INVALID_HEADER;
997
1005
                        }
998
1006
                    }
999
1007
                }
1061
1069
 
1062
1070
                h = ngx_list_push(&u->headers_in.headers);
1063
1071
                if (h == NULL) {
1064
 
                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
1072
                    return NGX_ERROR;
1065
1073
                }
1066
1074
 
1067
1075
                if (f->split_parts && f->split_parts->nelts) {
1075
1083
 
1076
1084
                    p = ngx_palloc(r->pool, size);
1077
1085
                    if (p == NULL) {
1078
 
                        return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
1086
                        return NGX_ERROR;
1079
1087
                    }
1080
1088
 
1081
1089
                    buf.pos = p;
1103
1111
 
1104
1112
                    h->lowcase_key = ngx_palloc(r->pool, h->key.len);
1105
1113
                    if (h->lowcase_key == NULL) {
1106
 
                        return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
1114
                        return NGX_ERROR;
1107
1115
                    }
1108
1116
 
1109
1117
                } else {
1115
1123
                                             h->key.len + 1 + h->value.len + 1
1116
1124
                                             + h->key.len);
1117
1125
                    if (h->key.data == NULL) {
1118
 
                        return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
1126
                        return NGX_ERROR;
1119
1127
                    }
1120
1128
 
1121
1129
                    h->value.data = h->key.data + h->key.len + 1;
1143
1151
                                   h->lowcase_key, h->key.len);
1144
1152
 
1145
1153
                if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
1146
 
                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
1154
                    return NGX_ERROR;
1147
1155
                }
1148
1156
 
1149
1157
                ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1172
1180
                    status = ngx_atoi(status_line->data, 3);
1173
1181
 
1174
1182
                    if (status == NGX_ERROR) {
1175
 
                        return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
1183
                        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
 
1184
                                      "upstream sent invalid status \"%V\"",
 
1185
                                      status_line);
 
1186
                        return NGX_HTTP_UPSTREAM_INVALID_HEADER;
1176
1187
                    }
1177
1188
 
1178
1189
                    u->headers_in.status_n = status;
1179
1190
                    u->headers_in.status_line = *status_line;
1180
1191
 
 
1192
                } else if (u->headers_in.location) {
 
1193
                    u->headers_in.status_n = 302;
 
1194
                    u->headers_in.status_line.len =
 
1195
                                           sizeof("302 Moved Temporarily") - 1;
 
1196
                    u->headers_in.status_line.data =
 
1197
                                           (u_char *) "302 Moved Temporarily";
 
1198
 
1181
1199
                } else {
1182
1200
                    u->headers_in.status_n = 200;
1183
1201
                    u->headers_in.status_line.len = sizeof("200 OK") - 1;
1186
1204
 
1187
1205
                u->state->status = u->headers_in.status_n;
1188
1206
#if 0
1189
 
                if (u->cachable) {
1190
 
                    u->cachable = ngx_http_upstream_is_cachable(r);
 
1207
                if (u->cacheable) {
 
1208
                    u->cacheable = ngx_http_upstream_is_cacheable(r);
1191
1209
                }
1192
1210
#endif
1193
1211
 
1221
1239
        }
1222
1240
 
1223
1241
        if (rc == NGX_OK) {
1224
 
            return NGX_AGAIN;
 
1242
            continue;
1225
1243
        }
1226
1244
 
1227
1245
        /* rc == NGX_AGAIN */
1233
1251
            f->split_parts = ngx_array_create(r->pool, 1,
1234
1252
                                        sizeof(ngx_http_fastcgi_split_part_t));
1235
1253
            if (f->split_parts == NULL) {
1236
 
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
 
1254
                return NGX_ERROR;
1237
1255
            }
1238
1256
        }
1239
1257
 
1610
1628
    ngx_http_variable_t  *var;
1611
1629
 
1612
1630
    var = ngx_http_add_variable(cf, &ngx_http_fastcgi_script_name,
1613
 
                                NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHABLE);
 
1631
                                NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE);
1614
1632
    if (var == NULL) {
1615
1633
        return NGX_ERROR;
1616
1634
    }
1638
1656
     *     conf->upstream.next_upstream = 0;
1639
1657
     *     conf->upstream.temp_path = NULL;
1640
1658
     *     conf->upstream.hide_headers_hash = { NULL, 0 };
1641
 
     *     conf->upstream.hide_headers = NULL;
1642
 
     *     conf->upstream.pass_headers = NULL;
1643
1659
     *     conf->upstream.schema = { 0, NULL };
1644
1660
     *     conf->upstream.uri = { 0, NULL };
1645
1661
     *     conf->upstream.location = NULL;
1669
1685
    conf->upstream.pass_request_headers = NGX_CONF_UNSET;
1670
1686
    conf->upstream.pass_request_body = NGX_CONF_UNSET;
1671
1687
 
 
1688
    conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
 
1689
    conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
 
1690
 
1672
1691
    conf->upstream.intercept_errors = NGX_CONF_UNSET;
1673
1692
 
1674
1693
    /* "fastcgi_cyclic_temp_file" is disabled */
1689
1708
    u_char                       *p;
1690
1709
    size_t                        size;
1691
1710
    uintptr_t                    *code;
1692
 
    ngx_str_t                    *header;
1693
 
    ngx_uint_t                    i, j;
1694
 
    ngx_array_t                   hide_headers;
 
1711
    ngx_uint_t                    i;
1695
1712
    ngx_keyval_t                 *src;
1696
 
    ngx_hash_key_t               *hk;
1697
1713
    ngx_hash_init_t               hash;
1698
1714
    ngx_http_script_compile_t     sc;
1699
1715
    ngx_http_script_copy_code_t  *copy;
1855
1871
 
1856
1872
    ngx_conf_merge_str_value(conf->index, prev->index, "");
1857
1873
 
1858
 
    if (conf->upstream.hide_headers == NULL
1859
 
        && conf->upstream.pass_headers == NULL)
1860
 
    {
1861
 
        conf->upstream.hide_headers = prev->upstream.hide_headers;
1862
 
        conf->upstream.pass_headers = prev->upstream.pass_headers;
1863
 
        conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash;
1864
 
 
1865
 
        if (conf->upstream.hide_headers_hash.buckets) {
1866
 
            goto peers;
1867
 
        }
1868
 
 
1869
 
    } else {
1870
 
        if (conf->upstream.hide_headers == NULL) {
1871
 
            conf->upstream.hide_headers = prev->upstream.hide_headers;
1872
 
        }
1873
 
 
1874
 
        if (conf->upstream.pass_headers == NULL) {
1875
 
            conf->upstream.pass_headers = prev->upstream.pass_headers;
1876
 
        }
1877
 
    }
1878
 
 
1879
 
    if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
1880
 
        != NGX_OK)
1881
 
    {
1882
 
        return NGX_CONF_ERROR;
1883
 
    }
1884
 
 
1885
 
    for (header = ngx_http_fastcgi_hide_headers; header->len; header++) {
1886
 
        hk = ngx_array_push(&hide_headers);
1887
 
        if (hk == NULL) {
1888
 
            return NGX_CONF_ERROR;
1889
 
        }
1890
 
 
1891
 
        hk->key = *header;
1892
 
        hk->key_hash = ngx_hash_key_lc(header->data, header->len);
1893
 
        hk->value = (void *) 1;
1894
 
    }
1895
 
 
1896
 
    if (conf->upstream.hide_headers) {
1897
 
 
1898
 
        header = conf->upstream.hide_headers->elts;
1899
 
 
1900
 
        for (i = 0; i < conf->upstream.hide_headers->nelts; i++) {
1901
 
 
1902
 
            hk = hide_headers.elts;
1903
 
 
1904
 
            for (j = 0; j < hide_headers.nelts; j++) {
1905
 
                if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
1906
 
                    goto exist;
1907
 
                }
1908
 
            }
1909
 
 
1910
 
            hk = ngx_array_push(&hide_headers);
1911
 
            if (hk == NULL) {
1912
 
                return NGX_CONF_ERROR;
1913
 
            }
1914
 
 
1915
 
            hk->key = header[i];
1916
 
            hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len);
1917
 
            hk->value = (void *) 1;
1918
 
 
1919
 
        exist:
1920
 
 
1921
 
            continue;
1922
 
        }
1923
 
    }
1924
 
 
1925
 
    if (conf->upstream.pass_headers) {
1926
 
 
1927
 
        hk = hide_headers.elts;
1928
 
        header = conf->upstream.pass_headers->elts;
1929
 
 
1930
 
        for (i = 0; i < conf->upstream.pass_headers->nelts; i++) {
1931
 
 
1932
 
            for (j = 0; j < hide_headers.nelts; j++) {
1933
 
 
1934
 
                if (hk[j].key.data == NULL) {
1935
 
                    continue;
1936
 
                }
1937
 
 
1938
 
                if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) {
1939
 
                    hk[j].key.data = NULL;
1940
 
                    break;
1941
 
                }
1942
 
            }
1943
 
        }
1944
 
    }
1945
 
 
1946
 
    hash.hash = &conf->upstream.hide_headers_hash;
1947
 
    hash.key = ngx_hash_key_lc;
1948
1874
    hash.max_size = 512;
1949
1875
    hash.bucket_size = ngx_align(64, ngx_cacheline_size);
1950
1876
    hash.name = "fastcgi_hide_headers_hash";
1951
 
    hash.pool = cf->pool;
1952
 
    hash.temp_pool = NULL;
1953
1877
 
1954
 
    if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) {
 
1878
    if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
 
1879
                                            &prev->upstream,
 
1880
                                            ngx_http_fastcgi_hide_headers,
 
1881
                                            &hash)
 
1882
        != NGX_OK)
 
1883
    {
1955
1884
        return NGX_CONF_ERROR;
1956
1885
    }
1957
1886
 
1958
 
peers:
1959
 
 
1960
1887
    if (conf->upstream.upstream == NULL) {
1961
1888
        conf->upstream.upstream = prev->upstream.upstream;
1962
1889
        conf->upstream.schema = prev->upstream.schema;
2104
2031
 
2105
2032
    if (r->uri.len) {
2106
2033
        v->valid = 1;
2107
 
        v->no_cachable = 0;
 
2034
        v->no_cacheable = 0;
2108
2035
        v->not_found = 0;
2109
2036
 
2110
2037
        flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
2128
2055
    } else {
2129
2056
        v->len = 0;
2130
2057
        v->valid = 1;
2131
 
        v->no_cachable = 0;
 
2058
        v->no_cacheable = 0;
2132
2059
        v->not_found = 0;
2133
2060
        v->data = NULL;
2134
2061
 
2171
2098
 
2172
2099
    clcf->handler = ngx_http_fastcgi_handler;
2173
2100
 
2174
 
    lcf->upstream.location = clcf->name;
2175
 
 
2176
2101
    if (clcf->name.data[clcf->name.len - 1] == '/') {
2177
2102
        clcf->auto_redirect = 1;
2178
2103
    }
2215
2140
    sc.source = &value[1];
2216
2141
    sc.lengths = &flcf->upstream.store_lengths;
2217
2142
    sc.values = &flcf->upstream.store_values;
2218
 
    sc.variables = ngx_http_script_variables_count(&value[1]);;
 
2143
    sc.variables = ngx_http_script_variables_count(&value[1]);
2219
2144
    sc.complete_lengths = 1;
2220
2145
    sc.complete_values = 1;
2221
2146