diff -ur ../nginx-0.5.17-orig/src/http/ngx_http_core_module.c src/http/ngx_http_core_module.c --- ../nginx-0.5.17-orig/src/http/ngx_http_core_module.c Mon Apr 2 10:27:30 2007 +++ src/http/ngx_http_core_module.c Thu Apr 5 18:57:42 2007 @@ -2929,9 +2929,9 @@ return NGX_CONF_ERROR; } - if (err->status < 400 || err->status > 599) { + if (err->status < 300 || err->status > 599) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "value \"%V\" must be between 400 and 599", + "value \"%V\" must be between 300 and 599", &value[i]); return NGX_CONF_ERROR; } diff -ur ../nginx-0.5.17-orig/src/http/ngx_http_upstream.c src/http/ngx_http_upstream.c --- ../nginx-0.5.17-orig/src/http/ngx_http_upstream.c Sat Mar 31 19:37:09 2007 +++ src/http/ngx_http_upstream.c Fri Apr 6 15:20:34 2007 @@ -96,111 +96,111 @@ { ngx_string("Status"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, status), - ngx_http_upstream_copy_header_line, 0, 0 }, + ngx_http_upstream_copy_header_line, 0, 0, 0 }, { ngx_string("Content-Type"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, content_type), - ngx_http_upstream_copy_content_type, 0, 1 }, + ngx_http_upstream_copy_content_type, 0, 1, 0 }, { ngx_string("Content-Length"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, content_length), - ngx_http_upstream_copy_content_length, 0, 0 }, + ngx_http_upstream_copy_content_length, 0, 0, 0 }, { ngx_string("Date"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, date), ngx_http_upstream_copy_header_line, - offsetof(ngx_http_headers_out_t, date), 0 }, + offsetof(ngx_http_headers_out_t, date), 0, 0 }, { ngx_string("Server"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, server), ngx_http_upstream_copy_header_line, - offsetof(ngx_http_headers_out_t, server), 0 }, + offsetof(ngx_http_headers_out_t, server), 0, 0 }, { ngx_string("WWW-Authenticate"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, www_authenticate), - ngx_http_upstream_copy_header_line, 0, 0 }, + ngx_http_upstream_copy_header_line, 0, 0, 0 }, { ngx_string("Location"), ngx_http_upstream_ignore_header_line, 0, - ngx_http_upstream_rewrite_location, 0, 0 }, + ngx_http_upstream_rewrite_location, 0, 0, 1 }, { ngx_string("Refresh"), ngx_http_upstream_ignore_header_line, 0, - ngx_http_upstream_rewrite_refresh, 0, 0 }, + ngx_http_upstream_rewrite_refresh, 0, 0, 0 }, { ngx_string("Set-Cookie"), ngx_http_upstream_ignore_header_line, 0, - ngx_http_upstream_copy_header_line, 0, 1 }, + ngx_http_upstream_copy_header_line, 0, 1, 1 }, { ngx_string("Content-Disposition"), ngx_http_upstream_ignore_header_line, 0, - ngx_http_upstream_copy_header_line, 0, 1 }, + ngx_http_upstream_copy_header_line, 0, 1, 0 }, { ngx_string("Cache-Control"), ngx_http_upstream_process_multi_header_lines, offsetof(ngx_http_upstream_headers_in_t, cache_control), ngx_http_upstream_copy_multi_header_lines, - offsetof(ngx_http_headers_out_t, cache_control), 1 }, + offsetof(ngx_http_headers_out_t, cache_control), 1, 1 }, { ngx_string("Expires"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, expires), ngx_http_upstream_copy_header_line, - offsetof(ngx_http_headers_out_t, expires), 1 }, + offsetof(ngx_http_headers_out_t, expires), 1, 1 }, { ngx_string("Accept-Ranges"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, accept_ranges), ngx_http_upstream_copy_header_line, - offsetof(ngx_http_headers_out_t, accept_ranges), 1 }, + offsetof(ngx_http_headers_out_t, accept_ranges), 1, 0 }, { ngx_string("Connection"), ngx_http_upstream_ignore_header_line, 0, - ngx_http_upstream_ignore_header_line, 0, 0 }, + ngx_http_upstream_ignore_header_line, 0, 0, 0 }, { ngx_string("Keep-Alive"), ngx_http_upstream_ignore_header_line, 0, - ngx_http_upstream_ignore_header_line, 0, 0 }, + ngx_http_upstream_ignore_header_line, 0, 0, 0 }, { ngx_string("X-Powered-By"), ngx_http_upstream_ignore_header_line, 0, - ngx_http_upstream_copy_header_line, 0, 0 }, + ngx_http_upstream_copy_header_line, 0, 0, 0 }, { ngx_string("X-Accel-Expires"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, x_accel_expires), - ngx_http_upstream_copy_header_line, 0, 0 }, + ngx_http_upstream_copy_header_line, 0, 0, 0 }, { ngx_string("X-Accel-Redirect"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, x_accel_redirect), - ngx_http_upstream_ignore_header_line, 0, 0 }, + ngx_http_upstream_ignore_header_line, 0, 0, 0 }, { ngx_string("X-Accel-Limit-Rate"), ngx_http_upstream_process_limit_rate, 0, - ngx_http_upstream_ignore_header_line, 0, 0 }, + ngx_http_upstream_ignore_header_line, 0, 0, 0 }, { ngx_string("X-Accel-Buffering"), ngx_http_upstream_process_buffering, 0, - ngx_http_upstream_ignore_header_line, 0, 0 }, + ngx_http_upstream_ignore_header_line, 0, 0, 0 }, { ngx_string("X-Accel-Charset"), ngx_http_upstream_process_charset, 0, - ngx_http_upstream_ignore_header_line, 0, 0 }, + ngx_http_upstream_ignore_header_line, 0, 0, 0 }, #if (NGX_HTTP_GZIP) { ngx_string("Content-Encoding"), ngx_http_upstream_process_header_line, offsetof(ngx_http_upstream_headers_in_t, content_encoding), - ngx_http_upstream_copy_content_encoding, 0, 0 }, + ngx_http_upstream_copy_content_encoding, 0, 0, 0 }, #endif - { ngx_null_string, NULL, 0, NULL, 0, 0 } + { ngx_null_string, NULL, 0, NULL, 0, 0, 0 } }; @@ -1067,7 +1067,7 @@ } - if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST + if (u->headers_in.status_n >= NGX_HTTP_SPECIAL_RESPONSE && u->conf->intercept_errors) { clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); @@ -1091,6 +1091,38 @@ *r->headers_out.www_authenticate = *u->headers_in.www_authenticate; + + } else if (u->headers_in.status_n == NGX_HTTP_MOVED_PERMANENTLY + || u->headers_in.status_n == NGX_HTTP_MOVED_TEMPORARILY) { + + umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); + + part = &r->upstream->headers_in.headers.part; + h = part->elts; + + for (i = 0; /* void */; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + + part = part->next; + h = part->elts; + i = 0; + } + + hh = ngx_hash_find(&umcf->headers_in_hash, h[i].hash, + h[i].lowcase_key, h[i].key.len); + + if (hh && hh->moved) { + if (hh->copy_handler(r, &h[i], hh->conf) != NGX_OK) { + ngx_http_upstream_finalize_request(r, u, + NGX_HTTP_INTERNAL_SERVER_ERROR); + return; + } + } + } } ngx_http_upstream_finalize_request(r, u, diff -ur ../nginx-0.5.17-orig/src/http/ngx_http_upstream.h src/http/ngx_http_upstream.h --- ../nginx-0.5.17-orig/src/http/ngx_http_upstream.h Tue Dec 12 19:46:16 2006 +++ src/http/ngx_http_upstream.h Fri Apr 6 15:09:07 2007 @@ -157,6 +157,7 @@ ngx_http_header_handler_pt copy_handler; ngx_uint_t conf; ngx_uint_t redirect; /* unsigned redirect:1; */ + ngx_uint_t moved; /* unsigned moved:1; */ } ngx_http_upstream_header_t;