Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2 | /* |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3 | * Copyright (C) Igor Sysoev |
| 4 | */ |
| 5 | |
| 6 | |
| 7 | #include <ngx_config.h> |
| 8 | #include <ngx_core.h> |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 9 | #include <ngx_http.h> |
| 10 | |
| 11 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 12 | typedef struct ngx_http_proxy_redirect_s ngx_http_proxy_redirect_t; |
| 13 | |
| 14 | typedef ngx_int_t (*ngx_http_proxy_redirect_pt)(ngx_http_request_t *r, |
| 15 | ngx_table_elt_t *h, size_t prefix, ngx_http_proxy_redirect_t *pr); |
| 16 | |
| 17 | struct ngx_http_proxy_redirect_s { |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 18 | ngx_http_proxy_redirect_pt handler; |
| 19 | ngx_str_t redirect; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 20 | |
| 21 | union { |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 22 | ngx_str_t text; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 23 | |
| 24 | struct { |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 25 | void *lengths; |
| 26 | void *values; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 27 | } vars; |
| 28 | |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 29 | void *regex; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 30 | } replacement; |
| 31 | }; |
| 32 | |
| 33 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 34 | typedef struct { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 35 | ngx_str_t key_start; |
Igor Sysoev | 73c3121 | 2008-12-10 14:44:48 +0000 | [diff] [blame] | 36 | ngx_str_t schema; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 37 | ngx_str_t host_header; |
| 38 | ngx_str_t port; |
| 39 | ngx_str_t uri; |
| 40 | } ngx_http_proxy_vars_t; |
| 41 | |
| 42 | |
| 43 | typedef struct { |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 44 | ngx_http_upstream_conf_t upstream; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 45 | |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 46 | ngx_array_t *flushes; |
| 47 | ngx_array_t *body_set_len; |
| 48 | ngx_array_t *body_set; |
| 49 | ngx_array_t *headers_set_len; |
| 50 | ngx_array_t *headers_set; |
| 51 | ngx_hash_t headers_set_hash; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 52 | |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 53 | ngx_array_t *headers_source; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 54 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 55 | ngx_array_t *proxy_lengths; |
| 56 | ngx_array_t *proxy_values; |
| 57 | |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 58 | ngx_array_t *redirects; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 59 | |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 60 | ngx_str_t body_source; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 61 | |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 62 | ngx_str_t method; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 63 | ngx_str_t location; |
| 64 | ngx_str_t url; |
| 65 | |
Igor Sysoev | 44a69c8 | 2009-04-06 08:58:44 +0000 | [diff] [blame] | 66 | #if (NGX_HTTP_CACHE) |
| 67 | ngx_http_complex_value_t cache_key; |
| 68 | #endif |
| 69 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 70 | ngx_http_proxy_vars_t vars; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 71 | |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 72 | ngx_flag_t redirect; |
Igor Sysoev | 8a19bff | 2007-04-22 20:21:59 +0000 | [diff] [blame] | 73 | |
| 74 | ngx_uint_t headers_hash_max_size; |
| 75 | ngx_uint_t headers_hash_bucket_size; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 76 | } ngx_http_proxy_loc_conf_t; |
| 77 | |
| 78 | |
| 79 | typedef struct { |
Igor Sysoev | 54b35b0 | 2010-06-15 15:15:06 +0000 | [diff] [blame] | 80 | ngx_http_status_t status; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 81 | ngx_http_proxy_vars_t vars; |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 82 | size_t internal_body_length; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 83 | } ngx_http_proxy_ctx_t; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 84 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 85 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 86 | static ngx_int_t ngx_http_proxy_eval(ngx_http_request_t *r, |
| 87 | ngx_http_proxy_ctx_t *ctx, ngx_http_proxy_loc_conf_t *plcf); |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 88 | #if (NGX_HTTP_CACHE) |
| 89 | static ngx_int_t ngx_http_proxy_create_key(ngx_http_request_t *r); |
| 90 | #endif |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 91 | static ngx_int_t ngx_http_proxy_create_request(ngx_http_request_t *r); |
| 92 | static ngx_int_t ngx_http_proxy_reinit_request(ngx_http_request_t *r); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 93 | static ngx_int_t ngx_http_proxy_process_status_line(ngx_http_request_t *r); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 94 | static ngx_int_t ngx_http_proxy_process_header(ngx_http_request_t *r); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 95 | static void ngx_http_proxy_abort_request(ngx_http_request_t *r); |
| 96 | static void ngx_http_proxy_finalize_request(ngx_http_request_t *r, |
| 97 | ngx_int_t rc); |
| 98 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 99 | static ngx_int_t ngx_http_proxy_host_variable(ngx_http_request_t *r, |
| 100 | ngx_http_variable_value_t *v, uintptr_t data); |
| 101 | static ngx_int_t ngx_http_proxy_port_variable(ngx_http_request_t *r, |
| 102 | ngx_http_variable_value_t *v, uintptr_t data); |
| 103 | static ngx_int_t |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 104 | ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r, |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 105 | ngx_http_variable_value_t *v, uintptr_t data); |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 106 | static ngx_int_t |
| 107 | ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r, |
| 108 | ngx_http_variable_value_t *v, uintptr_t data); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 109 | static ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, |
| 110 | ngx_table_elt_t *h, size_t prefix); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 111 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 112 | static ngx_int_t ngx_http_proxy_add_variables(ngx_conf_t *cf); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 113 | static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); |
| 114 | static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, |
| 115 | void *parent, void *child); |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 116 | static ngx_int_t ngx_http_proxy_merge_headers(ngx_conf_t *cf, |
| 117 | ngx_http_proxy_loc_conf_t *conf, ngx_http_proxy_loc_conf_t *prev); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 118 | |
| 119 | static char *ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, |
| 120 | void *conf); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 121 | static char *ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 122 | void *conf); |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 123 | static char *ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, |
| 124 | void *conf); |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 125 | #if (NGX_HTTP_CACHE) |
| 126 | static char *ngx_http_proxy_cache(ngx_conf_t *cf, ngx_command_t *cmd, |
| 127 | void *conf); |
Igor Sysoev | 44a69c8 | 2009-04-06 08:58:44 +0000 | [diff] [blame] | 128 | static char *ngx_http_proxy_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, |
| 129 | void *conf); |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 130 | #endif |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 131 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 132 | static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data); |
| 133 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 134 | #if (NGX_HTTP_SSL) |
| 135 | static ngx_int_t ngx_http_proxy_set_ssl(ngx_conf_t *cf, |
| 136 | ngx_http_proxy_loc_conf_t *plcf); |
| 137 | #endif |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 138 | static void ngx_http_proxy_set_vars(ngx_url_t *u, ngx_http_proxy_vars_t *v); |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 139 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 140 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 141 | static ngx_conf_post_t ngx_http_proxy_lowat_post = |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 142 | { ngx_http_proxy_lowat_check }; |
| 143 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 144 | |
| 145 | static ngx_conf_bitmask_t ngx_http_proxy_next_upstream_masks[] = { |
| 146 | { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR }, |
| 147 | { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT }, |
| 148 | { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER }, |
| 149 | { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 }, |
Igor Sysoev | 797c6ef | 2008-09-30 15:39:02 +0000 | [diff] [blame] | 150 | { ngx_string("http_502"), NGX_HTTP_UPSTREAM_FT_HTTP_502 }, |
Igor Sysoev | 8fea885 | 2006-03-15 09:53:04 +0000 | [diff] [blame] | 151 | { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 }, |
Igor Sysoev | 797c6ef | 2008-09-30 15:39:02 +0000 | [diff] [blame] | 152 | { ngx_string("http_504"), NGX_HTTP_UPSTREAM_FT_HTTP_504 }, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 153 | { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, |
Igor Sysoev | 55192e7 | 2009-06-06 18:49:47 +0000 | [diff] [blame] | 154 | { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING }, |
Igor Sysoev | bb28b6d | 2006-07-11 13:20:19 +0000 | [diff] [blame] | 155 | { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 156 | { ngx_null_string, 0 } |
| 157 | }; |
| 158 | |
| 159 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 160 | ngx_module_t ngx_http_proxy_module; |
| 161 | |
| 162 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 163 | static ngx_command_t ngx_http_proxy_commands[] = { |
| 164 | |
| 165 | { ngx_string("proxy_pass"), |
Igor Sysoev | e927b1e | 2006-11-14 12:43:14 +0000 | [diff] [blame] | 166 | NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 167 | ngx_http_proxy_pass, |
| 168 | NGX_HTTP_LOC_CONF_OFFSET, |
| 169 | 0, |
| 170 | NULL }, |
| 171 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 172 | { ngx_string("proxy_redirect"), |
| 173 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, |
| 174 | ngx_http_proxy_redirect, |
| 175 | NGX_HTTP_LOC_CONF_OFFSET, |
| 176 | 0, |
| 177 | NULL }, |
| 178 | |
Igor Sysoev | 58feb53 | 2007-07-12 11:19:05 +0000 | [diff] [blame] | 179 | { ngx_string("proxy_store"), |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 180 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 181 | ngx_http_proxy_store, |
| 182 | NGX_HTTP_LOC_CONF_OFFSET, |
| 183 | 0, |
| 184 | NULL }, |
| 185 | |
| 186 | { ngx_string("proxy_store_access"), |
Igor Sysoev | 58feb53 | 2007-07-12 11:19:05 +0000 | [diff] [blame] | 187 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123, |
| 188 | ngx_conf_set_access_slot, |
| 189 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 190 | offsetof(ngx_http_proxy_loc_conf_t, upstream.store_access), |
Igor Sysoev | 58feb53 | 2007-07-12 11:19:05 +0000 | [diff] [blame] | 191 | NULL }, |
| 192 | |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 193 | { ngx_string("proxy_buffering"), |
| 194 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 195 | ngx_conf_set_flag_slot, |
| 196 | NGX_HTTP_LOC_CONF_OFFSET, |
| 197 | offsetof(ngx_http_proxy_loc_conf_t, upstream.buffering), |
| 198 | NULL }, |
| 199 | |
Igor Sysoev | 6d16e1e | 2006-04-05 13:40:54 +0000 | [diff] [blame] | 200 | { ngx_string("proxy_ignore_client_abort"), |
| 201 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 202 | ngx_conf_set_flag_slot, |
| 203 | NGX_HTTP_LOC_CONF_OFFSET, |
| 204 | offsetof(ngx_http_proxy_loc_conf_t, upstream.ignore_client_abort), |
| 205 | NULL }, |
| 206 | |
Igor Sysoev | 72e9287 | 2009-11-02 15:24:02 +0000 | [diff] [blame] | 207 | { ngx_string("proxy_bind"), |
| 208 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
Igor Sysoev | bd375b9 | 2009-12-23 14:22:17 +0000 | [diff] [blame] | 209 | ngx_http_upstream_bind_set_slot, |
Igor Sysoev | 72e9287 | 2009-11-02 15:24:02 +0000 | [diff] [blame] | 210 | NGX_HTTP_LOC_CONF_OFFSET, |
| 211 | offsetof(ngx_http_proxy_loc_conf_t, upstream.local), |
| 212 | NULL }, |
| 213 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 214 | { ngx_string("proxy_connect_timeout"), |
| 215 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 216 | ngx_conf_set_msec_slot, |
| 217 | NGX_HTTP_LOC_CONF_OFFSET, |
| 218 | offsetof(ngx_http_proxy_loc_conf_t, upstream.connect_timeout), |
| 219 | NULL }, |
| 220 | |
| 221 | { ngx_string("proxy_send_timeout"), |
| 222 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 223 | ngx_conf_set_msec_slot, |
| 224 | NGX_HTTP_LOC_CONF_OFFSET, |
| 225 | offsetof(ngx_http_proxy_loc_conf_t, upstream.send_timeout), |
| 226 | NULL }, |
| 227 | |
| 228 | { ngx_string("proxy_send_lowat"), |
| 229 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 230 | ngx_conf_set_size_slot, |
| 231 | NGX_HTTP_LOC_CONF_OFFSET, |
| 232 | offsetof(ngx_http_proxy_loc_conf_t, upstream.send_lowat), |
| 233 | &ngx_http_proxy_lowat_post }, |
| 234 | |
Igor Sysoev | ef809b8 | 2006-06-28 16:00:26 +0000 | [diff] [blame] | 235 | { ngx_string("proxy_intercept_errors"), |
| 236 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 237 | ngx_conf_set_flag_slot, |
| 238 | NGX_HTTP_LOC_CONF_OFFSET, |
| 239 | offsetof(ngx_http_proxy_loc_conf_t, upstream.intercept_errors), |
| 240 | NULL }, |
| 241 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 242 | { ngx_string("proxy_set_header"), |
| 243 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 244 | ngx_conf_set_keyval_slot, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 245 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 246 | offsetof(ngx_http_proxy_loc_conf_t, headers_source), |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 247 | NULL }, |
| 248 | |
Igor Sysoev | 8a19bff | 2007-04-22 20:21:59 +0000 | [diff] [blame] | 249 | { ngx_string("proxy_headers_hash_max_size"), |
| 250 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 251 | ngx_conf_set_num_slot, |
| 252 | NGX_HTTP_LOC_CONF_OFFSET, |
| 253 | offsetof(ngx_http_proxy_loc_conf_t, headers_hash_max_size), |
| 254 | NULL }, |
| 255 | |
| 256 | { ngx_string("proxy_headers_hash_bucket_size"), |
| 257 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 258 | ngx_conf_set_num_slot, |
| 259 | NGX_HTTP_LOC_CONF_OFFSET, |
| 260 | offsetof(ngx_http_proxy_loc_conf_t, headers_hash_bucket_size), |
| 261 | NULL }, |
| 262 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 263 | { ngx_string("proxy_set_body"), |
| 264 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 265 | ngx_conf_set_str_slot, |
| 266 | NGX_HTTP_LOC_CONF_OFFSET, |
| 267 | offsetof(ngx_http_proxy_loc_conf_t, body_source), |
| 268 | NULL }, |
| 269 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 270 | { ngx_string("proxy_method"), |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 271 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 272 | ngx_conf_set_str_slot, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 273 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 274 | offsetof(ngx_http_proxy_loc_conf_t, method), |
| 275 | NULL }, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 276 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 277 | { ngx_string("proxy_pass_request_headers"), |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 278 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 279 | ngx_conf_set_flag_slot, |
| 280 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 281 | offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_request_headers), |
| 282 | NULL }, |
| 283 | |
| 284 | { ngx_string("proxy_pass_request_body"), |
| 285 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 286 | ngx_conf_set_flag_slot, |
| 287 | NGX_HTTP_LOC_CONF_OFFSET, |
| 288 | offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_request_body), |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 289 | NULL }, |
| 290 | |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 291 | { ngx_string("proxy_buffer_size"), |
| 292 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 293 | ngx_conf_set_size_slot, |
| 294 | NGX_HTTP_LOC_CONF_OFFSET, |
| 295 | offsetof(ngx_http_proxy_loc_conf_t, upstream.buffer_size), |
| 296 | NULL }, |
| 297 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 298 | { ngx_string("proxy_read_timeout"), |
| 299 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 300 | ngx_conf_set_msec_slot, |
| 301 | NGX_HTTP_LOC_CONF_OFFSET, |
| 302 | offsetof(ngx_http_proxy_loc_conf_t, upstream.read_timeout), |
| 303 | NULL }, |
| 304 | |
| 305 | { ngx_string("proxy_buffers"), |
| 306 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, |
| 307 | ngx_conf_set_bufs_slot, |
| 308 | NGX_HTTP_LOC_CONF_OFFSET, |
| 309 | offsetof(ngx_http_proxy_loc_conf_t, upstream.bufs), |
| 310 | NULL }, |
| 311 | |
| 312 | { ngx_string("proxy_busy_buffers_size"), |
| 313 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 314 | ngx_conf_set_size_slot, |
| 315 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 316 | offsetof(ngx_http_proxy_loc_conf_t, upstream.busy_buffers_size_conf), |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 317 | NULL }, |
| 318 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 319 | #if (NGX_HTTP_CACHE) |
| 320 | |
| 321 | { ngx_string("proxy_cache"), |
Igor Sysoev | 6d9d07b | 2010-08-02 12:47:52 +0000 | [diff] [blame] | 322 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 323 | ngx_http_proxy_cache, |
Igor Sysoev | 0ded9db | 2009-03-23 16:40:11 +0000 | [diff] [blame] | 324 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 64416aa | 2009-03-23 15:57:57 +0000 | [diff] [blame] | 325 | 0, |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 326 | NULL }, |
| 327 | |
Igor Sysoev | 44a69c8 | 2009-04-06 08:58:44 +0000 | [diff] [blame] | 328 | { ngx_string("proxy_cache_key"), |
Igor Sysoev | 6d9d07b | 2010-08-02 12:47:52 +0000 | [diff] [blame] | 329 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
Igor Sysoev | 44a69c8 | 2009-04-06 08:58:44 +0000 | [diff] [blame] | 330 | ngx_http_proxy_cache_key, |
| 331 | NGX_HTTP_LOC_CONF_OFFSET, |
| 332 | 0, |
| 333 | NULL }, |
| 334 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 335 | { ngx_string("proxy_cache_path"), |
| 336 | NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE, |
| 337 | ngx_http_file_cache_set_slot, |
| 338 | 0, |
| 339 | 0, |
| 340 | &ngx_http_proxy_module }, |
| 341 | |
Igor Sysoev | f7d659a | 2010-07-19 09:36:04 +0000 | [diff] [blame] | 342 | { ngx_string("proxy_cache_bypass"), |
| 343 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
| 344 | ngx_http_set_predicate_slot, |
| 345 | NGX_HTTP_LOC_CONF_OFFSET, |
| 346 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_bypass), |
| 347 | NULL }, |
| 348 | |
Igor Sysoev | 9b2763a | 2010-05-24 11:01:05 +0000 | [diff] [blame] | 349 | { ngx_string("proxy_no_cache"), |
| 350 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
Igor Sysoev | f3870c6 | 2010-07-14 11:15:45 +0000 | [diff] [blame] | 351 | ngx_http_set_predicate_slot, |
Igor Sysoev | 9b2763a | 2010-05-24 11:01:05 +0000 | [diff] [blame] | 352 | NGX_HTTP_LOC_CONF_OFFSET, |
| 353 | offsetof(ngx_http_proxy_loc_conf_t, upstream.no_cache), |
| 354 | NULL }, |
| 355 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 356 | { ngx_string("proxy_cache_valid"), |
| 357 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
| 358 | ngx_http_file_cache_valid_set_slot, |
| 359 | NGX_HTTP_LOC_CONF_OFFSET, |
| 360 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_valid), |
| 361 | NULL }, |
| 362 | |
| 363 | { ngx_string("proxy_cache_min_uses"), |
| 364 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 365 | ngx_conf_set_num_slot, |
| 366 | NGX_HTTP_LOC_CONF_OFFSET, |
| 367 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_min_uses), |
| 368 | NULL }, |
| 369 | |
| 370 | { ngx_string("proxy_cache_use_stale"), |
| 371 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
| 372 | ngx_conf_set_bitmask_slot, |
| 373 | NGX_HTTP_LOC_CONF_OFFSET, |
| 374 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_use_stale), |
| 375 | &ngx_http_proxy_next_upstream_masks }, |
| 376 | |
Igor Sysoev | 5ed3691 | 2009-05-19 13:27:27 +0000 | [diff] [blame] | 377 | { ngx_string("proxy_cache_methods"), |
| 378 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
| 379 | ngx_conf_set_bitmask_slot, |
| 380 | NGX_HTTP_LOC_CONF_OFFSET, |
| 381 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_methods), |
| 382 | &ngx_http_upstream_cache_method_mask }, |
| 383 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 384 | #endif |
| 385 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 386 | { ngx_string("proxy_temp_path"), |
| 387 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234, |
| 388 | ngx_conf_set_path_slot, |
| 389 | NGX_HTTP_LOC_CONF_OFFSET, |
| 390 | offsetof(ngx_http_proxy_loc_conf_t, upstream.temp_path), |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 391 | NULL }, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 392 | |
| 393 | { ngx_string("proxy_max_temp_file_size"), |
| 394 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 395 | ngx_conf_set_size_slot, |
| 396 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 397 | offsetof(ngx_http_proxy_loc_conf_t, upstream.max_temp_file_size_conf), |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 398 | NULL }, |
| 399 | |
| 400 | { ngx_string("proxy_temp_file_write_size"), |
| 401 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 402 | ngx_conf_set_size_slot, |
| 403 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 404 | offsetof(ngx_http_proxy_loc_conf_t, upstream.temp_file_write_size_conf), |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 405 | NULL }, |
| 406 | |
| 407 | { ngx_string("proxy_next_upstream"), |
Igor Sysoev | 9fa5a82 | 2005-09-30 14:41:25 +0000 | [diff] [blame] | 408 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 409 | ngx_conf_set_bitmask_slot, |
| 410 | NGX_HTTP_LOC_CONF_OFFSET, |
| 411 | offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream), |
| 412 | &ngx_http_proxy_next_upstream_masks }, |
| 413 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 414 | { ngx_string("proxy_pass_header"), |
Igor Sysoev | 6d9d07b | 2010-08-02 12:47:52 +0000 | [diff] [blame] | 415 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 416 | ngx_conf_set_str_array_slot, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 417 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 418 | offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_headers), |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 419 | NULL }, |
| 420 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 421 | { ngx_string("proxy_hide_header"), |
Igor Sysoev | 6d9d07b | 2010-08-02 12:47:52 +0000 | [diff] [blame] | 422 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 423 | ngx_conf_set_str_array_slot, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 424 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 425 | offsetof(ngx_http_proxy_loc_conf_t, upstream.hide_headers), |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 426 | NULL }, |
| 427 | |
Igor Sysoev | b01c9cc | 2009-04-30 16:15:07 +0000 | [diff] [blame] | 428 | { ngx_string("proxy_ignore_headers"), |
| 429 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
| 430 | ngx_conf_set_bitmask_slot, |
| 431 | NGX_HTTP_LOC_CONF_OFFSET, |
| 432 | offsetof(ngx_http_proxy_loc_conf_t, upstream.ignore_headers), |
Igor Sysoev | 7e14b50 | 2010-07-02 09:25:38 +0000 | [diff] [blame] | 433 | &ngx_http_upstream_ignore_headers_masks }, |
Igor Sysoev | b01c9cc | 2009-04-30 16:15:07 +0000 | [diff] [blame] | 434 | |
Igor Sysoev | 916ee8e | 2008-08-17 17:47:52 +0000 | [diff] [blame] | 435 | #if (NGX_HTTP_SSL) |
| 436 | |
| 437 | { ngx_string("proxy_ssl_session_reuse"), |
| 438 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 439 | ngx_conf_set_flag_slot, |
| 440 | NGX_HTTP_LOC_CONF_OFFSET, |
| 441 | offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_session_reuse), |
| 442 | NULL }, |
| 443 | |
| 444 | #endif |
| 445 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 446 | ngx_null_command |
| 447 | }; |
| 448 | |
| 449 | |
Igor Sysoev | 8f12558 | 2006-07-28 15:16:17 +0000 | [diff] [blame] | 450 | static ngx_http_module_t ngx_http_proxy_module_ctx = { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 451 | ngx_http_proxy_add_variables, /* preconfiguration */ |
| 452 | NULL, /* postconfiguration */ |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 453 | |
| 454 | NULL, /* create main configuration */ |
| 455 | NULL, /* init main configuration */ |
| 456 | |
| 457 | NULL, /* create server configuration */ |
| 458 | NULL, /* merge server configuration */ |
| 459 | |
| 460 | ngx_http_proxy_create_loc_conf, /* create location configration */ |
| 461 | ngx_http_proxy_merge_loc_conf /* merge location configration */ |
| 462 | }; |
| 463 | |
| 464 | |
| 465 | ngx_module_t ngx_http_proxy_module = { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 466 | NGX_MODULE_V1, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 467 | &ngx_http_proxy_module_ctx, /* module context */ |
| 468 | ngx_http_proxy_commands, /* module directives */ |
| 469 | NGX_HTTP_MODULE, /* module type */ |
Igor Sysoev | e573380 | 2005-09-08 14:36:09 +0000 | [diff] [blame] | 470 | NULL, /* init master */ |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 471 | NULL, /* init module */ |
Igor Sysoev | e573380 | 2005-09-08 14:36:09 +0000 | [diff] [blame] | 472 | NULL, /* init process */ |
| 473 | NULL, /* init thread */ |
| 474 | NULL, /* exit thread */ |
| 475 | NULL, /* exit process */ |
| 476 | NULL, /* exit master */ |
| 477 | NGX_MODULE_V1_PADDING |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 478 | }; |
| 479 | |
| 480 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 481 | static char ngx_http_proxy_version[] = " HTTP/1.0" CRLF; |
| 482 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 483 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 484 | static ngx_keyval_t ngx_http_proxy_headers[] = { |
| 485 | { ngx_string("Host"), ngx_string("$proxy_host") }, |
| 486 | { ngx_string("Connection"), ngx_string("close") }, |
| 487 | { ngx_string("Keep-Alive"), ngx_string("") }, |
Igor Sysoev | 1e1f4c8 | 2008-06-26 13:00:39 +0000 | [diff] [blame] | 488 | { ngx_string("Expect"), ngx_string("") }, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 489 | { ngx_null_string, ngx_null_string } |
| 490 | }; |
| 491 | |
| 492 | |
Igor Sysoev | 2b89d20 | 2009-04-15 11:42:49 +0000 | [diff] [blame] | 493 | static ngx_str_t ngx_http_proxy_hide_headers[] = { |
| 494 | ngx_string("Date"), |
| 495 | ngx_string("Server"), |
| 496 | ngx_string("X-Pad"), |
| 497 | ngx_string("X-Accel-Expires"), |
| 498 | ngx_string("X-Accel-Redirect"), |
| 499 | ngx_string("X-Accel-Limit-Rate"), |
| 500 | ngx_string("X-Accel-Buffering"), |
| 501 | ngx_string("X-Accel-Charset"), |
| 502 | ngx_null_string |
| 503 | }; |
| 504 | |
| 505 | |
Igor Sysoev | 081662a | 2009-04-15 11:21:12 +0000 | [diff] [blame] | 506 | #if (NGX_HTTP_CACHE) |
| 507 | |
| 508 | static ngx_keyval_t ngx_http_proxy_cache_headers[] = { |
| 509 | { ngx_string("Host"), ngx_string("$proxy_host") }, |
| 510 | { ngx_string("Connection"), ngx_string("close") }, |
| 511 | { ngx_string("Keep-Alive"), ngx_string("") }, |
| 512 | { ngx_string("Expect"), ngx_string("") }, |
| 513 | { ngx_string("If-Modified-Since"), ngx_string("") }, |
| 514 | { ngx_string("If-Unmodified-Since"), ngx_string("") }, |
Igor Sysoev | c7c0d61 | 2009-12-22 16:41:34 +0000 | [diff] [blame] | 515 | { ngx_string("If-None-Match"), ngx_string("") }, |
Igor Sysoev | 081662a | 2009-04-15 11:21:12 +0000 | [diff] [blame] | 516 | { ngx_string("If-Match"), ngx_string("") }, |
| 517 | { ngx_string("Range"), ngx_string("") }, |
| 518 | { ngx_string("If-Range"), ngx_string("") }, |
| 519 | { ngx_null_string, ngx_null_string } |
| 520 | }; |
| 521 | |
Igor Sysoev | 2b89d20 | 2009-04-15 11:42:49 +0000 | [diff] [blame] | 522 | #endif |
| 523 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 524 | |
| 525 | static ngx_http_variable_t ngx_http_proxy_vars[] = { |
| 526 | |
Igor Sysoev | 7bdb720 | 2006-04-19 15:30:56 +0000 | [diff] [blame] | 527 | { ngx_string("proxy_host"), NULL, ngx_http_proxy_host_variable, 0, |
Igor Sysoev | 2061259 | 2008-03-11 14:10:11 +0000 | [diff] [blame] | 528 | NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 }, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 529 | |
Igor Sysoev | 7bdb720 | 2006-04-19 15:30:56 +0000 | [diff] [blame] | 530 | { ngx_string("proxy_port"), NULL, ngx_http_proxy_port_variable, 0, |
Igor Sysoev | 2061259 | 2008-03-11 14:10:11 +0000 | [diff] [blame] | 531 | NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 }, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 532 | |
Igor Sysoev | 7bdb720 | 2006-04-19 15:30:56 +0000 | [diff] [blame] | 533 | { ngx_string("proxy_add_x_forwarded_for"), NULL, |
Igor Sysoev | d3283ff | 2005-12-05 13:18:09 +0000 | [diff] [blame] | 534 | ngx_http_proxy_add_x_forwarded_for_variable, 0, NGX_HTTP_VAR_NOHASH, 0 }, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 535 | |
| 536 | #if 0 |
Igor Sysoev | 7bdb720 | 2006-04-19 15:30:56 +0000 | [diff] [blame] | 537 | { ngx_string("proxy_add_via"), NULL, NULL, 0, NGX_HTTP_VAR_NOHASH, 0 }, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 538 | #endif |
| 539 | |
Igor Sysoev | 7bdb720 | 2006-04-19 15:30:56 +0000 | [diff] [blame] | 540 | { ngx_string("proxy_internal_body_length"), NULL, |
Igor Sysoev | d3283ff | 2005-12-05 13:18:09 +0000 | [diff] [blame] | 541 | ngx_http_proxy_internal_body_length_variable, 0, NGX_HTTP_VAR_NOHASH, 0 }, |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 542 | |
Igor Sysoev | 7bdb720 | 2006-04-19 15:30:56 +0000 | [diff] [blame] | 543 | { ngx_null_string, NULL, NULL, 0, 0, 0 } |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 544 | }; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 545 | |
| 546 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 547 | static ngx_path_init_t ngx_http_proxy_temp_path = { |
| 548 | ngx_string(NGX_HTTP_PROXY_TEMP_PATH), { 1, 2, 0 } |
| 549 | }; |
| 550 | |
| 551 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 552 | static ngx_int_t |
| 553 | ngx_http_proxy_handler(ngx_http_request_t *r) |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 554 | { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 555 | ngx_int_t rc; |
| 556 | ngx_http_upstream_t *u; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 557 | ngx_http_proxy_ctx_t *ctx; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 558 | ngx_http_proxy_loc_conf_t *plcf; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 559 | |
Igor Sysoev | 15b7420 | 2009-07-27 13:25:29 +0000 | [diff] [blame] | 560 | if (ngx_http_upstream_create(r) != NGX_OK) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 561 | return NGX_HTTP_INTERNAL_SERVER_ERROR; |
| 562 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 563 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 564 | ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_ctx_t)); |
| 565 | if (ctx == NULL) { |
| 566 | return NGX_ERROR; |
| 567 | } |
| 568 | |
| 569 | ngx_http_set_ctx(r, ctx, ngx_http_proxy_module); |
| 570 | |
| 571 | plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); |
| 572 | |
Igor Sysoev | 15b7420 | 2009-07-27 13:25:29 +0000 | [diff] [blame] | 573 | u = r->upstream; |
| 574 | |
Igor Sysoev | e4994fb | 2010-08-03 12:53:06 +0000 | [diff] [blame] | 575 | if (plcf->proxy_lengths == NULL) { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 576 | ctx->vars = plcf->vars; |
Igor Sysoev | 73c3121 | 2008-12-10 14:44:48 +0000 | [diff] [blame] | 577 | u->schema = plcf->vars.schema; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 578 | #if (NGX_HTTP_SSL) |
| 579 | u->ssl = (plcf->upstream.ssl != NULL); |
| 580 | #endif |
| 581 | |
| 582 | } else { |
| 583 | if (ngx_http_proxy_eval(r, ctx, plcf) != NGX_OK) { |
| 584 | return NGX_HTTP_INTERNAL_SERVER_ERROR; |
| 585 | } |
| 586 | } |
| 587 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 588 | u->output.tag = (ngx_buf_tag_t) &ngx_http_proxy_module; |
| 589 | |
| 590 | u->conf = &plcf->upstream; |
| 591 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 592 | #if (NGX_HTTP_CACHE) |
| 593 | u->create_key = ngx_http_proxy_create_key; |
| 594 | #endif |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 595 | u->create_request = ngx_http_proxy_create_request; |
| 596 | u->reinit_request = ngx_http_proxy_reinit_request; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 597 | u->process_header = ngx_http_proxy_process_status_line; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 598 | u->abort_request = ngx_http_proxy_abort_request; |
| 599 | u->finalize_request = ngx_http_proxy_finalize_request; |
Igor Sysoev | aed1ac1 | 2010-03-25 13:27:52 +0000 | [diff] [blame] | 600 | r->state = 0; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 601 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 602 | if (plcf->redirects) { |
| 603 | u->rewrite_redirect = ngx_http_proxy_rewrite_redirect; |
| 604 | } |
| 605 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 606 | u->buffering = plcf->upstream.buffering; |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 607 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 608 | u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); |
| 609 | if (u->pipe == NULL) { |
| 610 | return NGX_HTTP_INTERNAL_SERVER_ERROR; |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 611 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 612 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 613 | u->pipe->input_filter = ngx_event_pipe_copy_input_filter; |
| 614 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 615 | u->accel = 1; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 616 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 617 | rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); |
| 618 | |
| 619 | if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { |
| 620 | return rc; |
| 621 | } |
| 622 | |
| 623 | return NGX_DONE; |
| 624 | } |
| 625 | |
| 626 | |
| 627 | static ngx_int_t |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 628 | ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx, |
| 629 | ngx_http_proxy_loc_conf_t *plcf) |
| 630 | { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 631 | u_char *p; |
| 632 | size_t add; |
| 633 | u_short port; |
| 634 | ngx_str_t proxy; |
| 635 | ngx_url_t url; |
| 636 | ngx_http_upstream_t *u; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 637 | |
| 638 | if (ngx_http_script_run(r, &proxy, plcf->proxy_lengths->elts, 0, |
| 639 | plcf->proxy_values->elts) |
| 640 | == NULL) |
| 641 | { |
| 642 | return NGX_ERROR; |
| 643 | } |
| 644 | |
| 645 | if (ngx_strncasecmp(proxy.data, (u_char *) "http://", 7) == 0) { |
| 646 | |
| 647 | add = 7; |
| 648 | port = 80; |
| 649 | |
| 650 | #if (NGX_HTTP_SSL) |
| 651 | |
| 652 | } else if (ngx_strncasecmp(proxy.data, (u_char *) "https://", 8) == 0) { |
| 653 | |
| 654 | add = 8; |
| 655 | port = 443; |
| 656 | r->upstream->ssl = 1; |
| 657 | |
| 658 | #endif |
| 659 | |
| 660 | } else { |
| 661 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
| 662 | "invalid URL prefix in \"%V\"", &proxy); |
| 663 | return NGX_ERROR; |
| 664 | } |
| 665 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 666 | u = r->upstream; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 667 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 668 | u->schema.len = add; |
| 669 | u->schema.data = proxy.data; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 670 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 671 | ngx_memzero(&url, sizeof(ngx_url_t)); |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 672 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 673 | url.url.len = proxy.len - add; |
| 674 | url.url.data = proxy.data + add; |
| 675 | url.default_port = port; |
| 676 | url.uri_part = 1; |
| 677 | url.no_resolve = 1; |
| 678 | |
| 679 | if (ngx_parse_url(r->pool, &url) != NGX_OK) { |
| 680 | if (url.err) { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 681 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 682 | "%s in upstream \"%V\"", url.err, &url.url); |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 683 | } |
| 684 | |
| 685 | return NGX_ERROR; |
| 686 | } |
| 687 | |
Igor Sysoev | 6c71b88 | 2009-11-15 11:36:12 +0000 | [diff] [blame] | 688 | if (url.uri.len) { |
| 689 | if (url.uri.data[0] == '?') { |
| 690 | p = ngx_pnalloc(r->pool, url.uri.len + 1); |
| 691 | if (p == NULL) { |
| 692 | return NGX_ERROR; |
| 693 | } |
| 694 | |
| 695 | *p++ = '/'; |
| 696 | ngx_memcpy(p, url.uri.data, url.uri.len); |
| 697 | |
| 698 | url.uri.len++; |
| 699 | url.uri.data = p - 1; |
Igor Sysoev | 164abfb | 2008-10-24 19:34:24 +0000 | [diff] [blame] | 700 | } |
| 701 | |
Igor Sysoev | 6c71b88 | 2009-11-15 11:36:12 +0000 | [diff] [blame] | 702 | } else { |
| 703 | url.uri = r->unparsed_uri; |
Igor Sysoev | 164abfb | 2008-10-24 19:34:24 +0000 | [diff] [blame] | 704 | } |
| 705 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 706 | ctx->vars.key_start = u->schema; |
| 707 | |
| 708 | ngx_http_proxy_set_vars(&url, &ctx->vars); |
| 709 | |
| 710 | u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t)); |
| 711 | if (u->resolved == NULL) { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 712 | return NGX_ERROR; |
| 713 | } |
| 714 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 715 | if (url.addrs && url.addrs[0].sockaddr) { |
| 716 | u->resolved->sockaddr = url.addrs[0].sockaddr; |
| 717 | u->resolved->socklen = url.addrs[0].socklen; |
| 718 | u->resolved->naddrs = 1; |
| 719 | u->resolved->host = url.addrs[0].name; |
Igor Sysoev | 302cedc | 2008-12-23 19:35:12 +0000 | [diff] [blame] | 720 | |
| 721 | } else { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 722 | u->resolved->host = url.host; |
| 723 | u->resolved->port = (in_port_t) (url.no_port ? port : url.port); |
| 724 | u->resolved->no_port = url.no_port; |
Igor Sysoev | 302cedc | 2008-12-23 19:35:12 +0000 | [diff] [blame] | 725 | } |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 726 | |
| 727 | return NGX_OK; |
| 728 | } |
| 729 | |
| 730 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 731 | #if (NGX_HTTP_CACHE) |
| 732 | |
| 733 | static ngx_int_t |
| 734 | ngx_http_proxy_create_key(ngx_http_request_t *r) |
| 735 | { |
| 736 | size_t len, loc_len; |
| 737 | u_char *p; |
| 738 | uintptr_t escape; |
| 739 | ngx_str_t *key; |
| 740 | ngx_http_upstream_t *u; |
| 741 | ngx_http_proxy_ctx_t *ctx; |
| 742 | ngx_http_proxy_loc_conf_t *plcf; |
| 743 | |
| 744 | u = r->upstream; |
| 745 | |
| 746 | plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); |
| 747 | |
| 748 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
| 749 | |
| 750 | key = ngx_array_push(&r->cache->keys); |
| 751 | if (key == NULL) { |
| 752 | return NGX_ERROR; |
| 753 | } |
| 754 | |
Igor Sysoev | 44a69c8 | 2009-04-06 08:58:44 +0000 | [diff] [blame] | 755 | if (plcf->cache_key.value.len) { |
| 756 | |
| 757 | if (ngx_http_complex_value(r, &plcf->cache_key, key) != NGX_OK) { |
| 758 | return NGX_ERROR; |
| 759 | } |
| 760 | |
| 761 | return NGX_OK; |
| 762 | } |
| 763 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 764 | *key = ctx->vars.key_start; |
| 765 | |
| 766 | key = ngx_array_push(&r->cache->keys); |
| 767 | if (key == NULL) { |
| 768 | return NGX_ERROR; |
| 769 | } |
| 770 | |
| 771 | if (plcf->proxy_lengths) { |
| 772 | |
| 773 | *key = ctx->vars.uri; |
| 774 | u->uri = ctx->vars.uri; |
| 775 | |
| 776 | return NGX_OK; |
| 777 | |
| 778 | } else if (ctx->vars.uri.len == 0 && r->valid_unparsed_uri && r == r->main) |
| 779 | { |
| 780 | *key = r->unparsed_uri; |
| 781 | u->uri = r->unparsed_uri; |
| 782 | |
| 783 | return NGX_OK; |
| 784 | } |
| 785 | |
| 786 | loc_len = (r->valid_location && ctx->vars.uri.len) ? plcf->location.len : 0; |
| 787 | |
| 788 | if (r->quoted_uri || r->internal) { |
| 789 | escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len, |
| 790 | r->uri.len - loc_len, NGX_ESCAPE_URI); |
| 791 | } else { |
| 792 | escape = 0; |
| 793 | } |
| 794 | |
| 795 | len = ctx->vars.uri.len + r->uri.len - loc_len + escape |
| 796 | + sizeof("?") - 1 + r->args.len; |
| 797 | |
| 798 | p = ngx_pnalloc(r->pool, len); |
| 799 | if (p == NULL) { |
| 800 | return NGX_ERROR; |
| 801 | } |
| 802 | |
| 803 | key->data = p; |
| 804 | |
| 805 | if (r->valid_location) { |
| 806 | p = ngx_copy(p, ctx->vars.uri.data, ctx->vars.uri.len); |
| 807 | } |
| 808 | |
| 809 | if (escape) { |
| 810 | ngx_escape_uri(p, r->uri.data + loc_len, |
| 811 | r->uri.len - loc_len, NGX_ESCAPE_URI); |
| 812 | p += r->uri.len - loc_len + escape; |
| 813 | |
| 814 | } else { |
| 815 | p = ngx_copy(p, r->uri.data + loc_len, r->uri.len - loc_len); |
| 816 | } |
| 817 | |
| 818 | if (r->args.len > 0) { |
| 819 | *p++ = '?'; |
| 820 | p = ngx_copy(p, r->args.data, r->args.len); |
| 821 | } |
| 822 | |
| 823 | key->len = p - key->data; |
| 824 | u->uri = *key; |
| 825 | |
| 826 | return NGX_OK; |
| 827 | } |
| 828 | |
| 829 | #endif |
| 830 | |
| 831 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 832 | static ngx_int_t |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 833 | ngx_http_proxy_create_request(ngx_http_request_t *r) |
| 834 | { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 835 | size_t len, uri_len, loc_len, body_len; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 836 | uintptr_t escape; |
| 837 | ngx_buf_t *b; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 838 | ngx_str_t method; |
| 839 | ngx_uint_t i, unparsed_uri; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 840 | ngx_chain_t *cl, *body; |
| 841 | ngx_list_part_t *part; |
| 842 | ngx_table_elt_t *header; |
| 843 | ngx_http_upstream_t *u; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 844 | ngx_http_proxy_ctx_t *ctx; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 845 | ngx_http_script_code_pt code; |
| 846 | ngx_http_script_engine_t e, le; |
| 847 | ngx_http_proxy_loc_conf_t *plcf; |
| 848 | ngx_http_script_len_code_pt lcode; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 849 | |
| 850 | u = r->upstream; |
| 851 | |
| 852 | plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); |
| 853 | |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 854 | if (u->method.len) { |
| 855 | /* HEAD was changed to GET to cache response */ |
| 856 | method = u->method; |
| 857 | method.len++; |
| 858 | |
| 859 | } else if (plcf->method.len) { |
| 860 | method = plcf->method; |
| 861 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 862 | } else { |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 863 | method = r->method_name; |
| 864 | method.len++; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 865 | } |
| 866 | |
Igor Sysoev | fa62656 | 2007-11-28 15:06:05 +0000 | [diff] [blame] | 867 | len = method.len + sizeof(ngx_http_proxy_version) - 1 + sizeof(CRLF) - 1; |
| 868 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 869 | escape = 0; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 870 | loc_len = 0; |
| 871 | unparsed_uri = 0; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 872 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 873 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 874 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 875 | if (plcf->proxy_lengths) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 876 | uri_len = ctx->vars.uri.len; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 877 | |
| 878 | } else if (ctx->vars.uri.len == 0 && r->valid_unparsed_uri && r == r->main) |
| 879 | { |
Igor Sysoev | 8290d28 | 2006-02-03 12:58:48 +0000 | [diff] [blame] | 880 | unparsed_uri = 1; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 881 | uri_len = r->unparsed_uri.len; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 882 | |
| 883 | } else { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 884 | loc_len = (r->valid_location && ctx->vars.uri.len) ? |
| 885 | plcf->location.len : 0; |
| 886 | |
Igor Sysoev | da7b5e1 | 2010-06-15 09:31:19 +0000 | [diff] [blame] | 887 | if (r->quoted_uri || r->space_in_uri || r->internal) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 888 | escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len, |
| 889 | r->uri.len - loc_len, NGX_ESCAPE_URI); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 890 | } |
| 891 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 892 | uri_len = ctx->vars.uri.len + r->uri.len - loc_len + escape |
| 893 | + sizeof("?") - 1 + r->args.len; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 894 | } |
| 895 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 896 | if (uri_len == 0) { |
| 897 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
| 898 | "zero length URI to proxy"); |
| 899 | return NGX_ERROR; |
| 900 | } |
| 901 | |
| 902 | len += uri_len; |
| 903 | |
Igor Sysoev | 2d3f3f6 | 2007-10-14 18:56:15 +0000 | [diff] [blame] | 904 | ngx_http_script_flush_no_cacheable_variables(r, plcf->flushes); |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 905 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 906 | if (plcf->body_set_len) { |
| 907 | le.ip = plcf->body_set_len->elts; |
| 908 | le.request = r; |
| 909 | le.flushed = 1; |
| 910 | body_len = 0; |
| 911 | |
| 912 | while (*(uintptr_t *) le.ip) { |
| 913 | lcode = *(ngx_http_script_len_code_pt *) le.ip; |
| 914 | body_len += lcode(&le); |
| 915 | } |
| 916 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 917 | ctx->internal_body_length = body_len; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 918 | len += body_len; |
| 919 | } |
| 920 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 921 | le.ip = plcf->headers_set_len->elts; |
| 922 | le.request = r; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 923 | le.flushed = 1; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 924 | |
| 925 | while (*(uintptr_t *) le.ip) { |
| 926 | while (*(uintptr_t *) le.ip) { |
| 927 | lcode = *(ngx_http_script_len_code_pt *) le.ip; |
| 928 | len += lcode(&le); |
| 929 | } |
| 930 | le.ip += sizeof(uintptr_t); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 931 | } |
| 932 | |
| 933 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 934 | if (plcf->upstream.pass_request_headers) { |
| 935 | part = &r->headers_in.headers.part; |
| 936 | header = part->elts; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 937 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 938 | for (i = 0; /* void */; i++) { |
| 939 | |
| 940 | if (i >= part->nelts) { |
| 941 | if (part->next == NULL) { |
| 942 | break; |
| 943 | } |
| 944 | |
| 945 | part = part->next; |
| 946 | header = part->elts; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 947 | i = 0; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 948 | } |
| 949 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 950 | if (ngx_hash_find(&plcf->headers_set_hash, header[i].hash, |
| 951 | header[i].lowcase_key, header[i].key.len)) |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 952 | { |
| 953 | continue; |
| 954 | } |
| 955 | |
| 956 | len += header[i].key.len + sizeof(": ") - 1 |
| 957 | + header[i].value.len + sizeof(CRLF) - 1; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 958 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 959 | } |
| 960 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 961 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 962 | b = ngx_create_temp_buf(r->pool, len); |
| 963 | if (b == NULL) { |
| 964 | return NGX_ERROR; |
| 965 | } |
| 966 | |
| 967 | cl = ngx_alloc_chain_link(r->pool); |
| 968 | if (cl == NULL) { |
| 969 | return NGX_ERROR; |
| 970 | } |
| 971 | |
| 972 | cl->buf = b; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 973 | |
| 974 | |
| 975 | /* the request line */ |
| 976 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 977 | b->last = ngx_copy(b->last, method.data, method.len); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 978 | |
Igor Sysoev | a257367 | 2005-10-05 14:46:21 +0000 | [diff] [blame] | 979 | u->uri.data = b->last; |
| 980 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 981 | if (plcf->proxy_lengths) { |
| 982 | b->last = ngx_copy(b->last, ctx->vars.uri.data, ctx->vars.uri.len); |
| 983 | |
| 984 | } else if (unparsed_uri) { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 985 | b->last = ngx_copy(b->last, r->unparsed_uri.data, r->unparsed_uri.len); |
| 986 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 987 | } else { |
Igor Sysoev | a257367 | 2005-10-05 14:46:21 +0000 | [diff] [blame] | 988 | if (r->valid_location) { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 989 | b->last = ngx_copy(b->last, ctx->vars.uri.data, ctx->vars.uri.len); |
Igor Sysoev | a257367 | 2005-10-05 14:46:21 +0000 | [diff] [blame] | 990 | } |
Igor Sysoev | 82dc95e | 2005-10-03 12:53:14 +0000 | [diff] [blame] | 991 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 992 | if (escape) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 993 | ngx_escape_uri(b->last, r->uri.data + loc_len, |
| 994 | r->uri.len - loc_len, NGX_ESCAPE_URI); |
| 995 | b->last += r->uri.len - loc_len + escape; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 996 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 997 | } else { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 998 | b->last = ngx_copy(b->last, r->uri.data + loc_len, |
| 999 | r->uri.len - loc_len); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1000 | } |
| 1001 | |
| 1002 | if (r->args.len > 0) { |
| 1003 | *b->last++ = '?'; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1004 | b->last = ngx_copy(b->last, r->args.data, r->args.len); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1005 | } |
| 1006 | } |
| 1007 | |
Igor Sysoev | a257367 | 2005-10-05 14:46:21 +0000 | [diff] [blame] | 1008 | u->uri.len = b->last - u->uri.data; |
| 1009 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1010 | b->last = ngx_cpymem(b->last, ngx_http_proxy_version, |
| 1011 | sizeof(ngx_http_proxy_version) - 1); |
| 1012 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1013 | ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1014 | |
| 1015 | e.ip = plcf->headers_set->elts; |
| 1016 | e.pos = b->last; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1017 | e.request = r; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1018 | e.flushed = 1; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1019 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1020 | le.ip = plcf->headers_set_len->elts; |
| 1021 | |
| 1022 | while (*(uintptr_t *) le.ip) { |
| 1023 | lcode = *(ngx_http_script_len_code_pt *) le.ip; |
Igor Sysoev | e31e90b | 2005-05-19 13:25:22 +0000 | [diff] [blame] | 1024 | |
| 1025 | /* skip the header line name length */ |
| 1026 | (void) lcode(&le); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1027 | |
| 1028 | if (*(ngx_http_script_len_code_pt *) le.ip) { |
| 1029 | |
| 1030 | for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) { |
| 1031 | lcode = *(ngx_http_script_len_code_pt *) le.ip; |
| 1032 | } |
| 1033 | |
| 1034 | e.skip = (len == sizeof(CRLF) - 1) ? 1 : 0; |
| 1035 | |
| 1036 | } else { |
| 1037 | e.skip = 0; |
| 1038 | } |
| 1039 | |
| 1040 | le.ip += sizeof(uintptr_t); |
| 1041 | |
| 1042 | while (*(uintptr_t *) e.ip) { |
| 1043 | code = *(ngx_http_script_code_pt *) e.ip; |
| 1044 | code((ngx_http_script_engine_t *) &e); |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1045 | } |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1046 | e.ip += sizeof(uintptr_t); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1047 | } |
| 1048 | |
| 1049 | b->last = e.pos; |
| 1050 | |
| 1051 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1052 | if (plcf->upstream.pass_request_headers) { |
| 1053 | part = &r->headers_in.headers.part; |
| 1054 | header = part->elts; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1055 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1056 | for (i = 0; /* void */; i++) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1057 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1058 | if (i >= part->nelts) { |
| 1059 | if (part->next == NULL) { |
| 1060 | break; |
| 1061 | } |
| 1062 | |
| 1063 | part = part->next; |
| 1064 | header = part->elts; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1065 | i = 0; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1066 | } |
| 1067 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1068 | if (ngx_hash_find(&plcf->headers_set_hash, header[i].hash, |
| 1069 | header[i].lowcase_key, header[i].key.len)) |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1070 | { |
| 1071 | continue; |
| 1072 | } |
| 1073 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1074 | b->last = ngx_copy(b->last, header[i].key.data, header[i].key.len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1075 | |
| 1076 | *b->last++ = ':'; *b->last++ = ' '; |
| 1077 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1078 | b->last = ngx_copy(b->last, header[i].value.data, |
| 1079 | header[i].value.len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1080 | |
| 1081 | *b->last++ = CR; *b->last++ = LF; |
| 1082 | |
| 1083 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 1084 | "http proxy header: \"%V: %V\"", |
| 1085 | &header[i].key, &header[i].value); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1086 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1087 | } |
| 1088 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1089 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1090 | /* add "\r\n" at the header end */ |
| 1091 | *b->last++ = CR; *b->last++ = LF; |
| 1092 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1093 | if (plcf->body_set) { |
| 1094 | e.ip = plcf->body_set->elts; |
| 1095 | e.pos = b->last; |
| 1096 | |
| 1097 | while (*(uintptr_t *) e.ip) { |
| 1098 | code = *(ngx_http_script_code_pt *) e.ip; |
| 1099 | code((ngx_http_script_engine_t *) &e); |
| 1100 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1101 | |
Igor Sysoev | b141f2b | 2005-11-15 14:49:57 +0000 | [diff] [blame] | 1102 | b->last = e.pos; |
| 1103 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1104 | |
Igor Sysoev | d02661a | 2007-12-24 17:05:31 +0000 | [diff] [blame] | 1105 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 1106 | "http proxy header:\n\"%*s\"", |
| 1107 | (size_t) (b->last - b->pos), b->pos); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1108 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1109 | if (plcf->body_set == NULL && plcf->upstream.pass_request_body) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1110 | |
| 1111 | body = u->request_bufs; |
| 1112 | u->request_bufs = cl; |
| 1113 | |
| 1114 | while (body) { |
| 1115 | b = ngx_alloc_buf(r->pool); |
| 1116 | if (b == NULL) { |
| 1117 | return NGX_ERROR; |
| 1118 | } |
| 1119 | |
| 1120 | ngx_memcpy(b, body->buf, sizeof(ngx_buf_t)); |
| 1121 | |
| 1122 | cl->next = ngx_alloc_chain_link(r->pool); |
| 1123 | if (cl->next == NULL) { |
| 1124 | return NGX_ERROR; |
| 1125 | } |
| 1126 | |
| 1127 | cl = cl->next; |
| 1128 | cl->buf = b; |
| 1129 | |
| 1130 | body = body->next; |
| 1131 | } |
| 1132 | |
Igor Sysoev | ffe7144 | 2006-02-08 15:33:12 +0000 | [diff] [blame] | 1133 | b->flush = 1; |
| 1134 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1135 | } else { |
| 1136 | u->request_bufs = cl; |
| 1137 | } |
| 1138 | |
| 1139 | cl->next = NULL; |
| 1140 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1141 | return NGX_OK; |
| 1142 | } |
| 1143 | |
| 1144 | |
| 1145 | static ngx_int_t |
| 1146 | ngx_http_proxy_reinit_request(ngx_http_request_t *r) |
| 1147 | { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1148 | ngx_http_proxy_ctx_t *ctx; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1149 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1150 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1151 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1152 | if (ctx == NULL) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1153 | return NGX_OK; |
| 1154 | } |
| 1155 | |
Igor Sysoev | 54b35b0 | 2010-06-15 15:15:06 +0000 | [diff] [blame] | 1156 | ctx->status.code = 0; |
| 1157 | ctx->status.count = 0; |
| 1158 | ctx->status.start = NULL; |
| 1159 | ctx->status.end = NULL; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1160 | |
| 1161 | r->upstream->process_header = ngx_http_proxy_process_status_line; |
Igor Sysoev | aed1ac1 | 2010-03-25 13:27:52 +0000 | [diff] [blame] | 1162 | r->state = 0; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1163 | |
| 1164 | return NGX_OK; |
| 1165 | } |
| 1166 | |
| 1167 | |
| 1168 | static ngx_int_t |
| 1169 | ngx_http_proxy_process_status_line(ngx_http_request_t *r) |
| 1170 | { |
Igor Sysoev | 1cc1b31 | 2010-06-15 15:21:37 +0000 | [diff] [blame] | 1171 | size_t len; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1172 | ngx_int_t rc; |
| 1173 | ngx_http_upstream_t *u; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1174 | ngx_http_proxy_ctx_t *ctx; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1175 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1176 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1177 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1178 | if (ctx == NULL) { |
Igor Sysoev | 5a55d71 | 2007-12-09 08:22:35 +0000 | [diff] [blame] | 1179 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1180 | } |
| 1181 | |
Igor Sysoev | 54b35b0 | 2010-06-15 15:15:06 +0000 | [diff] [blame] | 1182 | u = r->upstream; |
| 1183 | |
| 1184 | rc = ngx_http_parse_status_line(r, &u->buffer, &ctx->status); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1185 | |
| 1186 | if (rc == NGX_AGAIN) { |
| 1187 | return rc; |
| 1188 | } |
| 1189 | |
Igor Sysoev | 54b35b0 | 2010-06-15 15:15:06 +0000 | [diff] [blame] | 1190 | if (rc == NGX_ERROR) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1191 | |
| 1192 | #if (NGX_HTTP_CACHE) |
| 1193 | |
| 1194 | if (r->cache) { |
| 1195 | r->http_version = NGX_HTTP_VERSION_9; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1196 | return NGX_OK; |
| 1197 | } |
| 1198 | |
| 1199 | #endif |
| 1200 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1201 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1202 | "upstream sent no valid HTTP/1.0 header"); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1203 | |
Igor Sysoev | 13c6874 | 2006-03-10 12:51:52 +0000 | [diff] [blame] | 1204 | #if 0 |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1205 | if (u->accel) { |
| 1206 | return NGX_HTTP_UPSTREAM_INVALID_HEADER; |
| 1207 | } |
Igor Sysoev | 13c6874 | 2006-03-10 12:51:52 +0000 | [diff] [blame] | 1208 | #endif |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1209 | |
| 1210 | r->http_version = NGX_HTTP_VERSION_9; |
Igor Sysoev | d7cf1a6 | 2007-11-06 15:01:13 +0000 | [diff] [blame] | 1211 | u->state->status = NGX_HTTP_OK; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1212 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1213 | return NGX_OK; |
| 1214 | } |
| 1215 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1216 | if (u->state) { |
Igor Sysoev | 54b35b0 | 2010-06-15 15:15:06 +0000 | [diff] [blame] | 1217 | u->state->status = ctx->status.code; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1218 | } |
| 1219 | |
Igor Sysoev | 54b35b0 | 2010-06-15 15:15:06 +0000 | [diff] [blame] | 1220 | u->headers_in.status_n = ctx->status.code; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1221 | |
Igor Sysoev | 1cc1b31 | 2010-06-15 15:21:37 +0000 | [diff] [blame] | 1222 | len = ctx->status.end - ctx->status.start; |
| 1223 | u->headers_in.status_line.len = len; |
| 1224 | |
| 1225 | u->headers_in.status_line.data = ngx_pnalloc(r->pool, len); |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1226 | if (u->headers_in.status_line.data == NULL) { |
Igor Sysoev | 5a55d71 | 2007-12-09 08:22:35 +0000 | [diff] [blame] | 1227 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1228 | } |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1229 | |
Igor Sysoev | 1cc1b31 | 2010-06-15 15:21:37 +0000 | [diff] [blame] | 1230 | ngx_memcpy(u->headers_in.status_line.data, ctx->status.start, len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1231 | |
| 1232 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 1233 | "http proxy status %ui \"%V\"", |
Igor Sysoev | 4e08b9c | 2006-12-20 19:38:06 +0000 | [diff] [blame] | 1234 | u->headers_in.status_n, &u->headers_in.status_line); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1235 | |
| 1236 | u->process_header = ngx_http_proxy_process_header; |
| 1237 | |
| 1238 | return ngx_http_proxy_process_header(r); |
| 1239 | } |
| 1240 | |
| 1241 | |
| 1242 | static ngx_int_t |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1243 | ngx_http_proxy_process_header(ngx_http_request_t *r) |
| 1244 | { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1245 | ngx_int_t rc; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1246 | ngx_table_elt_t *h; |
| 1247 | ngx_http_upstream_header_t *hh; |
| 1248 | ngx_http_upstream_main_conf_t *umcf; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1249 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1250 | umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1251 | |
Igor Sysoev | 3b30476 | 2008-05-22 12:09:41 +0000 | [diff] [blame] | 1252 | for ( ;; ) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1253 | |
Igor Sysoev | 753792e | 2008-09-24 14:02:50 +0000 | [diff] [blame] | 1254 | rc = ngx_http_parse_header_line(r, &r->upstream->buffer, 1); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1255 | |
| 1256 | if (rc == NGX_OK) { |
| 1257 | |
| 1258 | /* a header line has been parsed successfully */ |
| 1259 | |
| 1260 | h = ngx_list_push(&r->upstream->headers_in.headers); |
| 1261 | if (h == NULL) { |
Igor Sysoev | 5a55d71 | 2007-12-09 08:22:35 +0000 | [diff] [blame] | 1262 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1263 | } |
| 1264 | |
| 1265 | h->hash = r->header_hash; |
| 1266 | |
| 1267 | h->key.len = r->header_name_end - r->header_name_start; |
| 1268 | h->value.len = r->header_end - r->header_start; |
| 1269 | |
Igor Sysoev | 7f6b2ff | 2008-06-17 15:00:30 +0000 | [diff] [blame] | 1270 | h->key.data = ngx_pnalloc(r->pool, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1271 | h->key.len + 1 + h->value.len + 1 + h->key.len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1272 | if (h->key.data == NULL) { |
Igor Sysoev | 5a55d71 | 2007-12-09 08:22:35 +0000 | [diff] [blame] | 1273 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1274 | } |
| 1275 | |
| 1276 | h->value.data = h->key.data + h->key.len + 1; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1277 | h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1278 | |
| 1279 | ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1); |
| 1280 | ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1); |
| 1281 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1282 | if (h->key.len == r->lowcase_index) { |
| 1283 | ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1284 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1285 | } else { |
Igor Sysoev | 777b019 | 2008-08-04 10:07:00 +0000 | [diff] [blame] | 1286 | ngx_strlow(h->lowcase_key, h->key.data, h->key.len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1287 | } |
| 1288 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1289 | hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, |
| 1290 | h->lowcase_key, h->key.len); |
| 1291 | |
| 1292 | if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { |
Igor Sysoev | 5a55d71 | 2007-12-09 08:22:35 +0000 | [diff] [blame] | 1293 | return NGX_ERROR; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1294 | } |
| 1295 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1296 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 1297 | "http proxy header: \"%V: %V\"", |
| 1298 | &h->key, &h->value); |
| 1299 | |
| 1300 | continue; |
| 1301 | } |
| 1302 | |
| 1303 | if (rc == NGX_HTTP_PARSE_HEADER_DONE) { |
| 1304 | |
| 1305 | /* a whole header has been parsed successfully */ |
| 1306 | |
| 1307 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 1308 | "http proxy header done"); |
| 1309 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1310 | /* |
| 1311 | * if no "Server" and "Date" in header line, |
| 1312 | * then add the special empty headers |
| 1313 | */ |
| 1314 | |
| 1315 | if (r->upstream->headers_in.server == NULL) { |
| 1316 | h = ngx_list_push(&r->upstream->headers_in.headers); |
| 1317 | if (h == NULL) { |
Igor Sysoev | 5a55d71 | 2007-12-09 08:22:35 +0000 | [diff] [blame] | 1318 | return NGX_ERROR; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1319 | } |
| 1320 | |
| 1321 | h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash( |
| 1322 | ngx_hash('s', 'e'), 'r'), 'v'), 'e'), 'r'); |
| 1323 | |
Igor Sysoev | 05b1a8f | 2010-05-14 09:56:37 +0000 | [diff] [blame] | 1324 | ngx_str_set(&h->key, "Server"); |
| 1325 | ngx_str_null(&h->value); |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1326 | h->lowcase_key = (u_char *) "server"; |
| 1327 | } |
| 1328 | |
| 1329 | if (r->upstream->headers_in.date == NULL) { |
| 1330 | h = ngx_list_push(&r->upstream->headers_in.headers); |
| 1331 | if (h == NULL) { |
Igor Sysoev | 5a55d71 | 2007-12-09 08:22:35 +0000 | [diff] [blame] | 1332 | return NGX_ERROR; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1333 | } |
| 1334 | |
| 1335 | h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e'); |
| 1336 | |
Igor Sysoev | 05b1a8f | 2010-05-14 09:56:37 +0000 | [diff] [blame] | 1337 | ngx_str_set(&h->key, "Date"); |
| 1338 | ngx_str_null(&h->value); |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1339 | h->lowcase_key = (u_char *) "date"; |
| 1340 | } |
| 1341 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1342 | return NGX_OK; |
| 1343 | } |
| 1344 | |
Igor Sysoev | 7b190b4 | 2005-06-07 15:56:31 +0000 | [diff] [blame] | 1345 | if (rc == NGX_AGAIN) { |
| 1346 | return NGX_AGAIN; |
| 1347 | } |
| 1348 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1349 | /* there was error while a header line parsing */ |
| 1350 | |
| 1351 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
Igor Sysoev | 13c6874 | 2006-03-10 12:51:52 +0000 | [diff] [blame] | 1352 | "upstream sent invalid header"); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1353 | |
| 1354 | return NGX_HTTP_UPSTREAM_INVALID_HEADER; |
| 1355 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1356 | } |
| 1357 | |
| 1358 | |
| 1359 | static void |
| 1360 | ngx_http_proxy_abort_request(ngx_http_request_t *r) |
| 1361 | { |
| 1362 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 1363 | "abort http proxy request"); |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1364 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1365 | return; |
| 1366 | } |
| 1367 | |
| 1368 | |
| 1369 | static void |
| 1370 | ngx_http_proxy_finalize_request(ngx_http_request_t *r, ngx_int_t rc) |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1371 | { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1372 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 1373 | "finalize http proxy request"); |
| 1374 | |
| 1375 | return; |
| 1376 | } |
| 1377 | |
| 1378 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1379 | static ngx_int_t |
| 1380 | ngx_http_proxy_host_variable(ngx_http_request_t *r, |
| 1381 | ngx_http_variable_value_t *v, uintptr_t data) |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1382 | { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1383 | ngx_http_proxy_ctx_t *ctx; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1384 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1385 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1386 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1387 | if (ctx == NULL) { |
| 1388 | v->not_found = 1; |
| 1389 | return NGX_OK; |
| 1390 | } |
| 1391 | |
| 1392 | v->len = ctx->vars.host_header.len; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1393 | v->valid = 1; |
Igor Sysoev | 2d3f3f6 | 2007-10-14 18:56:15 +0000 | [diff] [blame] | 1394 | v->no_cacheable = 0; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1395 | v->not_found = 0; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1396 | v->data = ctx->vars.host_header.data; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1397 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1398 | return NGX_OK; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1399 | } |
| 1400 | |
| 1401 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1402 | static ngx_int_t |
| 1403 | ngx_http_proxy_port_variable(ngx_http_request_t *r, |
| 1404 | ngx_http_variable_value_t *v, uintptr_t data) |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1405 | { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1406 | ngx_http_proxy_ctx_t *ctx; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1407 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1408 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1409 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1410 | if (ctx == NULL) { |
| 1411 | v->not_found = 1; |
| 1412 | return NGX_OK; |
| 1413 | } |
| 1414 | |
| 1415 | v->len = ctx->vars.port.len; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1416 | v->valid = 1; |
Igor Sysoev | 2d3f3f6 | 2007-10-14 18:56:15 +0000 | [diff] [blame] | 1417 | v->no_cacheable = 0; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1418 | v->not_found = 0; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1419 | v->data = ctx->vars.port.data; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1420 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1421 | return NGX_OK; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1422 | } |
| 1423 | |
| 1424 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1425 | static ngx_int_t |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1426 | ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r, |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1427 | ngx_http_variable_value_t *v, uintptr_t data) |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1428 | { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1429 | u_char *p; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1430 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1431 | v->valid = 1; |
Igor Sysoev | 2d3f3f6 | 2007-10-14 18:56:15 +0000 | [diff] [blame] | 1432 | v->no_cacheable = 0; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1433 | v->not_found = 0; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1434 | |
| 1435 | if (r->headers_in.x_forwarded_for == NULL) { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1436 | v->len = r->connection->addr_text.len; |
| 1437 | v->data = r->connection->addr_text.data; |
| 1438 | return NGX_OK; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1439 | } |
| 1440 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1441 | v->len = r->headers_in.x_forwarded_for->value.len |
| 1442 | + sizeof(", ") - 1 + r->connection->addr_text.len; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1443 | |
Igor Sysoev | 7f6b2ff | 2008-06-17 15:00:30 +0000 | [diff] [blame] | 1444 | p = ngx_pnalloc(r->pool, v->len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1445 | if (p == NULL) { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1446 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1447 | } |
| 1448 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1449 | v->data = p; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1450 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1451 | p = ngx_copy(p, r->headers_in.x_forwarded_for->value.data, |
| 1452 | r->headers_in.x_forwarded_for->value.len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1453 | |
| 1454 | *p++ = ','; *p++ = ' '; |
| 1455 | |
| 1456 | ngx_memcpy(p, r->connection->addr_text.data, r->connection->addr_text.len); |
| 1457 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1458 | return NGX_OK; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1459 | } |
| 1460 | |
| 1461 | |
| 1462 | static ngx_int_t |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1463 | ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r, |
| 1464 | ngx_http_variable_value_t *v, uintptr_t data) |
| 1465 | { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1466 | ngx_http_proxy_ctx_t *ctx; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1467 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1468 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1469 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1470 | if (ctx == NULL) { |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1471 | v->not_found = 1; |
| 1472 | return NGX_OK; |
| 1473 | } |
| 1474 | |
| 1475 | v->valid = 1; |
Igor Sysoev | 2d3f3f6 | 2007-10-14 18:56:15 +0000 | [diff] [blame] | 1476 | v->no_cacheable = 0; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1477 | v->not_found = 0; |
| 1478 | |
Igor Sysoev | 7f6b2ff | 2008-06-17 15:00:30 +0000 | [diff] [blame] | 1479 | v->data = ngx_pnalloc(r->connection->pool, NGX_SIZE_T_LEN); |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1480 | |
| 1481 | if (v->data == NULL) { |
| 1482 | return NGX_ERROR; |
| 1483 | } |
| 1484 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1485 | v->len = ngx_sprintf(v->data, "%uz", ctx->internal_body_length) - v->data; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1486 | |
| 1487 | return NGX_OK; |
| 1488 | } |
| 1489 | |
| 1490 | |
| 1491 | static ngx_int_t |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1492 | ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, ngx_table_elt_t *h, |
| 1493 | size_t prefix) |
| 1494 | { |
| 1495 | ngx_int_t rc; |
| 1496 | ngx_uint_t i; |
| 1497 | ngx_http_proxy_loc_conf_t *plcf; |
| 1498 | ngx_http_proxy_redirect_t *pr; |
| 1499 | |
| 1500 | plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); |
| 1501 | |
| 1502 | pr = plcf->redirects->elts; |
| 1503 | |
| 1504 | if (pr == NULL) { |
| 1505 | return NGX_DECLINED; |
| 1506 | } |
| 1507 | |
| 1508 | for (i = 0; i < plcf->redirects->nelts; i++) { |
Igor Sysoev | 9e58019 | 2006-02-01 18:22:15 +0000 | [diff] [blame] | 1509 | rc = pr[i].handler(r, h, prefix, &pr[i]); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1510 | |
| 1511 | if (rc != NGX_DECLINED) { |
| 1512 | return rc; |
| 1513 | } |
| 1514 | } |
| 1515 | |
| 1516 | return NGX_DECLINED; |
| 1517 | } |
| 1518 | |
| 1519 | |
| 1520 | static ngx_int_t |
| 1521 | ngx_http_proxy_rewrite_redirect_text(ngx_http_request_t *r, ngx_table_elt_t *h, |
| 1522 | size_t prefix, ngx_http_proxy_redirect_t *pr) |
| 1523 | { |
| 1524 | size_t len; |
| 1525 | u_char *data, *p; |
| 1526 | |
| 1527 | if (pr->redirect.len > h->value.len - prefix |
| 1528 | || ngx_rstrncmp(h->value.data + prefix, pr->redirect.data, |
| 1529 | pr->redirect.len) != 0) |
| 1530 | { |
| 1531 | return NGX_DECLINED; |
| 1532 | } |
| 1533 | |
Igor Sysoev | 82e1933 | 2010-06-07 14:33:50 +0000 | [diff] [blame] | 1534 | len = pr->replacement.text.len + h->value.len - pr->redirect.len; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1535 | |
Igor Sysoev | 7f6b2ff | 2008-06-17 15:00:30 +0000 | [diff] [blame] | 1536 | data = ngx_pnalloc(r->pool, len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1537 | if (data == NULL) { |
| 1538 | return NGX_ERROR; |
| 1539 | } |
| 1540 | |
Igor Sysoev | 27b54fd | 2010-06-07 14:37:56 +0000 | [diff] [blame] | 1541 | p = ngx_copy(data, h->value.data, prefix); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1542 | |
Igor Sysoev | afd7ec5 | 2006-05-29 17:28:12 +0000 | [diff] [blame] | 1543 | if (pr->replacement.text.len) { |
| 1544 | p = ngx_copy(p, pr->replacement.text.data, pr->replacement.text.len); |
| 1545 | } |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1546 | |
| 1547 | ngx_memcpy(p, h->value.data + prefix + pr->redirect.len, |
| 1548 | h->value.len - pr->redirect.len - prefix); |
| 1549 | |
| 1550 | h->value.len = len; |
| 1551 | h->value.data = data; |
| 1552 | |
| 1553 | return NGX_OK; |
| 1554 | } |
| 1555 | |
| 1556 | |
| 1557 | static ngx_int_t |
| 1558 | ngx_http_proxy_rewrite_redirect_vars(ngx_http_request_t *r, ngx_table_elt_t *h, |
| 1559 | size_t prefix, ngx_http_proxy_redirect_t *pr) |
| 1560 | { |
| 1561 | size_t len; |
| 1562 | u_char *data, *p; |
| 1563 | ngx_http_script_code_pt code; |
| 1564 | ngx_http_script_engine_t e; |
| 1565 | ngx_http_script_len_code_pt lcode; |
| 1566 | |
| 1567 | if (pr->redirect.len > h->value.len - prefix |
| 1568 | || ngx_rstrncmp(h->value.data + prefix, pr->redirect.data, |
| 1569 | pr->redirect.len) != 0) |
| 1570 | { |
| 1571 | return NGX_DECLINED; |
| 1572 | } |
| 1573 | |
| 1574 | ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); |
| 1575 | |
| 1576 | e.ip = pr->replacement.vars.lengths; |
| 1577 | e.request = r; |
| 1578 | |
Igor Sysoev | 82e1933 | 2010-06-07 14:33:50 +0000 | [diff] [blame] | 1579 | len = h->value.len - pr->redirect.len; |
Igor Sysoev | c909808 | 2006-09-26 21:15:52 +0000 | [diff] [blame] | 1580 | |
| 1581 | while (*(uintptr_t *) e.ip) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1582 | lcode = *(ngx_http_script_len_code_pt *) e.ip; |
Igor Sysoev | c909808 | 2006-09-26 21:15:52 +0000 | [diff] [blame] | 1583 | len += lcode(&e); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1584 | } |
| 1585 | |
Igor Sysoev | 7f6b2ff | 2008-06-17 15:00:30 +0000 | [diff] [blame] | 1586 | data = ngx_pnalloc(r->pool, len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1587 | if (data == NULL) { |
| 1588 | return NGX_ERROR; |
| 1589 | } |
| 1590 | |
Igor Sysoev | 27b54fd | 2010-06-07 14:37:56 +0000 | [diff] [blame] | 1591 | p = ngx_copy(data, h->value.data, prefix); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1592 | |
| 1593 | e.ip = pr->replacement.vars.values; |
| 1594 | e.pos = p; |
| 1595 | |
| 1596 | while (*(uintptr_t *) e.ip) { |
| 1597 | code = *(ngx_http_script_code_pt *) e.ip; |
| 1598 | code(&e); |
| 1599 | } |
| 1600 | |
Igor Sysoev | c909808 | 2006-09-26 21:15:52 +0000 | [diff] [blame] | 1601 | ngx_memcpy(e.pos, h->value.data + prefix + pr->redirect.len, |
| 1602 | h->value.len - pr->redirect.len - prefix); |
| 1603 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1604 | h->value.len = len; |
| 1605 | h->value.data = data; |
| 1606 | |
| 1607 | return NGX_OK; |
| 1608 | } |
| 1609 | |
| 1610 | |
| 1611 | static ngx_int_t |
| 1612 | ngx_http_proxy_add_variables(ngx_conf_t *cf) |
| 1613 | { |
| 1614 | ngx_http_variable_t *var, *v; |
| 1615 | |
| 1616 | for (v = ngx_http_proxy_vars; v->name.len; v++) { |
| 1617 | var = ngx_http_add_variable(cf, &v->name, v->flags); |
| 1618 | if (var == NULL) { |
| 1619 | return NGX_ERROR; |
| 1620 | } |
| 1621 | |
Igor Sysoev | 7bdb720 | 2006-04-19 15:30:56 +0000 | [diff] [blame] | 1622 | var->get_handler = v->get_handler; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1623 | var->data = v->data; |
| 1624 | } |
| 1625 | |
| 1626 | return NGX_OK; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1627 | } |
| 1628 | |
| 1629 | |
| 1630 | static void * |
| 1631 | ngx_http_proxy_create_loc_conf(ngx_conf_t *cf) |
| 1632 | { |
| 1633 | ngx_http_proxy_loc_conf_t *conf; |
| 1634 | |
| 1635 | conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_loc_conf_t)); |
| 1636 | if (conf == NULL) { |
Igor Sysoev | 260c432 | 2009-06-02 16:09:44 +0000 | [diff] [blame] | 1637 | return NULL; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1638 | } |
| 1639 | |
| 1640 | /* |
| 1641 | * set by ngx_pcalloc(): |
| 1642 | * |
| 1643 | * conf->upstream.bufs.num = 0; |
Igor Sysoev | b01c9cc | 2009-04-30 16:15:07 +0000 | [diff] [blame] | 1644 | * conf->upstream.ignore_headers = 0; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1645 | * conf->upstream.next_upstream = 0; |
Igor Sysoev | 5ed3691 | 2009-05-19 13:27:27 +0000 | [diff] [blame] | 1646 | * conf->upstream.cache_use_stale = 0; |
| 1647 | * conf->upstream.cache_methods = 0; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1648 | * conf->upstream.temp_path = NULL; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1649 | * conf->upstream.hide_headers_hash = { NULL, 0 }; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1650 | * conf->upstream.uri = { 0, NULL }; |
| 1651 | * conf->upstream.location = NULL; |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 1652 | * conf->upstream.store_lengths = NULL; |
| 1653 | * conf->upstream.store_values = NULL; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1654 | * |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 1655 | * conf->method = NULL; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1656 | * conf->headers_source = NULL; |
| 1657 | * conf->headers_set_len = NULL; |
| 1658 | * conf->headers_set = NULL; |
| 1659 | * conf->headers_set_hash = NULL; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1660 | * conf->body_set_len = NULL; |
| 1661 | * conf->body_set = NULL; |
| 1662 | * conf->body_source = { 0, NULL }; |
Igor Sysoev | 931d88c | 2010-03-10 14:37:18 +0000 | [diff] [blame] | 1663 | * conf->redirects = NULL; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1664 | */ |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1665 | |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 1666 | conf->upstream.store = NGX_CONF_UNSET; |
| 1667 | conf->upstream.store_access = NGX_CONF_UNSET_UINT; |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 1668 | conf->upstream.buffering = NGX_CONF_UNSET; |
Igor Sysoev | 6d16e1e | 2006-04-05 13:40:54 +0000 | [diff] [blame] | 1669 | conf->upstream.ignore_client_abort = NGX_CONF_UNSET; |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 1670 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1671 | conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; |
| 1672 | conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; |
| 1673 | conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC; |
| 1674 | |
| 1675 | conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE; |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 1676 | conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1677 | |
| 1678 | conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1679 | conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE; |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1680 | conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1681 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1682 | conf->upstream.pass_request_headers = NGX_CONF_UNSET; |
| 1683 | conf->upstream.pass_request_body = NGX_CONF_UNSET; |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 1684 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1685 | #if (NGX_HTTP_CACHE) |
| 1686 | conf->upstream.cache = NGX_CONF_UNSET_PTR; |
| 1687 | conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; |
Igor Sysoev | f7d659a | 2010-07-19 09:36:04 +0000 | [diff] [blame] | 1688 | conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR; |
Igor Sysoev | 9b2763a | 2010-05-24 11:01:05 +0000 | [diff] [blame] | 1689 | conf->upstream.no_cache = NGX_CONF_UNSET_PTR; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1690 | conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; |
| 1691 | #endif |
| 1692 | |
Igor Sysoev | cb54061 | 2007-12-09 18:03:20 +0000 | [diff] [blame] | 1693 | conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; |
| 1694 | conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; |
| 1695 | |
Igor Sysoev | ef809b8 | 2006-06-28 16:00:26 +0000 | [diff] [blame] | 1696 | conf->upstream.intercept_errors = NGX_CONF_UNSET; |
Igor Sysoev | 916ee8e | 2008-08-17 17:47:52 +0000 | [diff] [blame] | 1697 | #if (NGX_HTTP_SSL) |
| 1698 | conf->upstream.ssl_session_reuse = NGX_CONF_UNSET; |
| 1699 | #endif |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1700 | |
| 1701 | /* "proxy_cyclic_temp_file" is disabled */ |
| 1702 | conf->upstream.cyclic_temp_file = 0; |
| 1703 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1704 | conf->redirect = NGX_CONF_UNSET; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1705 | conf->upstream.change_buffering = 1; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1706 | |
Igor Sysoev | 8a19bff | 2007-04-22 20:21:59 +0000 | [diff] [blame] | 1707 | conf->headers_hash_max_size = NGX_CONF_UNSET_UINT; |
| 1708 | conf->headers_hash_bucket_size = NGX_CONF_UNSET_UINT; |
| 1709 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1710 | return conf; |
| 1711 | } |
| 1712 | |
| 1713 | |
| 1714 | static char * |
| 1715 | ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) |
| 1716 | { |
| 1717 | ngx_http_proxy_loc_conf_t *prev = parent; |
| 1718 | ngx_http_proxy_loc_conf_t *conf = child; |
| 1719 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1720 | size_t size; |
| 1721 | ngx_keyval_t *s; |
| 1722 | ngx_hash_init_t hash; |
Igor Sysoev | 90f9552 | 2010-08-03 09:24:25 +0000 | [diff] [blame] | 1723 | ngx_http_core_loc_conf_t *clcf; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1724 | ngx_http_proxy_redirect_t *pr; |
| 1725 | ngx_http_script_compile_t sc; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1726 | |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 1727 | if (conf->upstream.store != 0) { |
| 1728 | ngx_conf_merge_value(conf->upstream.store, |
Igor Sysoev | da28ef8 | 2009-05-28 13:31:43 +0000 | [diff] [blame] | 1729 | prev->upstream.store, 0); |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 1730 | |
| 1731 | if (conf->upstream.store_lengths == NULL) { |
| 1732 | conf->upstream.store_lengths = prev->upstream.store_lengths; |
| 1733 | conf->upstream.store_values = prev->upstream.store_values; |
| 1734 | } |
| 1735 | } |
| 1736 | |
| 1737 | ngx_conf_merge_uint_value(conf->upstream.store_access, |
| 1738 | prev->upstream.store_access, 0600); |
Igor Sysoev | 58feb53 | 2007-07-12 11:19:05 +0000 | [diff] [blame] | 1739 | |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 1740 | ngx_conf_merge_value(conf->upstream.buffering, |
| 1741 | prev->upstream.buffering, 1); |
| 1742 | |
Igor Sysoev | 6d16e1e | 2006-04-05 13:40:54 +0000 | [diff] [blame] | 1743 | ngx_conf_merge_value(conf->upstream.ignore_client_abort, |
| 1744 | prev->upstream.ignore_client_abort, 0); |
| 1745 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1746 | ngx_conf_merge_msec_value(conf->upstream.connect_timeout, |
| 1747 | prev->upstream.connect_timeout, 60000); |
| 1748 | |
| 1749 | ngx_conf_merge_msec_value(conf->upstream.send_timeout, |
| 1750 | prev->upstream.send_timeout, 60000); |
| 1751 | |
| 1752 | ngx_conf_merge_msec_value(conf->upstream.read_timeout, |
| 1753 | prev->upstream.read_timeout, 60000); |
| 1754 | |
| 1755 | ngx_conf_merge_size_value(conf->upstream.send_lowat, |
| 1756 | prev->upstream.send_lowat, 0); |
| 1757 | |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 1758 | ngx_conf_merge_size_value(conf->upstream.buffer_size, |
| 1759 | prev->upstream.buffer_size, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1760 | (size_t) ngx_pagesize); |
| 1761 | |
| 1762 | ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs, |
| 1763 | 8, ngx_pagesize); |
| 1764 | |
| 1765 | if (conf->upstream.bufs.num < 2) { |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1766 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1767 | "there must be at least 2 \"proxy_buffers\""); |
| 1768 | return NGX_CONF_ERROR; |
| 1769 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1770 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1771 | |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 1772 | size = conf->upstream.buffer_size; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1773 | if (size < conf->upstream.bufs.size) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1774 | size = conf->upstream.bufs.size; |
| 1775 | } |
| 1776 | |
| 1777 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1778 | ngx_conf_merge_size_value(conf->upstream.busy_buffers_size_conf, |
| 1779 | prev->upstream.busy_buffers_size_conf, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1780 | NGX_CONF_UNSET_SIZE); |
| 1781 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1782 | if (conf->upstream.busy_buffers_size_conf == NGX_CONF_UNSET_SIZE) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1783 | conf->upstream.busy_buffers_size = 2 * size; |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1784 | } else { |
| 1785 | conf->upstream.busy_buffers_size = |
| 1786 | conf->upstream.busy_buffers_size_conf; |
| 1787 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1788 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1789 | if (conf->upstream.busy_buffers_size < size) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1790 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 1791 | "\"proxy_busy_buffers_size\" must be equal or bigger than " |
Igor Sysoev | f259a3f | 2007-02-21 11:50:39 +0000 | [diff] [blame] | 1792 | "maximum of the value of \"proxy_buffer_size\" and " |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1793 | "one of the \"proxy_buffers\""); |
| 1794 | |
| 1795 | return NGX_CONF_ERROR; |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1796 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1797 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1798 | if (conf->upstream.busy_buffers_size |
| 1799 | > (conf->upstream.bufs.num - 1) * conf->upstream.bufs.size) |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1800 | { |
| 1801 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 1802 | "\"proxy_busy_buffers_size\" must be less than " |
| 1803 | "the size of all \"proxy_buffers\" minus one buffer"); |
| 1804 | |
| 1805 | return NGX_CONF_ERROR; |
| 1806 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1807 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1808 | |
| 1809 | ngx_conf_merge_size_value(conf->upstream.temp_file_write_size_conf, |
| 1810 | prev->upstream.temp_file_write_size_conf, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1811 | NGX_CONF_UNSET_SIZE); |
| 1812 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1813 | if (conf->upstream.temp_file_write_size_conf == NGX_CONF_UNSET_SIZE) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1814 | conf->upstream.temp_file_write_size = 2 * size; |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1815 | } else { |
| 1816 | conf->upstream.temp_file_write_size = |
| 1817 | conf->upstream.temp_file_write_size_conf; |
| 1818 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1819 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1820 | if (conf->upstream.temp_file_write_size < size) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1821 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 1822 | "\"proxy_temp_file_write_size\" must be equal or bigger than " |
Igor Sysoev | f259a3f | 2007-02-21 11:50:39 +0000 | [diff] [blame] | 1823 | "maximum of the value of \"proxy_buffer_size\" and " |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1824 | "one of the \"proxy_buffers\""); |
| 1825 | |
| 1826 | return NGX_CONF_ERROR; |
| 1827 | } |
| 1828 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1829 | ngx_conf_merge_size_value(conf->upstream.max_temp_file_size_conf, |
| 1830 | prev->upstream.max_temp_file_size_conf, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1831 | NGX_CONF_UNSET_SIZE); |
| 1832 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1833 | if (conf->upstream.max_temp_file_size_conf == NGX_CONF_UNSET_SIZE) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1834 | conf->upstream.max_temp_file_size = 1024 * 1024 * 1024; |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1835 | } else { |
| 1836 | conf->upstream.max_temp_file_size = |
| 1837 | conf->upstream.max_temp_file_size_conf; |
| 1838 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1839 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1840 | if (conf->upstream.max_temp_file_size != 0 |
| 1841 | && conf->upstream.max_temp_file_size < size) |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1842 | { |
| 1843 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 1844 | "\"proxy_max_temp_file_size\" must be equal to zero to disable " |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1845 | "the temporary files usage or must be equal or bigger than " |
Igor Sysoev | f259a3f | 2007-02-21 11:50:39 +0000 | [diff] [blame] | 1846 | "maximum of the value of \"proxy_buffer_size\" and " |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 1847 | "one of the \"proxy_buffers\""); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1848 | |
| 1849 | return NGX_CONF_ERROR; |
| 1850 | } |
| 1851 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1852 | |
Igor Sysoev | b01c9cc | 2009-04-30 16:15:07 +0000 | [diff] [blame] | 1853 | ngx_conf_merge_bitmask_value(conf->upstream.ignore_headers, |
| 1854 | prev->upstream.ignore_headers, |
| 1855 | NGX_CONF_BITMASK_SET); |
| 1856 | |
| 1857 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1858 | ngx_conf_merge_bitmask_value(conf->upstream.next_upstream, |
| 1859 | prev->upstream.next_upstream, |
| 1860 | (NGX_CONF_BITMASK_SET |
| 1861 | |NGX_HTTP_UPSTREAM_FT_ERROR |
| 1862 | |NGX_HTTP_UPSTREAM_FT_TIMEOUT)); |
| 1863 | |
Igor Sysoev | bb28b6d | 2006-07-11 13:20:19 +0000 | [diff] [blame] | 1864 | if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) { |
| 1865 | conf->upstream.next_upstream = NGX_CONF_BITMASK_SET |
| 1866 | |NGX_HTTP_UPSTREAM_FT_OFF; |
| 1867 | } |
| 1868 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1869 | if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1870 | prev->upstream.temp_path, |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1871 | &ngx_http_proxy_temp_path) |
| 1872 | != NGX_OK) |
| 1873 | { |
| 1874 | return NGX_CONF_ERROR; |
| 1875 | } |
| 1876 | |
| 1877 | |
| 1878 | #if (NGX_HTTP_CACHE) |
| 1879 | |
| 1880 | ngx_conf_merge_ptr_value(conf->upstream.cache, |
| 1881 | prev->upstream.cache, NULL); |
| 1882 | |
| 1883 | if (conf->upstream.cache && conf->upstream.cache->data == NULL) { |
| 1884 | ngx_shm_zone_t *shm_zone; |
| 1885 | |
| 1886 | shm_zone = conf->upstream.cache; |
| 1887 | |
| 1888 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 1889 | "\"proxy_cache\" zone \"%V\" is unknown", |
Igor Sysoev | c7f876b | 2009-04-16 19:25:09 +0000 | [diff] [blame] | 1890 | &shm_zone->shm.name); |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1891 | |
| 1892 | return NGX_CONF_ERROR; |
| 1893 | } |
| 1894 | |
| 1895 | ngx_conf_merge_uint_value(conf->upstream.cache_min_uses, |
| 1896 | prev->upstream.cache_min_uses, 1); |
| 1897 | |
| 1898 | ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale, |
| 1899 | prev->upstream.cache_use_stale, |
| 1900 | (NGX_CONF_BITMASK_SET |
| 1901 | |NGX_HTTP_UPSTREAM_FT_OFF)); |
| 1902 | |
Igor Sysoev | 5ed3691 | 2009-05-19 13:27:27 +0000 | [diff] [blame] | 1903 | if (conf->upstream.cache_methods == 0) { |
| 1904 | conf->upstream.cache_methods = prev->upstream.cache_methods; |
| 1905 | } |
| 1906 | |
| 1907 | conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD; |
| 1908 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1909 | if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) { |
| 1910 | conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET |
| 1911 | |NGX_HTTP_UPSTREAM_FT_OFF; |
| 1912 | } |
| 1913 | |
Igor Sysoev | f7d659a | 2010-07-19 09:36:04 +0000 | [diff] [blame] | 1914 | ngx_conf_merge_ptr_value(conf->upstream.cache_bypass, |
| 1915 | prev->upstream.cache_bypass, NULL); |
| 1916 | |
Igor Sysoev | 9b2763a | 2010-05-24 11:01:05 +0000 | [diff] [blame] | 1917 | ngx_conf_merge_ptr_value(conf->upstream.no_cache, |
| 1918 | prev->upstream.no_cache, NULL); |
| 1919 | |
Igor Sysoev | 47f5f94 | 2010-07-19 09:55:43 +0000 | [diff] [blame] | 1920 | if (conf->upstream.no_cache && conf->upstream.cache_bypass == NULL) { |
| 1921 | ngx_log_error(NGX_LOG_WARN, cf->log, 0, |
| 1922 | "\"proxy_no_cache\" functionality has been changed in 0.8.46, " |
| 1923 | "now it should be used together with \"proxy_cache_bypass\""); |
| 1924 | } |
| 1925 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1926 | ngx_conf_merge_ptr_value(conf->upstream.cache_valid, |
| 1927 | prev->upstream.cache_valid, NULL); |
| 1928 | |
Igor Sysoev | 44a69c8 | 2009-04-06 08:58:44 +0000 | [diff] [blame] | 1929 | if (conf->cache_key.value.data == NULL) { |
| 1930 | conf->cache_key = prev->cache_key; |
| 1931 | } |
| 1932 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1933 | #endif |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1934 | |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 1935 | if (conf->method.len == 0) { |
| 1936 | conf->method = prev->method; |
| 1937 | |
| 1938 | } else { |
| 1939 | conf->method.data[conf->method.len] = ' '; |
| 1940 | conf->method.len++; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1941 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1942 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1943 | ngx_conf_merge_value(conf->upstream.pass_request_headers, |
| 1944 | prev->upstream.pass_request_headers, 1); |
| 1945 | ngx_conf_merge_value(conf->upstream.pass_request_body, |
| 1946 | prev->upstream.pass_request_body, 1); |
| 1947 | |
Igor Sysoev | ef809b8 | 2006-06-28 16:00:26 +0000 | [diff] [blame] | 1948 | ngx_conf_merge_value(conf->upstream.intercept_errors, |
| 1949 | prev->upstream.intercept_errors, 0); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1950 | |
Igor Sysoev | 916ee8e | 2008-08-17 17:47:52 +0000 | [diff] [blame] | 1951 | #if (NGX_HTTP_SSL) |
| 1952 | ngx_conf_merge_value(conf->upstream.ssl_session_reuse, |
| 1953 | prev->upstream.ssl_session_reuse, 1); |
| 1954 | #endif |
| 1955 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1956 | ngx_conf_merge_value(conf->redirect, prev->redirect, 1); |
| 1957 | |
| 1958 | if (conf->redirect) { |
| 1959 | |
| 1960 | if (conf->redirects == NULL) { |
| 1961 | conf->redirects = prev->redirects; |
| 1962 | } |
| 1963 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1964 | if (conf->redirects == NULL && conf->url.data) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1965 | |
| 1966 | conf->redirects = ngx_array_create(cf->pool, 1, |
| 1967 | sizeof(ngx_http_proxy_redirect_t)); |
| 1968 | if (conf->redirects == NULL) { |
| 1969 | return NGX_CONF_ERROR; |
| 1970 | } |
| 1971 | |
| 1972 | pr = ngx_array_push(conf->redirects); |
| 1973 | if (pr == NULL) { |
| 1974 | return NGX_CONF_ERROR; |
| 1975 | } |
| 1976 | |
| 1977 | pr->handler = ngx_http_proxy_rewrite_redirect_text; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1978 | pr->redirect = conf->url; |
Igor Sysoev | afd7ec5 | 2006-05-29 17:28:12 +0000 | [diff] [blame] | 1979 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1980 | if (conf->vars.uri.len) { |
| 1981 | pr->replacement.text = conf->location; |
Igor Sysoev | afd7ec5 | 2006-05-29 17:28:12 +0000 | [diff] [blame] | 1982 | |
| 1983 | } else { |
Igor Sysoev | 05b1a8f | 2010-05-14 09:56:37 +0000 | [diff] [blame] | 1984 | ngx_str_null(&pr->replacement.text); |
Igor Sysoev | afd7ec5 | 2006-05-29 17:28:12 +0000 | [diff] [blame] | 1985 | } |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1986 | } |
| 1987 | } |
| 1988 | |
Igor Sysoev | 2238056 | 2009-04-24 19:56:09 +0000 | [diff] [blame] | 1989 | #if (NGX_HTTP_SSL) |
| 1990 | if (conf->upstream.ssl == NULL) { |
| 1991 | conf->upstream.ssl = prev->upstream.ssl; |
| 1992 | } |
| 1993 | #endif |
| 1994 | |
Igor Sysoev | 8a19bff | 2007-04-22 20:21:59 +0000 | [diff] [blame] | 1995 | ngx_conf_merge_uint_value(conf->headers_hash_max_size, |
| 1996 | prev->headers_hash_max_size, 512); |
| 1997 | |
| 1998 | ngx_conf_merge_uint_value(conf->headers_hash_bucket_size, |
| 1999 | prev->headers_hash_bucket_size, 64); |
| 2000 | |
| 2001 | conf->headers_hash_bucket_size = ngx_align(conf->headers_hash_bucket_size, |
| 2002 | ngx_cacheline_size); |
| 2003 | |
Igor Sysoev | cb54061 | 2007-12-09 18:03:20 +0000 | [diff] [blame] | 2004 | hash.max_size = conf->headers_hash_max_size; |
| 2005 | hash.bucket_size = conf->headers_hash_bucket_size; |
| 2006 | hash.name = "proxy_headers_hash"; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 2007 | |
Igor Sysoev | cb54061 | 2007-12-09 18:03:20 +0000 | [diff] [blame] | 2008 | if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream, |
Igor Sysoev | 0cb0c67 | 2010-07-02 10:05:40 +0000 | [diff] [blame] | 2009 | &prev->upstream, ngx_http_proxy_hide_headers, &hash) |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 2010 | != NGX_OK) |
| 2011 | { |
| 2012 | return NGX_CONF_ERROR; |
| 2013 | } |
| 2014 | |
Igor Sysoev | 3d2fd18 | 2006-12-04 16:46:13 +0000 | [diff] [blame] | 2015 | if (conf->upstream.upstream == NULL) { |
| 2016 | conf->upstream.upstream = prev->upstream.upstream; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2017 | conf->vars = prev->vars; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2018 | } |
| 2019 | |
Igor Sysoev | 81cd5e4 | 2010-08-03 12:59:14 +0000 | [diff] [blame^] | 2020 | if (conf->proxy_lengths == NULL) { |
| 2021 | conf->proxy_lengths = prev->proxy_lengths; |
| 2022 | conf->proxy_values = prev->proxy_values; |
| 2023 | } |
| 2024 | |
Igor Sysoev | 90f9552 | 2010-08-03 09:24:25 +0000 | [diff] [blame] | 2025 | if (conf->upstream.upstream || conf->proxy_lengths) { |
| 2026 | clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); |
| 2027 | if (clcf->handler == NULL && clcf->lmt_excpt) { |
| 2028 | clcf->handler = ngx_http_proxy_handler; |
| 2029 | conf->location = prev->location; |
| 2030 | } |
| 2031 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2032 | |
| 2033 | if (conf->body_source.data == NULL) { |
| 2034 | conf->body_source = prev->body_source; |
| 2035 | conf->body_set_len = prev->body_set_len; |
| 2036 | conf->body_set = prev->body_set; |
| 2037 | } |
| 2038 | |
Igor Sysoev | b141f2b | 2005-11-15 14:49:57 +0000 | [diff] [blame] | 2039 | if (conf->body_source.data && conf->body_set_len == NULL) { |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2040 | |
| 2041 | ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
| 2042 | |
| 2043 | sc.cf = cf; |
| 2044 | sc.source = &conf->body_source; |
| 2045 | sc.flushes = &conf->flushes; |
| 2046 | sc.lengths = &conf->body_set_len; |
| 2047 | sc.values = &conf->body_set; |
| 2048 | sc.complete_lengths = 1; |
| 2049 | sc.complete_values = 1; |
| 2050 | |
| 2051 | if (ngx_http_script_compile(&sc) != NGX_OK) { |
| 2052 | return NGX_CONF_ERROR; |
| 2053 | } |
| 2054 | |
| 2055 | if (conf->headers_source == NULL) { |
| 2056 | conf->headers_source = ngx_array_create(cf->pool, 4, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 2057 | sizeof(ngx_keyval_t)); |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2058 | if (conf->headers_source == NULL) { |
| 2059 | return NGX_CONF_ERROR; |
| 2060 | } |
| 2061 | } |
| 2062 | |
| 2063 | s = ngx_array_push(conf->headers_source); |
| 2064 | if (s == NULL) { |
| 2065 | return NGX_CONF_ERROR; |
| 2066 | } |
| 2067 | |
Igor Sysoev | 05b1a8f | 2010-05-14 09:56:37 +0000 | [diff] [blame] | 2068 | ngx_str_set(&s->key, "Content-Length"); |
| 2069 | ngx_str_set(&s->value, "$proxy_internal_body_length"); |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2070 | } |
| 2071 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2072 | if (ngx_http_proxy_merge_headers(cf, conf, prev) != NGX_OK) { |
| 2073 | return NGX_CONF_ERROR; |
| 2074 | } |
| 2075 | |
| 2076 | return NGX_CONF_OK; |
| 2077 | } |
| 2078 | |
| 2079 | |
| 2080 | static ngx_int_t |
| 2081 | ngx_http_proxy_merge_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf, |
| 2082 | ngx_http_proxy_loc_conf_t *prev) |
| 2083 | { |
| 2084 | u_char *p; |
| 2085 | size_t size; |
| 2086 | uintptr_t *code; |
| 2087 | ngx_uint_t i; |
Igor Sysoev | 17483d5 | 2010-06-03 14:50:59 +0000 | [diff] [blame] | 2088 | ngx_array_t headers_names; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2089 | ngx_keyval_t *src, *s, *h; |
| 2090 | ngx_hash_key_t *hk; |
| 2091 | ngx_hash_init_t hash; |
| 2092 | ngx_http_script_compile_t sc; |
| 2093 | ngx_http_script_copy_code_t *copy; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2094 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2095 | if (conf->headers_source == NULL) { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2096 | conf->flushes = prev->flushes; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2097 | conf->headers_set_len = prev->headers_set_len; |
| 2098 | conf->headers_set = prev->headers_set; |
| 2099 | conf->headers_set_hash = prev->headers_set_hash; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2100 | conf->headers_source = prev->headers_source; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2101 | } |
| 2102 | |
Igor Sysoev | 83c93ba | 2009-06-08 12:33:11 +0000 | [diff] [blame] | 2103 | if (conf->headers_set_hash.buckets |
Igor Sysoev | 0775182 | 2009-06-15 14:25:08 +0000 | [diff] [blame] | 2104 | #if (NGX_HTTP_CACHE) |
| 2105 | && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL)) |
| 2106 | #endif |
| 2107 | ) |
Igor Sysoev | 83c93ba | 2009-06-08 12:33:11 +0000 | [diff] [blame] | 2108 | { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2109 | return NGX_OK; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2110 | } |
| 2111 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2112 | |
Igor Sysoev | 17483d5 | 2010-06-03 14:50:59 +0000 | [diff] [blame] | 2113 | if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) |
| 2114 | != NGX_OK) |
| 2115 | { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2116 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2117 | } |
| 2118 | |
| 2119 | if (conf->headers_source == NULL) { |
| 2120 | conf->headers_source = ngx_array_create(cf->pool, 4, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 2121 | sizeof(ngx_keyval_t)); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2122 | if (conf->headers_source == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2123 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2124 | } |
| 2125 | } |
| 2126 | |
| 2127 | conf->headers_set_len = ngx_array_create(cf->pool, 64, 1); |
| 2128 | if (conf->headers_set_len == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2129 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2130 | } |
| 2131 | |
| 2132 | conf->headers_set = ngx_array_create(cf->pool, 512, 1); |
| 2133 | if (conf->headers_set == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2134 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2135 | } |
| 2136 | |
| 2137 | |
| 2138 | src = conf->headers_source->elts; |
| 2139 | |
Igor Sysoev | 081662a | 2009-04-15 11:21:12 +0000 | [diff] [blame] | 2140 | #if (NGX_HTTP_CACHE) |
| 2141 | |
| 2142 | h = conf->upstream.cache ? ngx_http_proxy_cache_headers: |
| 2143 | ngx_http_proxy_headers; |
| 2144 | #else |
| 2145 | |
| 2146 | h = ngx_http_proxy_headers; |
| 2147 | |
| 2148 | #endif |
| 2149 | |
| 2150 | while (h->key.len) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2151 | |
| 2152 | for (i = 0; i < conf->headers_source->nelts; i++) { |
| 2153 | if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) { |
| 2154 | goto next; |
| 2155 | } |
| 2156 | } |
| 2157 | |
| 2158 | s = ngx_array_push(conf->headers_source); |
| 2159 | if (s == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2160 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2161 | } |
| 2162 | |
| 2163 | *s = *h; |
| 2164 | |
Igor Sysoev | 4959ec4 | 2005-05-23 12:07:45 +0000 | [diff] [blame] | 2165 | src = conf->headers_source->elts; |
| 2166 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2167 | next: |
| 2168 | |
Igor Sysoev | 081662a | 2009-04-15 11:21:12 +0000 | [diff] [blame] | 2169 | h++; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2170 | } |
| 2171 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2172 | |
| 2173 | src = conf->headers_source->elts; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2174 | for (i = 0; i < conf->headers_source->nelts; i++) { |
| 2175 | |
Igor Sysoev | 17483d5 | 2010-06-03 14:50:59 +0000 | [diff] [blame] | 2176 | hk = ngx_array_push(&headers_names); |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 2177 | if (hk == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2178 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2179 | } |
| 2180 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 2181 | hk->key = src[i].key; |
| 2182 | hk->key_hash = ngx_hash_key_lc(src[i].key.data, src[i].key.len); |
| 2183 | hk->value = (void *) 1; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2184 | |
Igor Sysoev | 403d244 | 2005-05-26 18:12:40 +0000 | [diff] [blame] | 2185 | if (src[i].value.len == 0) { |
| 2186 | continue; |
| 2187 | } |
| 2188 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2189 | if (ngx_http_script_variables_count(&src[i].value) == 0) { |
| 2190 | copy = ngx_array_push_n(conf->headers_set_len, |
| 2191 | sizeof(ngx_http_script_copy_code_t)); |
| 2192 | if (copy == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2193 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2194 | } |
| 2195 | |
| 2196 | copy->code = (ngx_http_script_code_pt) |
| 2197 | ngx_http_script_copy_len_code; |
| 2198 | copy->len = src[i].key.len + sizeof(": ") - 1 |
| 2199 | + src[i].value.len + sizeof(CRLF) - 1; |
| 2200 | |
| 2201 | |
| 2202 | size = (sizeof(ngx_http_script_copy_code_t) |
| 2203 | + src[i].key.len + sizeof(": ") - 1 |
| 2204 | + src[i].value.len + sizeof(CRLF) - 1 |
| 2205 | + sizeof(uintptr_t) - 1) |
| 2206 | & ~(sizeof(uintptr_t) - 1); |
| 2207 | |
| 2208 | copy = ngx_array_push_n(conf->headers_set, size); |
| 2209 | if (copy == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2210 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2211 | } |
| 2212 | |
| 2213 | copy->code = ngx_http_script_copy_code; |
| 2214 | copy->len = src[i].key.len + sizeof(": ") - 1 |
| 2215 | + src[i].value.len + sizeof(CRLF) - 1; |
| 2216 | |
| 2217 | p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); |
| 2218 | |
| 2219 | p = ngx_cpymem(p, src[i].key.data, src[i].key.len); |
| 2220 | *p++ = ':'; *p++ = ' '; |
| 2221 | p = ngx_cpymem(p, src[i].value.data, src[i].value.len); |
| 2222 | *p++ = CR; *p = LF; |
| 2223 | |
| 2224 | } else { |
| 2225 | copy = ngx_array_push_n(conf->headers_set_len, |
| 2226 | sizeof(ngx_http_script_copy_code_t)); |
| 2227 | if (copy == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2228 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2229 | } |
| 2230 | |
| 2231 | copy->code = (ngx_http_script_code_pt) |
| 2232 | ngx_http_script_copy_len_code; |
| 2233 | copy->len = src[i].key.len + sizeof(": ") - 1; |
| 2234 | |
| 2235 | |
| 2236 | size = (sizeof(ngx_http_script_copy_code_t) |
| 2237 | + src[i].key.len + sizeof(": ") - 1 + sizeof(uintptr_t) - 1) |
| 2238 | & ~(sizeof(uintptr_t) - 1); |
| 2239 | |
| 2240 | copy = ngx_array_push_n(conf->headers_set, size); |
| 2241 | if (copy == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2242 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2243 | } |
| 2244 | |
| 2245 | copy->code = ngx_http_script_copy_code; |
| 2246 | copy->len = src[i].key.len + sizeof(": ") - 1; |
| 2247 | |
| 2248 | p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); |
| 2249 | p = ngx_cpymem(p, src[i].key.data, src[i].key.len); |
| 2250 | *p++ = ':'; *p = ' '; |
| 2251 | |
| 2252 | |
| 2253 | ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
| 2254 | |
| 2255 | sc.cf = cf; |
| 2256 | sc.source = &src[i].value; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2257 | sc.flushes = &conf->flushes; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2258 | sc.lengths = &conf->headers_set_len; |
| 2259 | sc.values = &conf->headers_set; |
| 2260 | |
| 2261 | if (ngx_http_script_compile(&sc) != NGX_OK) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2262 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2263 | } |
| 2264 | |
| 2265 | |
| 2266 | copy = ngx_array_push_n(conf->headers_set_len, |
| 2267 | sizeof(ngx_http_script_copy_code_t)); |
| 2268 | if (copy == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2269 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2270 | } |
| 2271 | |
| 2272 | copy->code = (ngx_http_script_code_pt) |
| 2273 | ngx_http_script_copy_len_code; |
| 2274 | copy->len = sizeof(CRLF) - 1; |
| 2275 | |
| 2276 | |
| 2277 | size = (sizeof(ngx_http_script_copy_code_t) |
| 2278 | + sizeof(CRLF) - 1 + sizeof(uintptr_t) - 1) |
| 2279 | & ~(sizeof(uintptr_t) - 1); |
| 2280 | |
| 2281 | copy = ngx_array_push_n(conf->headers_set, size); |
| 2282 | if (copy == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2283 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2284 | } |
| 2285 | |
| 2286 | copy->code = ngx_http_script_copy_code; |
| 2287 | copy->len = sizeof(CRLF) - 1; |
| 2288 | |
| 2289 | p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); |
| 2290 | *p++ = CR; *p = LF; |
| 2291 | } |
| 2292 | |
| 2293 | code = ngx_array_push_n(conf->headers_set_len, sizeof(uintptr_t)); |
| 2294 | if (code == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2295 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2296 | } |
| 2297 | |
| 2298 | *code = (uintptr_t) NULL; |
| 2299 | |
| 2300 | code = ngx_array_push_n(conf->headers_set, sizeof(uintptr_t)); |
| 2301 | if (code == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2302 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2303 | } |
| 2304 | |
| 2305 | *code = (uintptr_t) NULL; |
| 2306 | } |
| 2307 | |
| 2308 | code = ngx_array_push_n(conf->headers_set_len, sizeof(uintptr_t)); |
| 2309 | if (code == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2310 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2311 | } |
| 2312 | |
| 2313 | *code = (uintptr_t) NULL; |
| 2314 | |
| 2315 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 2316 | hash.hash = &conf->headers_set_hash; |
| 2317 | hash.key = ngx_hash_key_lc; |
Igor Sysoev | 8a19bff | 2007-04-22 20:21:59 +0000 | [diff] [blame] | 2318 | hash.max_size = conf->headers_hash_max_size; |
| 2319 | hash.bucket_size = conf->headers_hash_bucket_size; |
| 2320 | hash.name = "proxy_headers_hash"; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 2321 | hash.pool = cf->pool; |
| 2322 | hash.temp_pool = NULL; |
| 2323 | |
Igor Sysoev | 17483d5 | 2010-06-03 14:50:59 +0000 | [diff] [blame] | 2324 | return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2325 | } |
| 2326 | |
| 2327 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2328 | static char * |
| 2329 | ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
| 2330 | { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2331 | ngx_http_proxy_loc_conf_t *plcf = conf; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2332 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2333 | size_t add; |
| 2334 | u_short port; |
| 2335 | ngx_str_t *value, *url; |
| 2336 | ngx_url_t u; |
| 2337 | ngx_uint_t n; |
| 2338 | ngx_http_core_loc_conf_t *clcf; |
| 2339 | ngx_http_script_compile_t sc; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2340 | |
Igor Sysoev | 73c3121 | 2008-12-10 14:44:48 +0000 | [diff] [blame] | 2341 | if (plcf->upstream.upstream || plcf->proxy_lengths) { |
Igor Sysoev | a257367 | 2005-10-05 14:46:21 +0000 | [diff] [blame] | 2342 | return "is duplicate"; |
| 2343 | } |
| 2344 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2345 | clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); |
| 2346 | |
Igor Sysoev | 5639272 | 2009-07-20 11:44:38 +0000 | [diff] [blame] | 2347 | clcf->handler = ngx_http_proxy_handler; |
| 2348 | |
| 2349 | if (clcf->name.data[clcf->name.len - 1] == '/') { |
| 2350 | clcf->auto_redirect = 1; |
| 2351 | } |
| 2352 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2353 | value = cf->args->elts; |
| 2354 | |
| 2355 | url = &value[1]; |
| 2356 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2357 | n = ngx_http_script_variables_count(url); |
| 2358 | |
| 2359 | if (n) { |
| 2360 | |
| 2361 | ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
| 2362 | |
| 2363 | sc.cf = cf; |
| 2364 | sc.source = url; |
| 2365 | sc.lengths = &plcf->proxy_lengths; |
| 2366 | sc.values = &plcf->proxy_values; |
| 2367 | sc.variables = n; |
| 2368 | sc.complete_lengths = 1; |
| 2369 | sc.complete_values = 1; |
Igor Sysoev | b4e5b4c | 2007-12-01 19:57:37 +0000 | [diff] [blame] | 2370 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2371 | if (ngx_http_script_compile(&sc) != NGX_OK) { |
| 2372 | return NGX_CONF_ERROR; |
| 2373 | } |
| 2374 | |
| 2375 | #if (NGX_HTTP_SSL) |
| 2376 | if (ngx_http_proxy_set_ssl(cf, plcf) != NGX_OK) { |
| 2377 | return NGX_CONF_ERROR; |
| 2378 | } |
| 2379 | #endif |
| 2380 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2381 | return NGX_CONF_OK; |
| 2382 | } |
| 2383 | |
Igor Sysoev | 722231f | 2007-02-14 18:51:19 +0000 | [diff] [blame] | 2384 | if (ngx_strncasecmp(url->data, (u_char *) "http://", 7) == 0) { |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2385 | add = 7; |
Igor Sysoev | 43f279d | 2005-12-18 16:02:44 +0000 | [diff] [blame] | 2386 | port = 80; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2387 | |
Igor Sysoev | 722231f | 2007-02-14 18:51:19 +0000 | [diff] [blame] | 2388 | } else if (ngx_strncasecmp(url->data, (u_char *) "https://", 8) == 0) { |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2389 | |
| 2390 | #if (NGX_HTTP_SSL) |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2391 | if (ngx_http_proxy_set_ssl(cf, plcf) != NGX_OK) { |
| 2392 | return NGX_CONF_ERROR; |
| 2393 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2394 | |
| 2395 | add = 8; |
Igor Sysoev | 43f279d | 2005-12-18 16:02:44 +0000 | [diff] [blame] | 2396 | port = 443; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2397 | #else |
| 2398 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 2399 | "https protocol requires SSL support"); |
| 2400 | return NGX_CONF_ERROR; |
| 2401 | #endif |
| 2402 | |
| 2403 | } else { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2404 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid URL prefix"); |
| 2405 | return NGX_CONF_ERROR; |
| 2406 | } |
| 2407 | |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 2408 | ngx_memzero(&u, sizeof(ngx_url_t)); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2409 | |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 2410 | u.url.len = url->len - add; |
| 2411 | u.url.data = url->data + add; |
Igor Sysoev | bf3aaac | 2006-12-12 16:46:16 +0000 | [diff] [blame] | 2412 | u.default_port = port; |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 2413 | u.uri_part = 1; |
Igor Sysoev | bf3aaac | 2006-12-12 16:46:16 +0000 | [diff] [blame] | 2414 | u.no_resolve = 1; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2415 | |
Igor Sysoev | 3d2fd18 | 2006-12-04 16:46:13 +0000 | [diff] [blame] | 2416 | plcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0); |
| 2417 | if (plcf->upstream.upstream == NULL) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2418 | return NGX_CONF_ERROR; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2419 | } |
| 2420 | |
Igor Sysoev | 73c3121 | 2008-12-10 14:44:48 +0000 | [diff] [blame] | 2421 | plcf->vars.schema.len = add; |
| 2422 | plcf->vars.schema.data = url->data; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2423 | plcf->vars.key_start = plcf->vars.schema; |
| 2424 | |
| 2425 | ngx_http_proxy_set_vars(&u, &plcf->vars); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2426 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2427 | plcf->location = clcf->name; |
| 2428 | |
Igor Sysoev | 8889b65 | 2007-07-29 18:11:39 +0000 | [diff] [blame] | 2429 | if (clcf->named |
Igor Sysoev | a257367 | 2005-10-05 14:46:21 +0000 | [diff] [blame] | 2430 | #if (NGX_PCRE) |
Igor Sysoev | 8889b65 | 2007-07-29 18:11:39 +0000 | [diff] [blame] | 2431 | || clcf->regex |
| 2432 | #endif |
| 2433 | || clcf->noname) |
| 2434 | { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2435 | if (plcf->vars.uri.len) { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2436 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 2437 | "\"proxy_pass\" may not have URI part in " |
Igor Sysoev | e927b1e | 2006-11-14 12:43:14 +0000 | [diff] [blame] | 2438 | "location given by regular expression, " |
Igor Sysoev | 8889b65 | 2007-07-29 18:11:39 +0000 | [diff] [blame] | 2439 | "or inside named location, " |
Igor Sysoev | e927b1e | 2006-11-14 12:43:14 +0000 | [diff] [blame] | 2440 | "or inside the \"if\" statement, " |
| 2441 | "or inside the \"limit_except\" block"); |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2442 | return NGX_CONF_ERROR; |
| 2443 | } |
| 2444 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2445 | plcf->location.len = 0; |
Igor Sysoev | a257367 | 2005-10-05 14:46:21 +0000 | [diff] [blame] | 2446 | } |
| 2447 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2448 | plcf->url = *url; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2449 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2450 | return NGX_CONF_OK; |
| 2451 | } |
| 2452 | |
| 2453 | |
| 2454 | static char * |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2455 | ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2456 | { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2457 | ngx_http_proxy_loc_conf_t *plcf = conf; |
| 2458 | |
| 2459 | ngx_str_t *value; |
| 2460 | ngx_array_t *vars_lengths, *vars_values; |
| 2461 | ngx_http_script_compile_t sc; |
| 2462 | ngx_http_proxy_redirect_t *pr; |
| 2463 | |
| 2464 | if (plcf->redirect == 0) { |
| 2465 | return NGX_CONF_OK; |
| 2466 | } |
| 2467 | |
| 2468 | value = cf->args->elts; |
| 2469 | |
Igor Sysoev | 06d4aa1 | 2009-04-30 12:43:38 +0000 | [diff] [blame] | 2470 | if (cf->args->nelts == 2) { |
| 2471 | if (ngx_strcmp(value[1].data, "off") == 0) { |
| 2472 | plcf->redirect = 0; |
| 2473 | plcf->redirects = NULL; |
| 2474 | return NGX_CONF_OK; |
| 2475 | } |
| 2476 | |
| 2477 | if (ngx_strcmp(value[1].data, "false") == 0) { |
| 2478 | ngx_conf_log_error(NGX_LOG_ERR, cf, 0, |
| 2479 | "invalid parameter \"false\", use \"off\" instead"); |
| 2480 | plcf->redirect = 0; |
| 2481 | plcf->redirects = NULL; |
| 2482 | return NGX_CONF_OK; |
| 2483 | } |
| 2484 | |
| 2485 | if (ngx_strcmp(value[1].data, "default") != 0) { |
| 2486 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 2487 | "invalid parameter \"%V\"", &value[1]); |
| 2488 | return NGX_CONF_ERROR; |
| 2489 | } |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2490 | } |
| 2491 | |
| 2492 | if (plcf->redirects == NULL) { |
| 2493 | plcf->redirects = ngx_array_create(cf->pool, 1, |
| 2494 | sizeof(ngx_http_proxy_redirect_t)); |
| 2495 | if (plcf->redirects == NULL) { |
| 2496 | return NGX_CONF_ERROR; |
| 2497 | } |
| 2498 | } |
| 2499 | |
| 2500 | pr = ngx_array_push(plcf->redirects); |
| 2501 | if (pr == NULL) { |
| 2502 | return NGX_CONF_ERROR; |
| 2503 | } |
| 2504 | |
Igor Sysoev | 06d4aa1 | 2009-04-30 12:43:38 +0000 | [diff] [blame] | 2505 | if (ngx_strcmp(value[1].data, "default") == 0) { |
Igor Sysoev | 7fa1c07 | 2010-03-10 14:41:49 +0000 | [diff] [blame] | 2506 | if (plcf->proxy_lengths) { |
| 2507 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 2508 | "\"proxy_redirect default\" may not be used " |
| 2509 | "with \"proxy_pass\" directive with variables"); |
| 2510 | return NGX_CONF_ERROR; |
| 2511 | } |
| 2512 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2513 | if (plcf->url.data == NULL) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2514 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
Igor Sysoev | 931d88c | 2010-03-10 14:37:18 +0000 | [diff] [blame] | 2515 | "\"proxy_redirect default\" must go " |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2516 | "after the \"proxy_pass\" directive"); |
| 2517 | return NGX_CONF_ERROR; |
| 2518 | } |
| 2519 | |
| 2520 | pr->handler = ngx_http_proxy_rewrite_redirect_text; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2521 | pr->redirect = plcf->url; |
Igor Sysoev | afd7ec5 | 2006-05-29 17:28:12 +0000 | [diff] [blame] | 2522 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2523 | if (plcf->vars.uri.len) { |
| 2524 | pr->replacement.text = plcf->location; |
Igor Sysoev | afd7ec5 | 2006-05-29 17:28:12 +0000 | [diff] [blame] | 2525 | |
| 2526 | } else { |
Igor Sysoev | 05b1a8f | 2010-05-14 09:56:37 +0000 | [diff] [blame] | 2527 | ngx_str_null(&pr->replacement.text); |
Igor Sysoev | afd7ec5 | 2006-05-29 17:28:12 +0000 | [diff] [blame] | 2528 | } |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2529 | |
| 2530 | return NGX_CONF_OK; |
| 2531 | } |
| 2532 | |
| 2533 | if (ngx_http_script_variables_count(&value[2]) == 0) { |
| 2534 | pr->handler = ngx_http_proxy_rewrite_redirect_text; |
| 2535 | pr->redirect = value[1]; |
| 2536 | pr->replacement.text = value[2]; |
| 2537 | |
| 2538 | return NGX_CONF_OK; |
| 2539 | } |
| 2540 | |
| 2541 | ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
| 2542 | |
| 2543 | vars_lengths = NULL; |
| 2544 | vars_values = NULL; |
| 2545 | |
| 2546 | sc.cf = cf; |
| 2547 | sc.source = &value[2]; |
| 2548 | sc.lengths = &vars_lengths; |
| 2549 | sc.values = &vars_values; |
| 2550 | sc.complete_lengths = 1; |
| 2551 | sc.complete_values = 1; |
| 2552 | |
| 2553 | if (ngx_http_script_compile(&sc) != NGX_OK) { |
| 2554 | return NGX_CONF_ERROR; |
| 2555 | } |
| 2556 | |
| 2557 | pr->handler = ngx_http_proxy_rewrite_redirect_vars; |
| 2558 | pr->redirect = value[1]; |
| 2559 | pr->replacement.vars.lengths = vars_lengths->elts; |
| 2560 | pr->replacement.vars.values = vars_values->elts; |
| 2561 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2562 | return NGX_CONF_OK; |
| 2563 | } |
| 2564 | |
| 2565 | |
| 2566 | static char * |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 2567 | ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
| 2568 | { |
| 2569 | ngx_http_proxy_loc_conf_t *plcf = conf; |
| 2570 | |
| 2571 | ngx_str_t *value; |
| 2572 | ngx_http_script_compile_t sc; |
| 2573 | |
Igor Sysoev | da28ef8 | 2009-05-28 13:31:43 +0000 | [diff] [blame] | 2574 | if (plcf->upstream.store != NGX_CONF_UNSET |
| 2575 | || plcf->upstream.store_lengths) |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 2576 | { |
| 2577 | return "is duplicate"; |
| 2578 | } |
| 2579 | |
| 2580 | value = cf->args->elts; |
| 2581 | |
Igor Sysoev | 98f692a | 2009-05-28 13:41:44 +0000 | [diff] [blame] | 2582 | if (ngx_strcmp(value[1].data, "off") == 0) { |
| 2583 | plcf->upstream.store = 0; |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 2584 | return NGX_CONF_OK; |
| 2585 | } |
| 2586 | |
Igor Sysoev | 98f692a | 2009-05-28 13:41:44 +0000 | [diff] [blame] | 2587 | #if (NGX_HTTP_CACHE) |
| 2588 | |
| 2589 | if (plcf->upstream.cache != NGX_CONF_UNSET_PTR |
| 2590 | && plcf->upstream.cache != NULL) |
| 2591 | { |
| 2592 | return "is incompatible with \"proxy_cache\""; |
| 2593 | } |
| 2594 | |
| 2595 | #endif |
| 2596 | |
| 2597 | if (ngx_strcmp(value[1].data, "on") == 0) { |
| 2598 | plcf->upstream.store = 1; |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 2599 | return NGX_CONF_OK; |
| 2600 | } |
| 2601 | |
| 2602 | /* include the terminating '\0' into script */ |
| 2603 | value[1].len++; |
| 2604 | |
| 2605 | ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
| 2606 | |
| 2607 | sc.cf = cf; |
| 2608 | sc.source = &value[1]; |
| 2609 | sc.lengths = &plcf->upstream.store_lengths; |
| 2610 | sc.values = &plcf->upstream.store_values; |
Igor Sysoev | bfb23bf | 2007-10-09 20:11:03 +0000 | [diff] [blame] | 2611 | sc.variables = ngx_http_script_variables_count(&value[1]); |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 2612 | sc.complete_lengths = 1; |
| 2613 | sc.complete_values = 1; |
| 2614 | |
| 2615 | if (ngx_http_script_compile(&sc) != NGX_OK) { |
| 2616 | return NGX_CONF_ERROR; |
| 2617 | } |
| 2618 | |
| 2619 | return NGX_CONF_OK; |
| 2620 | } |
| 2621 | |
| 2622 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2623 | #if (NGX_HTTP_CACHE) |
| 2624 | |
| 2625 | static char * |
| 2626 | ngx_http_proxy_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
| 2627 | { |
| 2628 | ngx_http_proxy_loc_conf_t *plcf = conf; |
| 2629 | |
| 2630 | ngx_str_t *value; |
| 2631 | |
| 2632 | value = cf->args->elts; |
| 2633 | |
| 2634 | if (plcf->upstream.cache != NGX_CONF_UNSET_PTR) { |
| 2635 | return "is duplicate"; |
| 2636 | } |
| 2637 | |
| 2638 | if (ngx_strcmp(value[1].data, "off") == 0) { |
| 2639 | plcf->upstream.cache = NULL; |
| 2640 | return NGX_CONF_OK; |
| 2641 | } |
| 2642 | |
Igor Sysoev | 98f692a | 2009-05-28 13:41:44 +0000 | [diff] [blame] | 2643 | if (plcf->upstream.store > 0 || plcf->upstream.store_lengths) { |
| 2644 | return "is incompatible with \"proxy_store\""; |
| 2645 | } |
| 2646 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2647 | plcf->upstream.cache = ngx_shared_memory_add(cf, &value[1], 0, |
| 2648 | &ngx_http_proxy_module); |
| 2649 | if (plcf->upstream.cache == NULL) { |
| 2650 | return NGX_CONF_ERROR; |
| 2651 | } |
| 2652 | |
| 2653 | return NGX_CONF_OK; |
| 2654 | } |
| 2655 | |
Igor Sysoev | 44a69c8 | 2009-04-06 08:58:44 +0000 | [diff] [blame] | 2656 | |
| 2657 | static char * |
| 2658 | ngx_http_proxy_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
| 2659 | { |
| 2660 | ngx_http_proxy_loc_conf_t *plcf = conf; |
| 2661 | |
| 2662 | ngx_str_t *value; |
| 2663 | ngx_http_compile_complex_value_t ccv; |
| 2664 | |
| 2665 | value = cf->args->elts; |
| 2666 | |
| 2667 | if (plcf->cache_key.value.len) { |
| 2668 | return "is duplicate"; |
| 2669 | } |
| 2670 | |
| 2671 | ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
| 2672 | |
| 2673 | ccv.cf = cf; |
| 2674 | ccv.value = &value[1]; |
| 2675 | ccv.complex_value = &plcf->cache_key; |
| 2676 | |
| 2677 | if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
| 2678 | return NGX_CONF_ERROR; |
| 2679 | } |
| 2680 | |
| 2681 | return NGX_CONF_OK; |
| 2682 | } |
| 2683 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2684 | #endif |
| 2685 | |
| 2686 | |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 2687 | static char * |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2688 | ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data) |
| 2689 | { |
| 2690 | #if (NGX_FREEBSD) |
| 2691 | ssize_t *np = data; |
| 2692 | |
Igor Sysoev | 08e63d4 | 2006-08-14 15:09:38 +0000 | [diff] [blame] | 2693 | if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2694 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 2695 | "\"proxy_send_lowat\" must be less than %d " |
| 2696 | "(sysctl net.inet.tcp.sendspace)", |
| 2697 | ngx_freebsd_net_inet_tcp_sendspace); |
| 2698 | |
| 2699 | return NGX_CONF_ERROR; |
| 2700 | } |
| 2701 | |
| 2702 | #elif !(NGX_HAVE_SO_SNDLOWAT) |
| 2703 | ssize_t *np = data; |
| 2704 | |
| 2705 | ngx_conf_log_error(NGX_LOG_WARN, cf, 0, |
| 2706 | "\"proxy_send_lowat\" is not supported, ignored"); |
| 2707 | |
| 2708 | *np = 0; |
| 2709 | |
| 2710 | #endif |
| 2711 | |
| 2712 | return NGX_CONF_OK; |
| 2713 | } |
Igor Sysoev | 3d2fd18 | 2006-12-04 16:46:13 +0000 | [diff] [blame] | 2714 | |
| 2715 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2716 | #if (NGX_HTTP_SSL) |
| 2717 | |
| 2718 | static ngx_int_t |
| 2719 | ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf) |
| 2720 | { |
| 2721 | ngx_pool_cleanup_t *cln; |
| 2722 | |
| 2723 | plcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t)); |
| 2724 | if (plcf->upstream.ssl == NULL) { |
| 2725 | return NGX_ERROR; |
| 2726 | } |
| 2727 | |
| 2728 | plcf->upstream.ssl->log = cf->log; |
| 2729 | |
| 2730 | if (ngx_ssl_create(plcf->upstream.ssl, |
| 2731 | NGX_SSL_SSLv2|NGX_SSL_SSLv3|NGX_SSL_TLSv1, NULL) |
| 2732 | != NGX_OK) |
| 2733 | { |
| 2734 | return NGX_ERROR; |
| 2735 | } |
| 2736 | |
| 2737 | cln = ngx_pool_cleanup_add(cf->pool, 0); |
| 2738 | if (cln == NULL) { |
| 2739 | return NGX_ERROR; |
| 2740 | } |
| 2741 | |
| 2742 | cln->handler = ngx_ssl_cleanup_ctx; |
| 2743 | cln->data = plcf->upstream.ssl; |
| 2744 | |
| 2745 | return NGX_OK; |
| 2746 | } |
| 2747 | |
| 2748 | #endif |
| 2749 | |
| 2750 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2751 | static void |
| 2752 | ngx_http_proxy_set_vars(ngx_url_t *u, ngx_http_proxy_vars_t *v) |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2753 | { |
Igor Sysoev | c9491d1 | 2008-08-26 14:24:14 +0000 | [diff] [blame] | 2754 | if (u->family != AF_UNIX) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2755 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2756 | if (u->no_port || u->port == u->default_port) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2757 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2758 | v->host_header = u->host; |
| 2759 | |
| 2760 | if (u->default_port == 80) { |
Igor Sysoev | 05b1a8f | 2010-05-14 09:56:37 +0000 | [diff] [blame] | 2761 | ngx_str_set(&v->port, "80"); |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2762 | |
| 2763 | } else { |
Igor Sysoev | 05b1a8f | 2010-05-14 09:56:37 +0000 | [diff] [blame] | 2764 | ngx_str_set(&v->port, "443"); |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2765 | } |
| 2766 | |
| 2767 | } else { |
Igor Sysoev | 00e0377 | 2007-11-28 19:55:31 +0000 | [diff] [blame] | 2768 | v->host_header.len = u->host.len + 1 + u->port_text.len; |
| 2769 | v->host_header.data = u->host.data; |
| 2770 | v->port = u->port_text; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2771 | } |
| 2772 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2773 | v->key_start.len += v->host_header.len; |
| 2774 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2775 | } else { |
Igor Sysoev | 05b1a8f | 2010-05-14 09:56:37 +0000 | [diff] [blame] | 2776 | ngx_str_set(&v->host_header, "localhost"); |
| 2777 | ngx_str_null(&v->port); |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2778 | v->key_start.len += sizeof("unix:") - 1 + u->host.len + 1; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2779 | } |
| 2780 | |
| 2781 | v->uri = u->uri; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2782 | } |