comparison src/http/ngx_http_upstream.c @ 332:2eea67ed0bc2 NGINX_0_5_36

nginx 0.5.36 *) Bugfix: the "sub_filter" directive might set text to change into output. *) Bugfix: a segmentation fault occurred in worker process, if empty stub block was used second time in SSI. *) Bugfix: the "proxy_store" and "fastcgi_store" directives did not check a response length. *) Bugfix: nginx issued the bogus error message "SSL_shutdown() failed (SSL: )"; bug appeared in 0.5.35. *) Bugfix: in HTTPS mode requests might fail with the "bad write retry" error; bug appeared in 0.5.35. *) Bugfix: the "fastcgi_catch_stderr" directive did return error code; now it returns 502 code, that can be rerouted to a next server using the "fastcgi_next_upstream invalid_header" directive. *) Bugfix: a segmentation fault occurred in master process if the "fastcgi_catch_stderr" directive was used; bug appeared in 0.5.32. Thanks to Manlio Perillo.
author Igor Sysoev <http://sysoev.ru>
date Sun, 04 May 2008 00:00:00 +0400
parents 26ff8d6b618d
children
comparison
equal deleted inserted replaced
331:27fb10cee3fd 332:2eea67ed0bc2
1039 if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) { 1039 if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) {
1040 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_INVALID_HEADER); 1040 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_INVALID_HEADER);
1041 return; 1041 return;
1042 } 1042 }
1043 1043
1044 if (rc == NGX_ERROR || rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { 1044 if (rc == NGX_ERROR) {
1045 ngx_http_upstream_finalize_request(r, u, 1045 ngx_http_upstream_finalize_request(r, u,
1046 NGX_HTTP_INTERNAL_SERVER_ERROR); 1046 NGX_HTTP_INTERNAL_SERVER_ERROR);
1047 return; 1047 return;
1048 } 1048 }
1049 1049
1232 r->headers_out.date->hash = 0; 1232 r->headers_out.date->hash = 0;
1233 } 1233 }
1234 1234
1235 r->headers_out.status = u->headers_in.status_n; 1235 r->headers_out.status = u->headers_in.status_n;
1236 r->headers_out.status_line = u->headers_in.status_line; 1236 r->headers_out.status_line = u->headers_in.status_line;
1237
1238 u->headers_in.content_length_n = r->headers_out.content_length_n;
1237 1239
1238 if (r->headers_out.content_length_n != -1) { 1240 if (r->headers_out.content_length_n != -1) {
1239 u->length = (size_t) r->headers_out.content_length_n; 1241 u->length = (size_t) r->headers_out.content_length_n;
1240 1242
1241 } else { 1243 } else {
1836 1838
1837 1839
1838 static void 1840 static void
1839 ngx_http_upstream_process_body(ngx_event_t *ev) 1841 ngx_http_upstream_process_body(ngx_event_t *ev)
1840 { 1842 {
1843 ngx_temp_file_t *tf;
1841 ngx_event_pipe_t *p; 1844 ngx_event_pipe_t *p;
1842 ngx_connection_t *c, *downstream; 1845 ngx_connection_t *c, *downstream;
1843 ngx_http_log_ctx_t *ctx; 1846 ngx_http_log_ctx_t *ctx;
1844 ngx_http_request_t *r; 1847 ngx_http_request_t *r;
1845 ngx_http_upstream_t *u; 1848 ngx_http_upstream_t *u;
1930 1933
1931 if (u->peer.connection) { 1934 if (u->peer.connection) {
1932 1935
1933 if (u->store) { 1936 if (u->store) {
1934 1937
1935 if (p->upstream_eof && u->headers_in.status_n == NGX_HTTP_OK) { 1938 tf = u->pipe->temp_file;
1936 1939
1940 if (p->upstream_eof
1941 && u->headers_in.status_n == NGX_HTTP_OK
1942 && (u->headers_in.content_length_n == -1
1943 || (u->headers_in.content_length_n == tf->offset)))
1944 {
1937 ngx_http_upstream_store(r, u); 1945 ngx_http_upstream_store(r, u);
1938 1946
1939 } else if ((p->upstream_error 1947 } else if ((p->upstream_error
1940 || (p->upstream_eof 1948 || (p->upstream_eof
1941 && u->headers_in.status_n != NGX_HTTP_OK)) 1949 && u->headers_in.status_n != NGX_HTTP_OK))
1942 && u->pipe->temp_file->file.fd != NGX_INVALID_FILE) 1950 && tf->file.fd != NGX_INVALID_FILE)
1943 { 1951 {
1944 if (ngx_delete_file(u->pipe->temp_file->file.name.data) 1952 if (ngx_delete_file(tf->file.name.data) == NGX_FILE_ERROR) {
1945 == NGX_FILE_ERROR) 1953
1946 {
1947 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, 1954 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
1948 ngx_delete_file_n " \"%s\" failed", 1955 ngx_delete_file_n " \"%s\" failed",
1949 u->pipe->temp_file->file.name.data); 1956 u->pipe->temp_file->file.name.data);
1950 } 1957 }
1951 } 1958 }
2533 } 2540 }
2534 2541
2535 last = p; 2542 last = p;
2536 2543
2537 while (*++p == ' ') { /* void */ } 2544 while (*++p == ' ') { /* void */ }
2545
2546 if (*p == '\0') {
2547 return NGX_OK;
2548 }
2538 2549
2539 if (ngx_strncasecmp(p, (u_char *) "charset=", 8) != 0) { 2550 if (ngx_strncasecmp(p, (u_char *) "charset=", 8) != 0) {
2540 continue; 2551 continue;
2541 } 2552 }
2542 2553
3263 3274
3264 return uscf; 3275 return uscf;
3265 } 3276 }
3266 3277
3267 3278
3279 ngx_int_t
3280 ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
3281 ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,
3282 ngx_str_t *default_hide_headers, ngx_hash_init_t *hash)
3283 {
3284 ngx_str_t *h;
3285 ngx_uint_t i, j;
3286 ngx_array_t hide_headers;
3287 ngx_hash_key_t *hk;
3288
3289 if (conf->hide_headers == NGX_CONF_UNSET_PTR
3290 && conf->pass_headers == NGX_CONF_UNSET_PTR)
3291 {
3292 conf->hide_headers_hash = prev->hide_headers_hash;
3293
3294 if (conf->hide_headers_hash.buckets) {
3295 return NGX_OK;
3296 }
3297
3298 conf->hide_headers = prev->hide_headers;
3299 conf->pass_headers = prev->pass_headers;
3300
3301 } else {
3302 if (conf->hide_headers == NGX_CONF_UNSET_PTR) {
3303 conf->hide_headers = prev->hide_headers;
3304 }
3305
3306 if (conf->pass_headers == NGX_CONF_UNSET_PTR) {
3307 conf->pass_headers = prev->pass_headers;
3308 }
3309 }
3310
3311 if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
3312 != NGX_OK)
3313 {
3314 return NGX_ERROR;
3315 }
3316
3317 for (h = default_hide_headers; h->len; h++) {
3318 hk = ngx_array_push(&hide_headers);
3319 if (hk == NULL) {
3320 return NGX_ERROR;
3321 }
3322
3323 hk->key = *h;
3324 hk->key_hash = ngx_hash_key_lc(h->data, h->len);
3325 hk->value = (void *) 1;
3326 }
3327
3328 if (conf->hide_headers != NGX_CONF_UNSET_PTR) {
3329
3330 h = conf->hide_headers->elts;
3331
3332 for (i = 0; i < conf->hide_headers->nelts; i++) {
3333
3334 hk = hide_headers.elts;
3335
3336 for (j = 0; j < hide_headers.nelts; j++) {
3337 if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) {
3338 goto exist;
3339 }
3340 }
3341
3342 hk = ngx_array_push(&hide_headers);
3343 if (hk == NULL) {
3344 return NGX_ERROR;
3345 }
3346
3347 hk->key = h[i];
3348 hk->key_hash = ngx_hash_key_lc(h[i].data, h[i].len);
3349 hk->value = (void *) 1;
3350
3351 exist:
3352
3353 continue;
3354 }
3355 }
3356
3357 if (conf->pass_headers != NGX_CONF_UNSET_PTR) {
3358
3359 h = conf->pass_headers->elts;
3360 hk = hide_headers.elts;
3361
3362 for (i = 0; i < conf->pass_headers->nelts; i++) {
3363 for (j = 0; j < hide_headers.nelts; j++) {
3364
3365 if (hk[j].key.data == NULL) {
3366 continue;
3367 }
3368
3369 if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) {
3370 hk[j].key.data = NULL;
3371 break;
3372 }
3373 }
3374 }
3375 }
3376
3377 hash->hash = &conf->hide_headers_hash;
3378 hash->key = ngx_hash_key_lc;
3379 hash->pool = cf->pool;
3380 hash->temp_pool = NULL;
3381
3382 return ngx_hash_init(hash, hide_headers.elts, hide_headers.nelts);
3383 }
3384
3385
3268 static void * 3386 static void *
3269 ngx_http_upstream_create_main_conf(ngx_conf_t *cf) 3387 ngx_http_upstream_create_main_conf(ngx_conf_t *cf)
3270 { 3388 {
3271 ngx_http_upstream_main_conf_t *umcf; 3389 ngx_http_upstream_main_conf_t *umcf;
3272 3390