summaryrefslogtreecommitdiffhomepage
path: root/src/http/modules/proxy
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2004-03-12 16:57:08 +0000
committerIgor Sysoev <igor@sysoev.ru>2004-03-12 16:57:08 +0000
commit67f88e9cc678d31b5995518922d3fcb63a129465 (patch)
tree370c489b498feddaf17f12b125f6f75d69cdb9f2 /src/http/modules/proxy
parenta893eab667078a8ad9f473296663b36e6ade111a (diff)
downloadnginx-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.c44
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_handler.h38
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_upstream.c93
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;
}