diff options
| author | Igor Sysoev <igor@sysoev.ru> | 2004-03-12 16:57:08 +0000 |
|---|---|---|
| committer | Igor Sysoev <igor@sysoev.ru> | 2004-03-12 16:57:08 +0000 |
| commit | 67f88e9cc678d31b5995518922d3fcb63a129465 (patch) | |
| tree | 370c489b498feddaf17f12b125f6f75d69cdb9f2 /src/http/modules/proxy | |
| parent | a893eab667078a8ad9f473296663b36e6ade111a (diff) | |
| download | nginx-67f88e9cc678d31b5995518922d3fcb63a129465.tar.gz nginx-67f88e9cc678d31b5995518922d3fcb63a129465.tar.bz2 | |
nginx-0.0.2-2004-03-12-19:57:08 import
Diffstat (limited to 'src/http/modules/proxy')
| -rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_handler.c | 44 | ||||
| -rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_handler.h | 38 | ||||
| -rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_upstream.c | 93 |
3 files changed, 158 insertions, 17 deletions
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c index 68e9032c2..669a970d6 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -81,6 +81,20 @@ static ngx_command_t ngx_http_proxy_commands[] = { offsetof(ngx_http_proxy_loc_conf_t, send_timeout), NULL }, + { ngx_string("proxy_set_x_real_ip"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, set_x_real_ip), + NULL }, + + { ngx_string("proxy_add_x_forwarded_for"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, add_x_forwarded_for), + NULL }, + { ngx_string("proxy_header_buffer_size"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, @@ -109,6 +123,8 @@ static ngx_command_t ngx_http_proxy_commands[] = { offsetof(ngx_http_proxy_loc_conf_t, busy_buffers_size), NULL }, +#if (NGX_HTTP_FILE_CACHE) + { ngx_string("proxy_cache_path"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234, ngx_conf_set_path_slot, @@ -116,6 +132,8 @@ static ngx_command_t ngx_http_proxy_commands[] = { offsetof(ngx_http_proxy_loc_conf_t, cache_path), ngx_garbage_collector_http_cache_handler }, +#endif + { ngx_string("proxy_temp_path"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234, ngx_conf_set_path_slot, @@ -311,6 +329,7 @@ static int ngx_http_proxy_handler(ngx_http_request_t *r) ngx_memzero(p->state, sizeof(ngx_http_proxy_state_t)); +#if (NGX_HTTP_FILE_CACHE) if (!p->lcf->cache || (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD)) @@ -337,6 +356,14 @@ static int ngx_http_proxy_handler(ngx_http_request_t *r) } return ngx_http_proxy_get_cached_response(p); + +#else + + p->state->cache_state = NGX_HTTP_PROXY_CACHE_PASS; + + return ngx_http_proxy_request_upstream(p); + +#endif } @@ -404,12 +431,20 @@ void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev) rev->timedout = 0; p->busy_lock.time++; p->state->bl_time = p->busy_lock.time; + +#if (NGX_HTTP_FILE_CACHE) + if (p->state->cache_state < NGX_HTTP_PROXY_CACHE_MISS) { ngx_http_proxy_upstream_busy_lock(p); } else { ngx_http_proxy_cache_busy_lock(p); } +#else + + ngx_http_proxy_upstream_busy_lock(p); + +#endif return; } @@ -738,6 +773,10 @@ static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf) conf->request_buffer_size = NGX_CONF_UNSET; conf->connect_timeout = NGX_CONF_UNSET; conf->send_timeout = NGX_CONF_UNSET; + + conf->set_x_real_ip = NGX_CONF_UNSET; + conf->add_x_forwarded_for = NGX_CONF_UNSET; + conf->header_buffer_size = NGX_CONF_UNSET; conf->read_timeout = NGX_CONF_UNSET; conf->busy_buffers_size = NGX_CONF_UNSET; @@ -776,6 +815,11 @@ static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, ngx_conf_merge_msec_value(conf->connect_timeout, prev->connect_timeout, 60000); ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 30000); + + ngx_conf_merge_value(conf->set_x_real_ip, prev->set_x_real_ip, 0); + ngx_conf_merge_value(conf->add_x_forwarded_for, + prev->add_x_forwarded_for, 0); + ngx_conf_merge_size_value(conf->header_buffer_size, prev->header_buffer_size, 4096); ngx_conf_merge_msec_value(conf->read_timeout, prev->read_timeout, 30000); diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h index 62d05489d..44fb662c0 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.h +++ b/src/http/modules/proxy/ngx_http_proxy_handler.h @@ -56,19 +56,22 @@ typedef struct { ssize_t max_temp_file_size; ssize_t temp_file_write_size; - int cyclic_temp_file; + ngx_flag_t cyclic_temp_file; - int cache; + ngx_flag_t cache; - int pass_server; - int pass_x_accel_expires; + ngx_flag_t set_x_real_ip; + ngx_flag_t add_x_forwarded_for; - int ignore_expires; + ngx_flag_t pass_server; + ngx_flag_t pass_x_accel_expires; + + ngx_flag_t ignore_expires; int lm_factor; time_t default_expires; - int next_upstream; - int use_stale; + u_int next_upstream; + u_int use_stale; ngx_path_t *cache_path; ngx_path_t *temp_path; @@ -194,26 +197,31 @@ typedef struct { #define NGX_HTTP_PROXY_PARSE_NO_HEADER 20 -#define NGX_HTTP_PROXY_FT_ERROR 2 -#define NGX_HTTP_PROXY_FT_TIMEOUT 4 -#define NGX_HTTP_PROXY_FT_INVALID_HEADER 8 -#define NGX_HTTP_PROXY_FT_HTTP_500 16 -#define NGX_HTTP_PROXY_FT_HTTP_404 32 -#define NGX_HTTP_PROXY_FT_BUSY_LOCK 64 -#define NGX_HTTP_PROXY_FT_MAX_WAITING 128 +#define NGX_HTTP_PROXY_FT_ERROR 0x02 +#define NGX_HTTP_PROXY_FT_TIMEOUT 0x04 +#define NGX_HTTP_PROXY_FT_INVALID_HEADER 0x08 +#define NGX_HTTP_PROXY_FT_HTTP_500 0x10 +#define NGX_HTTP_PROXY_FT_HTTP_404 0x20 +#define NGX_HTTP_PROXY_FT_BUSY_LOCK 0x40 +#define NGX_HTTP_PROXY_FT_MAX_WAITING 0x80 int ngx_http_proxy_request_upstream(ngx_http_proxy_ctx_t *p); +#if (NGX_HTTP_FILE_CACHE) + int ngx_http_proxy_get_cached_response(ngx_http_proxy_ctx_t *p); int ngx_http_proxy_send_cached_response(ngx_http_proxy_ctx_t *p); int ngx_http_proxy_is_cachable(ngx_http_proxy_ctx_t *p); int ngx_http_proxy_update_cache(ngx_http_proxy_ctx_t *p); +void ngx_http_proxy_cache_busy_lock(ngx_http_proxy_ctx_t *p); + +#endif + void ngx_http_proxy_check_broken_connection(ngx_event_t *wev); void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev); -void ngx_http_proxy_cache_busy_lock(ngx_http_proxy_ctx_t *p); void ngx_http_proxy_upstream_busy_lock(ngx_http_proxy_ctx_t *p); size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len); diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c index a65b86470..67dabe94e 100644 --- a/src/http/modules/proxy/ngx_http_proxy_upstream.c +++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c @@ -38,6 +38,8 @@ static char *upstream_header_errors[] = { static char http_version[] = " HTTP/1.0" CRLF; static char host_header[] = "Host: "; +static char x_real_ip_header[] = "X-Real-IP: "; +static char x_forwarded_for_header[] = "X-Forwarded-For: "; static char connection_close_header[] = "Connection: close" CRLF; @@ -116,6 +118,27 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p) + sizeof(connection_close_header) - 1 + 2; /* 2 is for "\r\n" at the header end */ + if (p->lcf->set_x_real_ip) { + /* 2 is for "\r\n" */ + len += sizeof(x_real_ip_header) - 1 + INET_ADDRSTRLEN - 1 + 2; + } + + + if (p->lcf->add_x_forwarded_for) { + if (r->headers_in.x_forwarded_for) { + len += r->headers_in.x_forwarded_for->key.len + + 2 /* 2 is ofr ": " */ + + r->headers_in.x_forwarded_for->value.len + + 2 /* 2 is ofr ", " */ + + INET_ADDRSTRLEN - 1 + + 2; /* 2 is for "\r\n" */ + } else { + len += sizeof(x_forwarded_for_header) - 1 + INET_ADDRSTRLEN - 1 + 2; + /* 2 is for "\r\n" */ + } + } + + header = (ngx_table_elt_t *) r->headers_in.headers->elts; for (i = 0; i < r->headers_in.headers->nelts; i++) { @@ -156,19 +179,57 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p) h->last = ngx_cpymem(h->last, http_version, sizeof(http_version) - 1); - /* "Host" header */ + /* the "Host" header */ h->last = ngx_cpymem(h->last, host_header, sizeof(host_header) - 1); h->last = ngx_cpymem(h->last, uc->host_header.data, uc->host_header.len); *(h->last++) = CR; *(h->last++) = LF; - /* "Connection: close" header */ + /* the "Connection: close" header */ h->last = ngx_cpymem(h->last, connection_close_header, sizeof(connection_close_header) - 1); + /* the "X-Real-IP" header */ + + if (p->lcf->set_x_real_ip) { + h->last = ngx_cpymem(h->last, x_real_ip_header, + sizeof(x_real_ip_header) - 1); + h->last = ngx_cpymem(h->last, r->connection->addr_text.data, + r->connection->addr_text.len); + *(h->last++) = CR; *(h->last++) = LF; + } + + + /* the "X-Forwarded-For" header */ + + if (p->lcf->add_x_forwarded_for) { + if (r->headers_in.x_forwarded_for) { + h->last = ngx_cpymem(h->last, + r->headers_in.x_forwarded_for->key.data, + r->headers_in.x_forwarded_for->key.len); + + *(h->last++) = ':'; *(h->last++) = ' '; + + h->last = ngx_cpymem(h->last, + r->headers_in.x_forwarded_for->value.data, + r->headers_in.x_forwarded_for->value.len); + + *(h->last++) = ','; *(h->last++) = ' '; + + } else { + h->last = ngx_cpymem(h->last, x_forwarded_for_header, + sizeof(x_forwarded_for_header) - 1); + } + + h->last = ngx_cpymem(h->last, r->connection->addr_text.data, + r->connection->addr_text.len); + *(h->last++) = CR; *(h->last++) = LF; + } + + for (i = 0; i < r->headers_in.headers->nelts; i++) { if (&header[i] == r->headers_in.host) { @@ -183,6 +244,12 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p) continue; } + if (&header[i] == r->headers_in.x_forwarded_for + && p->lcf->add_x_forwarded_for) + { + continue; + } + h->last = ngx_cpymem(h->last, header[i].key.data, header[i].key.len); *(h->last++) = ':'; *(h->last++) = ' '; @@ -377,12 +444,16 @@ void ngx_http_proxy_upstream_busy_lock(ngx_http_proxy_ctx_t *p) ft_type = NGX_HTTP_PROXY_FT_MAX_WAITING; } +#if (NGX_HTTP_CACHE) + if (p->stale && (p->lcf->use_stale & ft_type)) { ngx_http_proxy_finalize_request(p, ngx_http_proxy_send_cached_response(p)); return; } +#endif + p->state->status = NGX_HTTP_SERVICE_UNAVAILABLE; ngx_http_proxy_finalize_request(p, NGX_HTTP_SERVICE_UNAVAILABLE); } @@ -692,6 +763,8 @@ static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev) return; } +#if (NGX_HTTP_CACHE) + if (p->upstream->peer.tries == 0 && p->stale && (p->lcf->use_stale & NGX_HTTP_PROXY_FT_HTTP_500)) @@ -701,6 +774,8 @@ static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev) return; } + +#endif } if (p->status == NGX_HTTP_NOT_FOUND @@ -841,10 +916,14 @@ static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev) /* TODO: hook to process the upstream header */ +#if (NGX_HTTP_CACHE) + if (p->cachable) { p->cachable = ngx_http_proxy_is_cachable(p); } +#endif + ngx_http_proxy_send_response(p); return; @@ -1118,6 +1197,9 @@ static void ngx_http_proxy_process_body(ngx_event_t *ev) } if (p->upstream->peer.connection) { + +#if (NGX_HTTP_FILE_CACHE) + if (ep->upstream_done && p->cachable) { if (ngx_http_proxy_update_cache(p) == NGX_ERROR) { ngx_http_busy_unlock(p->lcf->busy_lock, &p->busy_lock); @@ -1136,6 +1218,8 @@ static void ngx_http_proxy_process_body(ngx_event_t *ev) } } +#endif + if (ep->upstream_done || ep->upstream_eof || ep->upstream_error) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, "http proxy upstream exit"); @@ -1214,12 +1298,17 @@ static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p, int ft_type) if (p->upstream->peer.tries == 0 || !(p->lcf->next_upstream & ft_type)) { + +#if (NGX_HTTP_CACHE) + if (p->stale && (p->lcf->use_stale & ft_type)) { ngx_http_proxy_finalize_request(p, ngx_http_proxy_send_cached_response(p)); return; } +#endif + ngx_http_proxy_finalize_request(p, status); return; } |
