Mercurial > hg > nginx-vendor-0-6
diff src/http/modules/proxy/ngx_http_proxy_header.c @ 0:f0b350454894 NGINX_0_1_0
nginx 0.1.0
*) The first public version.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 04 Oct 2004 00:00:00 +0400 |
parents | |
children | cc9f381affaa |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/src/http/modules/proxy/ngx_http_proxy_header.c @@ -0,0 +1,198 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_http.h> +#include <ngx_http_proxy_handler.h> + + +static int ngx_http_proxy_rewrite_location_header(ngx_http_proxy_ctx_t *p, + ngx_table_elt_t *loc); + +int ngx_http_proxy_copy_header(ngx_http_proxy_ctx_t *p, + ngx_http_proxy_headers_in_t *headers_in) +{ + ngx_uint_t i; + ngx_list_part_t *part; + ngx_table_elt_t *ho, *h; + ngx_http_request_t *r; + + r = p->request; + + part = &headers_in->headers.part; + h = part->elts; + +#if 0 + h = headers_in->headers.elts; + for (i = 0; i < headers_in->headers.nelts; i++) { +#endif + + for (i = 0 ; /* void */; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + + part = part->next; + h = part->elts; + i = 0; + } + + /* ignore some headers */ + + if (&h[i] == headers_in->connection) { + continue; + } + + if (&h[i] == headers_in->x_pad) { + continue; + } + + if (p->accel) { + if (&h[i] == headers_in->date + || &h[i] == headers_in->accept_ranges) { + continue; + } + + if (&h[i] == headers_in->x_accel_expires + && !p->lcf->pass_x_accel_expires) + { + continue; + } + + if (&h[i] == headers_in->server && !p->lcf->pass_server) { + continue; + } + + if (&h[i] == headers_in->location) { + if (ngx_http_proxy_rewrite_location_header(p, &h[i]) + == NGX_ERROR) + { + return NGX_ERROR; + } + + continue; + } + } + + + /* "Content-Type" is handled specially */ + + if (&h[i] == headers_in->content_type) { + r->headers_out.content_type = &h[i]; + r->headers_out.content_type->key.len = 0; + continue; + } + + + /* copy some header pointers and set up r->headers_out */ + + if (!(ho = ngx_list_push(&r->headers_out.headers))) { + return NGX_ERROR; + } + + *ho = h[i]; + + if (&h[i] == headers_in->expires) { + r->headers_out.expires = ho; + continue; + } + + if (&h[i] == headers_in->cache_control) { + r->headers_out.cache_control = ho; + continue; + } + + if (&h[i] == headers_in->etag) { + r->headers_out.etag = ho; + continue; + } + + if (&h[i] == headers_in->last_modified) { + r->headers_out.last_modified = ho; + /* TODO: update r->headers_out.last_modified_time */ + continue; + } + + /* + * ngx_http_header_filter() passes the following headers as is + * and does not handle them specially if they are set: + * r->headers_out.server, + * r->headers_out.date, + * r->headers_out.content_length + */ + + if (&h[i] == headers_in->server) { + r->headers_out.server = ho; + continue; + } + + if (&h[i] == headers_in->date) { + r->headers_out.date = ho; + continue; + } + + if (&h[i] == headers_in->content_length) { + r->headers_out.content_length = ho; + r->headers_out.content_length_n = ngx_atoi(ho->value.data, + ho->value.len); + continue; + } + } + + return NGX_OK; +} + + +static int ngx_http_proxy_rewrite_location_header(ngx_http_proxy_ctx_t *p, + ngx_table_elt_t *loc) +{ + u_char *last; + ngx_table_elt_t *location; + ngx_http_request_t *r; + ngx_http_proxy_upstream_conf_t *uc; + + r = p->request; + uc = p->lcf->upstream; + + if (!(location = ngx_list_push(&r->headers_out.headers))) { + return NGX_ERROR; + } + + /* + * we do not set r->headers_out.location to avoid the handling + * the local redirects without a host name by ngx_http_header_filter() + */ + +#if 0 + r->headers_out.location = location; +#endif + + if (uc->url.len > loc->value.len + || ngx_rstrncmp(loc->value.data, uc->url.data, uc->url.len) != 0) + { + *location = *loc; + return NGX_OK; + } + + /* TODO: proxy_reverse */ + + location->value.len = uc->location->len + + (loc->value.len - uc->url.len) + 1; + if (!(location->value.data = ngx_palloc(r->pool, location->value.len))) { + return NGX_ERROR; + } + + last = ngx_cpymem(location->value.data, + uc->location->data, uc->location->len); + + ngx_cpystrn(last, loc->value.data + uc->url.len, + loc->value.len - uc->url.len + 1); + + return NGX_OK; +}