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 |
Maxim Konovalov | f8d59e3 | 2012-01-18 15:07:43 +0000 | [diff] [blame] | 4 | * Copyright (C) Nginx, Inc. |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 5 | */ |
| 6 | |
| 7 | |
| 8 | #include <ngx_config.h> |
| 9 | #include <ngx_core.h> |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 10 | #include <ngx_http.h> |
| 11 | |
| 12 | |
Valentin Bartenev | 9a0eb4f | 2014-12-22 12:59:09 +0300 | [diff] [blame] | 13 | typedef struct { |
| 14 | ngx_array_t caches; /* ngx_http_file_cache_t * */ |
| 15 | } ngx_http_proxy_main_conf_t; |
| 16 | |
| 17 | |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 18 | typedef struct ngx_http_proxy_rewrite_s ngx_http_proxy_rewrite_t; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 19 | |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 20 | typedef ngx_int_t (*ngx_http_proxy_rewrite_pt)(ngx_http_request_t *r, |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 21 | ngx_table_elt_t *h, size_t prefix, size_t len, |
| 22 | ngx_http_proxy_rewrite_t *pr); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 23 | |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 24 | struct ngx_http_proxy_rewrite_s { |
| 25 | ngx_http_proxy_rewrite_pt handler; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 26 | |
| 27 | union { |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 28 | ngx_http_complex_value_t complex; |
| 29 | #if (NGX_PCRE) |
| 30 | ngx_http_regex_t *regex; |
| 31 | #endif |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 32 | } pattern; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 33 | |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 34 | ngx_http_complex_value_t replacement; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 35 | }; |
| 36 | |
| 37 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 38 | typedef struct { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 39 | ngx_str_t key_start; |
Igor Sysoev | 73c3121 | 2008-12-10 14:44:48 +0000 | [diff] [blame] | 40 | ngx_str_t schema; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 41 | ngx_str_t host_header; |
| 42 | ngx_str_t port; |
| 43 | ngx_str_t uri; |
| 44 | } ngx_http_proxy_vars_t; |
| 45 | |
| 46 | |
| 47 | typedef struct { |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 48 | ngx_array_t *flushes; |
| 49 | ngx_array_t *lengths; |
| 50 | ngx_array_t *values; |
| 51 | ngx_hash_t hash; |
| 52 | } ngx_http_proxy_headers_t; |
| 53 | |
| 54 | |
| 55 | typedef struct { |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 56 | ngx_http_upstream_conf_t upstream; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 57 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 58 | ngx_array_t *body_flushes; |
Roman Arutyunyan | 1b79cb2 | 2014-11-19 17:33:24 +0300 | [diff] [blame] | 59 | ngx_array_t *body_lengths; |
| 60 | ngx_array_t *body_values; |
| 61 | ngx_str_t body_source; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 62 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 63 | ngx_http_proxy_headers_t headers; |
Roman Arutyunyan | 8898c97 | 2014-11-19 17:33:23 +0300 | [diff] [blame] | 64 | #if (NGX_HTTP_CACHE) |
| 65 | ngx_http_proxy_headers_t headers_cache; |
| 66 | #endif |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 67 | ngx_array_t *headers_source; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 68 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 69 | ngx_array_t *proxy_lengths; |
| 70 | ngx_array_t *proxy_values; |
| 71 | |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 72 | ngx_array_t *redirects; |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 73 | ngx_array_t *cookie_domains; |
Valentin Bartenev | a113cb3 | 2012-02-13 11:08:05 +0000 | [diff] [blame] | 74 | ngx_array_t *cookie_paths; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 75 | |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 76 | ngx_str_t method; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 77 | ngx_str_t location; |
| 78 | ngx_str_t url; |
| 79 | |
Igor Sysoev | 44a69c8 | 2009-04-06 08:58:44 +0000 | [diff] [blame] | 80 | #if (NGX_HTTP_CACHE) |
| 81 | ngx_http_complex_value_t cache_key; |
| 82 | #endif |
| 83 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 84 | ngx_http_proxy_vars_t vars; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 85 | |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 86 | ngx_flag_t redirect; |
Igor Sysoev | 8a19bff | 2007-04-22 20:21:59 +0000 | [diff] [blame] | 87 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 88 | ngx_uint_t http_version; |
| 89 | |
Igor Sysoev | 8a19bff | 2007-04-22 20:21:59 +0000 | [diff] [blame] | 90 | ngx_uint_t headers_hash_max_size; |
| 91 | ngx_uint_t headers_hash_bucket_size; |
Andrei Belov | 003b2cd | 2013-09-19 18:30:33 +0400 | [diff] [blame] | 92 | |
| 93 | #if (NGX_HTTP_SSL) |
| 94 | ngx_uint_t ssl; |
| 95 | ngx_uint_t ssl_protocols; |
Piotr Sikora | 43736b1 | 2013-09-23 15:58:28 -0700 | [diff] [blame] | 96 | ngx_str_t ssl_ciphers; |
Maxim Dounin | 27475dd | 2014-04-18 20:13:30 +0400 | [diff] [blame] | 97 | ngx_uint_t ssl_verify_depth; |
| 98 | ngx_str_t ssl_trusted_certificate; |
| 99 | ngx_str_t ssl_crl; |
Piotr Sikora | a9d9b09 | 2014-10-30 04:30:41 -0700 | [diff] [blame] | 100 | ngx_str_t ssl_certificate; |
| 101 | ngx_str_t ssl_certificate_key; |
| 102 | ngx_array_t *ssl_passwords; |
Andrei Belov | 003b2cd | 2013-09-19 18:30:33 +0400 | [diff] [blame] | 103 | #endif |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 104 | } ngx_http_proxy_loc_conf_t; |
| 105 | |
| 106 | |
| 107 | typedef struct { |
Igor Sysoev | 54b35b0 | 2010-06-15 15:15:06 +0000 | [diff] [blame] | 108 | ngx_http_status_t status; |
Maxim Dounin | df74d88 | 2012-11-21 00:59:16 +0000 | [diff] [blame] | 109 | ngx_http_chunked_t chunked; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 110 | ngx_http_proxy_vars_t vars; |
Maxim Dounin | 9a483c8 | 2012-11-21 01:03:48 +0000 | [diff] [blame] | 111 | off_t internal_body_length; |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 112 | |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 113 | ngx_chain_t *free; |
| 114 | ngx_chain_t *busy; |
| 115 | |
| 116 | unsigned head:1; |
| 117 | unsigned internal_chunked:1; |
| 118 | unsigned header_sent:1; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 119 | } ngx_http_proxy_ctx_t; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 120 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 121 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 122 | static ngx_int_t ngx_http_proxy_eval(ngx_http_request_t *r, |
| 123 | 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] | 124 | #if (NGX_HTTP_CACHE) |
| 125 | static ngx_int_t ngx_http_proxy_create_key(ngx_http_request_t *r); |
| 126 | #endif |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 127 | static ngx_int_t ngx_http_proxy_create_request(ngx_http_request_t *r); |
| 128 | static ngx_int_t ngx_http_proxy_reinit_request(ngx_http_request_t *r); |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 129 | static ngx_int_t ngx_http_proxy_body_output_filter(void *data, ngx_chain_t *in); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 130 | 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] | 131 | static ngx_int_t ngx_http_proxy_process_header(ngx_http_request_t *r); |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 132 | static ngx_int_t ngx_http_proxy_input_filter_init(void *data); |
| 133 | static ngx_int_t ngx_http_proxy_copy_filter(ngx_event_pipe_t *p, |
| 134 | ngx_buf_t *buf); |
| 135 | static ngx_int_t ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, |
| 136 | ngx_buf_t *buf); |
| 137 | static ngx_int_t ngx_http_proxy_non_buffered_copy_filter(void *data, |
| 138 | ssize_t bytes); |
| 139 | static ngx_int_t ngx_http_proxy_non_buffered_chunked_filter(void *data, |
| 140 | ssize_t bytes); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 141 | static void ngx_http_proxy_abort_request(ngx_http_request_t *r); |
| 142 | static void ngx_http_proxy_finalize_request(ngx_http_request_t *r, |
| 143 | ngx_int_t rc); |
| 144 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 145 | static ngx_int_t ngx_http_proxy_host_variable(ngx_http_request_t *r, |
| 146 | ngx_http_variable_value_t *v, uintptr_t data); |
| 147 | static ngx_int_t ngx_http_proxy_port_variable(ngx_http_request_t *r, |
| 148 | ngx_http_variable_value_t *v, uintptr_t data); |
| 149 | static ngx_int_t |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 150 | 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] | 151 | ngx_http_variable_value_t *v, uintptr_t data); |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 152 | static ngx_int_t |
| 153 | ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r, |
| 154 | ngx_http_variable_value_t *v, uintptr_t data); |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 155 | static ngx_int_t ngx_http_proxy_internal_chunked_variable(ngx_http_request_t *r, |
| 156 | ngx_http_variable_value_t *v, uintptr_t data); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 157 | static ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, |
| 158 | ngx_table_elt_t *h, size_t prefix); |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 159 | static ngx_int_t ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r, |
| 160 | ngx_table_elt_t *h); |
| 161 | static ngx_int_t ngx_http_proxy_rewrite_cookie_value(ngx_http_request_t *r, |
| 162 | ngx_table_elt_t *h, u_char *value, ngx_array_t *rewrites); |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 163 | static ngx_int_t ngx_http_proxy_rewrite(ngx_http_request_t *r, |
| 164 | ngx_table_elt_t *h, size_t prefix, size_t len, ngx_str_t *replacement); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 165 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 166 | static ngx_int_t ngx_http_proxy_add_variables(ngx_conf_t *cf); |
Valentin Bartenev | 9a0eb4f | 2014-12-22 12:59:09 +0300 | [diff] [blame] | 167 | static void *ngx_http_proxy_create_main_conf(ngx_conf_t *cf); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 168 | static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf); |
| 169 | static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, |
| 170 | void *parent, void *child); |
Roman Arutyunyan | 62dfdf1 | 2014-11-19 17:33:21 +0300 | [diff] [blame] | 171 | static ngx_int_t ngx_http_proxy_init_headers(ngx_conf_t *cf, |
Roman Arutyunyan | 8898c97 | 2014-11-19 17:33:23 +0300 | [diff] [blame] | 172 | ngx_http_proxy_loc_conf_t *conf, ngx_http_proxy_headers_t *headers, |
| 173 | ngx_keyval_t *default_headers); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 174 | |
| 175 | static char *ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, |
| 176 | void *conf); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 177 | 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] | 178 | void *conf); |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 179 | static char *ngx_http_proxy_cookie_domain(ngx_conf_t *cf, ngx_command_t *cmd, |
| 180 | void *conf); |
Valentin Bartenev | a113cb3 | 2012-02-13 11:08:05 +0000 | [diff] [blame] | 181 | static char *ngx_http_proxy_cookie_path(ngx_conf_t *cf, ngx_command_t *cmd, |
| 182 | void *conf); |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 183 | static char *ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, |
| 184 | void *conf); |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 185 | #if (NGX_HTTP_CACHE) |
| 186 | static char *ngx_http_proxy_cache(ngx_conf_t *cf, ngx_command_t *cmd, |
| 187 | void *conf); |
Igor Sysoev | 44a69c8 | 2009-04-06 08:58:44 +0000 | [diff] [blame] | 188 | static char *ngx_http_proxy_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, |
| 189 | void *conf); |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 190 | #endif |
Piotr Sikora | a9d9b09 | 2014-10-30 04:30:41 -0700 | [diff] [blame] | 191 | #if (NGX_HTTP_SSL) |
| 192 | static char *ngx_http_proxy_ssl_password_file(ngx_conf_t *cf, |
| 193 | ngx_command_t *cmd, void *conf); |
| 194 | #endif |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 195 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 196 | static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data); |
| 197 | |
Valentin Bartenev | 85551e5 | 2012-02-13 11:00:08 +0000 | [diff] [blame] | 198 | static ngx_int_t ngx_http_proxy_rewrite_regex(ngx_conf_t *cf, |
| 199 | ngx_http_proxy_rewrite_t *pr, ngx_str_t *regex, ngx_uint_t caseless); |
| 200 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 201 | #if (NGX_HTTP_SSL) |
| 202 | static ngx_int_t ngx_http_proxy_set_ssl(ngx_conf_t *cf, |
| 203 | ngx_http_proxy_loc_conf_t *plcf); |
| 204 | #endif |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 205 | 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] | 206 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 207 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 208 | static ngx_conf_post_t ngx_http_proxy_lowat_post = |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 209 | { ngx_http_proxy_lowat_check }; |
| 210 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 211 | |
| 212 | static ngx_conf_bitmask_t ngx_http_proxy_next_upstream_masks[] = { |
| 213 | { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR }, |
| 214 | { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT }, |
| 215 | { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER }, |
Maxim Dounin | 35062c6 | 2016-03-28 19:50:19 +0300 | [diff] [blame] | 216 | { ngx_string("non_idempotent"), NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT }, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 217 | { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 }, |
Igor Sysoev | 797c6ef | 2008-09-30 15:39:02 +0000 | [diff] [blame] | 218 | { ngx_string("http_502"), NGX_HTTP_UPSTREAM_FT_HTTP_502 }, |
Igor Sysoev | 8fea885 | 2006-03-15 09:53:04 +0000 | [diff] [blame] | 219 | { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 }, |
Igor Sysoev | 797c6ef | 2008-09-30 15:39:02 +0000 | [diff] [blame] | 220 | { ngx_string("http_504"), NGX_HTTP_UPSTREAM_FT_HTTP_504 }, |
Maxim Dounin | 1a983a0 | 2013-05-27 16:54:09 +0400 | [diff] [blame] | 221 | { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 }, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 222 | { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 }, |
Igor Sysoev | 55192e7 | 2009-06-06 18:49:47 +0000 | [diff] [blame] | 223 | { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING }, |
Igor Sysoev | bb28b6d | 2006-07-11 13:20:19 +0000 | [diff] [blame] | 224 | { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF }, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 225 | { ngx_null_string, 0 } |
| 226 | }; |
| 227 | |
| 228 | |
Andrei Belov | 003b2cd | 2013-09-19 18:30:33 +0400 | [diff] [blame] | 229 | #if (NGX_HTTP_SSL) |
| 230 | |
| 231 | static ngx_conf_bitmask_t ngx_http_proxy_ssl_protocols[] = { |
| 232 | { ngx_string("SSLv2"), NGX_SSL_SSLv2 }, |
| 233 | { ngx_string("SSLv3"), NGX_SSL_SSLv3 }, |
| 234 | { ngx_string("TLSv1"), NGX_SSL_TLSv1 }, |
| 235 | { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 }, |
| 236 | { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 }, |
| 237 | { ngx_null_string, 0 } |
| 238 | }; |
| 239 | |
| 240 | #endif |
| 241 | |
| 242 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 243 | static ngx_conf_enum_t ngx_http_proxy_http_version[] = { |
| 244 | { ngx_string("1.0"), NGX_HTTP_VERSION_10 }, |
| 245 | { ngx_string("1.1"), NGX_HTTP_VERSION_11 }, |
| 246 | { ngx_null_string, 0 } |
| 247 | }; |
| 248 | |
| 249 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 250 | ngx_module_t ngx_http_proxy_module; |
| 251 | |
| 252 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 253 | static ngx_command_t ngx_http_proxy_commands[] = { |
| 254 | |
| 255 | { ngx_string("proxy_pass"), |
Igor Sysoev | e927b1e | 2006-11-14 12:43:14 +0000 | [diff] [blame] | 256 | 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] | 257 | ngx_http_proxy_pass, |
| 258 | NGX_HTTP_LOC_CONF_OFFSET, |
| 259 | 0, |
| 260 | NULL }, |
| 261 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 262 | { ngx_string("proxy_redirect"), |
| 263 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, |
| 264 | ngx_http_proxy_redirect, |
| 265 | NGX_HTTP_LOC_CONF_OFFSET, |
| 266 | 0, |
| 267 | NULL }, |
| 268 | |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 269 | { ngx_string("proxy_cookie_domain"), |
| 270 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, |
| 271 | ngx_http_proxy_cookie_domain, |
| 272 | NGX_HTTP_LOC_CONF_OFFSET, |
| 273 | 0, |
| 274 | NULL }, |
| 275 | |
Valentin Bartenev | a113cb3 | 2012-02-13 11:08:05 +0000 | [diff] [blame] | 276 | { ngx_string("proxy_cookie_path"), |
| 277 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12, |
| 278 | ngx_http_proxy_cookie_path, |
| 279 | NGX_HTTP_LOC_CONF_OFFSET, |
| 280 | 0, |
| 281 | NULL }, |
| 282 | |
Igor Sysoev | 58feb53 | 2007-07-12 11:19:05 +0000 | [diff] [blame] | 283 | { ngx_string("proxy_store"), |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 284 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 285 | ngx_http_proxy_store, |
| 286 | NGX_HTTP_LOC_CONF_OFFSET, |
| 287 | 0, |
| 288 | NULL }, |
| 289 | |
| 290 | { ngx_string("proxy_store_access"), |
Igor Sysoev | 58feb53 | 2007-07-12 11:19:05 +0000 | [diff] [blame] | 291 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123, |
| 292 | ngx_conf_set_access_slot, |
| 293 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 294 | offsetof(ngx_http_proxy_loc_conf_t, upstream.store_access), |
Igor Sysoev | 58feb53 | 2007-07-12 11:19:05 +0000 | [diff] [blame] | 295 | NULL }, |
| 296 | |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 297 | { ngx_string("proxy_buffering"), |
| 298 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 299 | ngx_conf_set_flag_slot, |
| 300 | NGX_HTTP_LOC_CONF_OFFSET, |
| 301 | offsetof(ngx_http_proxy_loc_conf_t, upstream.buffering), |
| 302 | NULL }, |
| 303 | |
Maxim Dounin | f568ff8 | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 304 | { ngx_string("proxy_request_buffering"), |
| 305 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 306 | ngx_conf_set_flag_slot, |
| 307 | NGX_HTTP_LOC_CONF_OFFSET, |
| 308 | offsetof(ngx_http_proxy_loc_conf_t, upstream.request_buffering), |
| 309 | NULL }, |
| 310 | |
Igor Sysoev | 6d16e1e | 2006-04-05 13:40:54 +0000 | [diff] [blame] | 311 | { ngx_string("proxy_ignore_client_abort"), |
| 312 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 313 | ngx_conf_set_flag_slot, |
| 314 | NGX_HTTP_LOC_CONF_OFFSET, |
| 315 | offsetof(ngx_http_proxy_loc_conf_t, upstream.ignore_client_abort), |
| 316 | NULL }, |
| 317 | |
Igor Sysoev | 72e9287 | 2009-11-02 15:24:02 +0000 | [diff] [blame] | 318 | { ngx_string("proxy_bind"), |
| 319 | 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] | 320 | ngx_http_upstream_bind_set_slot, |
Igor Sysoev | 72e9287 | 2009-11-02 15:24:02 +0000 | [diff] [blame] | 321 | NGX_HTTP_LOC_CONF_OFFSET, |
| 322 | offsetof(ngx_http_proxy_loc_conf_t, upstream.local), |
| 323 | NULL }, |
| 324 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 325 | { ngx_string("proxy_connect_timeout"), |
| 326 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 327 | ngx_conf_set_msec_slot, |
| 328 | NGX_HTTP_LOC_CONF_OFFSET, |
| 329 | offsetof(ngx_http_proxy_loc_conf_t, upstream.connect_timeout), |
| 330 | NULL }, |
| 331 | |
| 332 | { ngx_string("proxy_send_timeout"), |
| 333 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 334 | ngx_conf_set_msec_slot, |
| 335 | NGX_HTTP_LOC_CONF_OFFSET, |
| 336 | offsetof(ngx_http_proxy_loc_conf_t, upstream.send_timeout), |
| 337 | NULL }, |
| 338 | |
| 339 | { ngx_string("proxy_send_lowat"), |
| 340 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 341 | ngx_conf_set_size_slot, |
| 342 | NGX_HTTP_LOC_CONF_OFFSET, |
| 343 | offsetof(ngx_http_proxy_loc_conf_t, upstream.send_lowat), |
| 344 | &ngx_http_proxy_lowat_post }, |
| 345 | |
Igor Sysoev | ef809b8 | 2006-06-28 16:00:26 +0000 | [diff] [blame] | 346 | { ngx_string("proxy_intercept_errors"), |
| 347 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 348 | ngx_conf_set_flag_slot, |
| 349 | NGX_HTTP_LOC_CONF_OFFSET, |
| 350 | offsetof(ngx_http_proxy_loc_conf_t, upstream.intercept_errors), |
| 351 | NULL }, |
| 352 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 353 | { ngx_string("proxy_set_header"), |
| 354 | 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] | 355 | ngx_conf_set_keyval_slot, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 356 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 357 | offsetof(ngx_http_proxy_loc_conf_t, headers_source), |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 358 | NULL }, |
| 359 | |
Igor Sysoev | 8a19bff | 2007-04-22 20:21:59 +0000 | [diff] [blame] | 360 | { ngx_string("proxy_headers_hash_max_size"), |
| 361 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 362 | ngx_conf_set_num_slot, |
| 363 | NGX_HTTP_LOC_CONF_OFFSET, |
| 364 | offsetof(ngx_http_proxy_loc_conf_t, headers_hash_max_size), |
| 365 | NULL }, |
| 366 | |
| 367 | { ngx_string("proxy_headers_hash_bucket_size"), |
| 368 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 369 | ngx_conf_set_num_slot, |
| 370 | NGX_HTTP_LOC_CONF_OFFSET, |
| 371 | offsetof(ngx_http_proxy_loc_conf_t, headers_hash_bucket_size), |
| 372 | NULL }, |
| 373 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 374 | { ngx_string("proxy_set_body"), |
| 375 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 376 | ngx_conf_set_str_slot, |
| 377 | NGX_HTTP_LOC_CONF_OFFSET, |
| 378 | offsetof(ngx_http_proxy_loc_conf_t, body_source), |
| 379 | NULL }, |
| 380 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 381 | { ngx_string("proxy_method"), |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 382 | 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] | 383 | ngx_conf_set_str_slot, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 384 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 385 | offsetof(ngx_http_proxy_loc_conf_t, method), |
| 386 | NULL }, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 387 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 388 | { ngx_string("proxy_pass_request_headers"), |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 389 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 390 | ngx_conf_set_flag_slot, |
| 391 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 392 | offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_request_headers), |
| 393 | NULL }, |
| 394 | |
| 395 | { ngx_string("proxy_pass_request_body"), |
| 396 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 397 | ngx_conf_set_flag_slot, |
| 398 | NGX_HTTP_LOC_CONF_OFFSET, |
| 399 | offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_request_body), |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 400 | NULL }, |
| 401 | |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 402 | { ngx_string("proxy_buffer_size"), |
| 403 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 404 | ngx_conf_set_size_slot, |
| 405 | NGX_HTTP_LOC_CONF_OFFSET, |
| 406 | offsetof(ngx_http_proxy_loc_conf_t, upstream.buffer_size), |
| 407 | NULL }, |
| 408 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 409 | { ngx_string("proxy_read_timeout"), |
| 410 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 411 | ngx_conf_set_msec_slot, |
| 412 | NGX_HTTP_LOC_CONF_OFFSET, |
| 413 | offsetof(ngx_http_proxy_loc_conf_t, upstream.read_timeout), |
| 414 | NULL }, |
| 415 | |
| 416 | { ngx_string("proxy_buffers"), |
| 417 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, |
| 418 | ngx_conf_set_bufs_slot, |
| 419 | NGX_HTTP_LOC_CONF_OFFSET, |
| 420 | offsetof(ngx_http_proxy_loc_conf_t, upstream.bufs), |
| 421 | NULL }, |
| 422 | |
| 423 | { ngx_string("proxy_busy_buffers_size"), |
| 424 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 425 | ngx_conf_set_size_slot, |
| 426 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 427 | offsetof(ngx_http_proxy_loc_conf_t, upstream.busy_buffers_size_conf), |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 428 | NULL }, |
| 429 | |
Roman Arutyunyan | 2244a5e | 2014-10-14 18:32:01 +0400 | [diff] [blame] | 430 | { ngx_string("proxy_force_ranges"), |
| 431 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 432 | ngx_conf_set_flag_slot, |
| 433 | NGX_HTTP_LOC_CONF_OFFSET, |
| 434 | offsetof(ngx_http_proxy_loc_conf_t, upstream.force_ranges), |
| 435 | NULL }, |
| 436 | |
Roman Arutyunyan | 18e4d04 | 2014-10-28 12:29:59 +0300 | [diff] [blame] | 437 | { ngx_string("proxy_limit_rate"), |
| 438 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 439 | ngx_conf_set_size_slot, |
| 440 | NGX_HTTP_LOC_CONF_OFFSET, |
| 441 | offsetof(ngx_http_proxy_loc_conf_t, upstream.limit_rate), |
| 442 | NULL }, |
| 443 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 444 | #if (NGX_HTTP_CACHE) |
| 445 | |
| 446 | { ngx_string("proxy_cache"), |
Igor Sysoev | 6d9d07b | 2010-08-02 12:47:52 +0000 | [diff] [blame] | 447 | 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] | 448 | ngx_http_proxy_cache, |
Igor Sysoev | 0ded9db | 2009-03-23 16:40:11 +0000 | [diff] [blame] | 449 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 64416aa | 2009-03-23 15:57:57 +0000 | [diff] [blame] | 450 | 0, |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 451 | NULL }, |
| 452 | |
Igor Sysoev | 44a69c8 | 2009-04-06 08:58:44 +0000 | [diff] [blame] | 453 | { ngx_string("proxy_cache_key"), |
Igor Sysoev | 6d9d07b | 2010-08-02 12:47:52 +0000 | [diff] [blame] | 454 | 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] | 455 | ngx_http_proxy_cache_key, |
| 456 | NGX_HTTP_LOC_CONF_OFFSET, |
| 457 | 0, |
| 458 | NULL }, |
| 459 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 460 | { ngx_string("proxy_cache_path"), |
| 461 | NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE, |
| 462 | ngx_http_file_cache_set_slot, |
Valentin Bartenev | 9a0eb4f | 2014-12-22 12:59:09 +0300 | [diff] [blame] | 463 | NGX_HTTP_MAIN_CONF_OFFSET, |
| 464 | offsetof(ngx_http_proxy_main_conf_t, caches), |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 465 | &ngx_http_proxy_module }, |
| 466 | |
Igor Sysoev | f7d659a | 2010-07-19 09:36:04 +0000 | [diff] [blame] | 467 | { ngx_string("proxy_cache_bypass"), |
| 468 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
| 469 | ngx_http_set_predicate_slot, |
| 470 | NGX_HTTP_LOC_CONF_OFFSET, |
| 471 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_bypass), |
| 472 | NULL }, |
| 473 | |
Igor Sysoev | 9b2763a | 2010-05-24 11:01:05 +0000 | [diff] [blame] | 474 | { ngx_string("proxy_no_cache"), |
| 475 | 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] | 476 | ngx_http_set_predicate_slot, |
Igor Sysoev | 9b2763a | 2010-05-24 11:01:05 +0000 | [diff] [blame] | 477 | NGX_HTTP_LOC_CONF_OFFSET, |
| 478 | offsetof(ngx_http_proxy_loc_conf_t, upstream.no_cache), |
| 479 | NULL }, |
| 480 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 481 | { ngx_string("proxy_cache_valid"), |
| 482 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
| 483 | ngx_http_file_cache_valid_set_slot, |
| 484 | NGX_HTTP_LOC_CONF_OFFSET, |
| 485 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_valid), |
| 486 | NULL }, |
| 487 | |
| 488 | { ngx_string("proxy_cache_min_uses"), |
| 489 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 490 | ngx_conf_set_num_slot, |
| 491 | NGX_HTTP_LOC_CONF_OFFSET, |
| 492 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_min_uses), |
| 493 | NULL }, |
| 494 | |
| 495 | { ngx_string("proxy_cache_use_stale"), |
| 496 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
| 497 | ngx_conf_set_bitmask_slot, |
| 498 | NGX_HTTP_LOC_CONF_OFFSET, |
| 499 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_use_stale), |
| 500 | &ngx_http_proxy_next_upstream_masks }, |
| 501 | |
Igor Sysoev | 5ed3691 | 2009-05-19 13:27:27 +0000 | [diff] [blame] | 502 | { ngx_string("proxy_cache_methods"), |
| 503 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
| 504 | ngx_conf_set_bitmask_slot, |
| 505 | NGX_HTTP_LOC_CONF_OFFSET, |
| 506 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_methods), |
| 507 | &ngx_http_upstream_cache_method_mask }, |
| 508 | |
Maxim Dounin | 822fe46 | 2011-12-26 11:15:23 +0000 | [diff] [blame] | 509 | { ngx_string("proxy_cache_lock"), |
| 510 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 511 | ngx_conf_set_flag_slot, |
| 512 | NGX_HTTP_LOC_CONF_OFFSET, |
| 513 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_lock), |
| 514 | NULL }, |
| 515 | |
| 516 | { ngx_string("proxy_cache_lock_timeout"), |
| 517 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 518 | ngx_conf_set_msec_slot, |
| 519 | NGX_HTTP_LOC_CONF_OFFSET, |
| 520 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_lock_timeout), |
| 521 | NULL }, |
| 522 | |
Roman Arutyunyan | 2628cc1 | 2014-11-18 20:41:12 +0300 | [diff] [blame] | 523 | { ngx_string("proxy_cache_lock_age"), |
| 524 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 525 | ngx_conf_set_msec_slot, |
| 526 | NGX_HTTP_LOC_CONF_OFFSET, |
| 527 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_lock_age), |
| 528 | NULL }, |
| 529 | |
Maxim Dounin | 1ac2693 | 2013-11-18 20:48:22 +0400 | [diff] [blame] | 530 | { ngx_string("proxy_cache_revalidate"), |
| 531 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 532 | ngx_conf_set_flag_slot, |
| 533 | NGX_HTTP_LOC_CONF_OFFSET, |
| 534 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_revalidate), |
| 535 | NULL }, |
| 536 | |
Roman Arutyunyan | f0ee4eb | 2015-11-11 15:47:30 +0300 | [diff] [blame] | 537 | { ngx_string("proxy_cache_convert_head"), |
| 538 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 539 | ngx_conf_set_flag_slot, |
| 540 | NGX_HTTP_LOC_CONF_OFFSET, |
| 541 | offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_convert_head), |
| 542 | NULL }, |
| 543 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 544 | #endif |
| 545 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 546 | { ngx_string("proxy_temp_path"), |
| 547 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234, |
| 548 | ngx_conf_set_path_slot, |
| 549 | NGX_HTTP_LOC_CONF_OFFSET, |
| 550 | offsetof(ngx_http_proxy_loc_conf_t, upstream.temp_path), |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 551 | NULL }, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 552 | |
| 553 | { ngx_string("proxy_max_temp_file_size"), |
| 554 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 555 | ngx_conf_set_size_slot, |
| 556 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 557 | 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] | 558 | NULL }, |
| 559 | |
| 560 | { ngx_string("proxy_temp_file_write_size"), |
| 561 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 562 | ngx_conf_set_size_slot, |
| 563 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 564 | 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] | 565 | NULL }, |
| 566 | |
| 567 | { ngx_string("proxy_next_upstream"), |
Igor Sysoev | 9fa5a82 | 2005-09-30 14:41:25 +0000 | [diff] [blame] | 568 | 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] | 569 | ngx_conf_set_bitmask_slot, |
| 570 | NGX_HTTP_LOC_CONF_OFFSET, |
| 571 | offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream), |
| 572 | &ngx_http_proxy_next_upstream_masks }, |
| 573 | |
Roman Arutyunyan | 02ce6c4 | 2014-09-12 18:50:47 +0400 | [diff] [blame] | 574 | { ngx_string("proxy_next_upstream_tries"), |
| 575 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 576 | ngx_conf_set_num_slot, |
| 577 | NGX_HTTP_LOC_CONF_OFFSET, |
| 578 | offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream_tries), |
| 579 | NULL }, |
| 580 | |
| 581 | { ngx_string("proxy_next_upstream_timeout"), |
| 582 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 583 | ngx_conf_set_msec_slot, |
| 584 | NGX_HTTP_LOC_CONF_OFFSET, |
| 585 | offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream_timeout), |
| 586 | NULL }, |
| 587 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 588 | { ngx_string("proxy_pass_header"), |
Igor Sysoev | 6d9d07b | 2010-08-02 12:47:52 +0000 | [diff] [blame] | 589 | 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] | 590 | ngx_conf_set_str_array_slot, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 591 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 592 | offsetof(ngx_http_proxy_loc_conf_t, upstream.pass_headers), |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 593 | NULL }, |
| 594 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 595 | { ngx_string("proxy_hide_header"), |
Igor Sysoev | 6d9d07b | 2010-08-02 12:47:52 +0000 | [diff] [blame] | 596 | 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] | 597 | ngx_conf_set_str_array_slot, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 598 | NGX_HTTP_LOC_CONF_OFFSET, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 599 | offsetof(ngx_http_proxy_loc_conf_t, upstream.hide_headers), |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 600 | NULL }, |
| 601 | |
Igor Sysoev | b01c9cc | 2009-04-30 16:15:07 +0000 | [diff] [blame] | 602 | { ngx_string("proxy_ignore_headers"), |
| 603 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
| 604 | ngx_conf_set_bitmask_slot, |
| 605 | NGX_HTTP_LOC_CONF_OFFSET, |
| 606 | offsetof(ngx_http_proxy_loc_conf_t, upstream.ignore_headers), |
Igor Sysoev | 7e14b50 | 2010-07-02 09:25:38 +0000 | [diff] [blame] | 607 | &ngx_http_upstream_ignore_headers_masks }, |
Igor Sysoev | b01c9cc | 2009-04-30 16:15:07 +0000 | [diff] [blame] | 608 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 609 | { ngx_string("proxy_http_version"), |
| 610 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 611 | ngx_conf_set_enum_slot, |
| 612 | NGX_HTTP_LOC_CONF_OFFSET, |
| 613 | offsetof(ngx_http_proxy_loc_conf_t, http_version), |
| 614 | &ngx_http_proxy_http_version }, |
| 615 | |
Igor Sysoev | 916ee8e | 2008-08-17 17:47:52 +0000 | [diff] [blame] | 616 | #if (NGX_HTTP_SSL) |
| 617 | |
| 618 | { ngx_string("proxy_ssl_session_reuse"), |
| 619 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 620 | ngx_conf_set_flag_slot, |
| 621 | NGX_HTTP_LOC_CONF_OFFSET, |
| 622 | offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_session_reuse), |
| 623 | NULL }, |
| 624 | |
Andrei Belov | 003b2cd | 2013-09-19 18:30:33 +0400 | [diff] [blame] | 625 | { ngx_string("proxy_ssl_protocols"), |
| 626 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
| 627 | ngx_conf_set_bitmask_slot, |
| 628 | NGX_HTTP_LOC_CONF_OFFSET, |
| 629 | offsetof(ngx_http_proxy_loc_conf_t, ssl_protocols), |
| 630 | &ngx_http_proxy_ssl_protocols }, |
| 631 | |
Piotr Sikora | 43736b1 | 2013-09-23 15:58:28 -0700 | [diff] [blame] | 632 | { ngx_string("proxy_ssl_ciphers"), |
| 633 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 634 | ngx_conf_set_str_slot, |
| 635 | NGX_HTTP_LOC_CONF_OFFSET, |
| 636 | offsetof(ngx_http_proxy_loc_conf_t, ssl_ciphers), |
| 637 | NULL }, |
| 638 | |
Maxim Dounin | 59ef4a3 | 2014-04-18 20:13:28 +0400 | [diff] [blame] | 639 | { ngx_string("proxy_ssl_name"), |
| 640 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 641 | ngx_http_set_complex_value_slot, |
| 642 | NGX_HTTP_LOC_CONF_OFFSET, |
| 643 | offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_name), |
| 644 | NULL }, |
| 645 | |
| 646 | { ngx_string("proxy_ssl_server_name"), |
| 647 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 648 | ngx_conf_set_flag_slot, |
| 649 | NGX_HTTP_LOC_CONF_OFFSET, |
| 650 | offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_server_name), |
| 651 | NULL }, |
| 652 | |
Maxim Dounin | 27475dd | 2014-04-18 20:13:30 +0400 | [diff] [blame] | 653 | { ngx_string("proxy_ssl_verify"), |
| 654 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
| 655 | ngx_conf_set_flag_slot, |
| 656 | NGX_HTTP_LOC_CONF_OFFSET, |
| 657 | offsetof(ngx_http_proxy_loc_conf_t, upstream.ssl_verify), |
| 658 | NULL }, |
| 659 | |
| 660 | { ngx_string("proxy_ssl_verify_depth"), |
| 661 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 662 | ngx_conf_set_num_slot, |
| 663 | NGX_HTTP_LOC_CONF_OFFSET, |
| 664 | offsetof(ngx_http_proxy_loc_conf_t, ssl_verify_depth), |
| 665 | NULL }, |
| 666 | |
| 667 | { ngx_string("proxy_ssl_trusted_certificate"), |
| 668 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 669 | ngx_conf_set_str_slot, |
| 670 | NGX_HTTP_LOC_CONF_OFFSET, |
| 671 | offsetof(ngx_http_proxy_loc_conf_t, ssl_trusted_certificate), |
| 672 | NULL }, |
| 673 | |
| 674 | { ngx_string("proxy_ssl_crl"), |
| 675 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 676 | ngx_conf_set_str_slot, |
| 677 | NGX_HTTP_LOC_CONF_OFFSET, |
| 678 | offsetof(ngx_http_proxy_loc_conf_t, ssl_crl), |
| 679 | NULL }, |
| 680 | |
Piotr Sikora | a9d9b09 | 2014-10-30 04:30:41 -0700 | [diff] [blame] | 681 | { ngx_string("proxy_ssl_certificate"), |
| 682 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 683 | ngx_conf_set_str_slot, |
| 684 | NGX_HTTP_LOC_CONF_OFFSET, |
| 685 | offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate), |
| 686 | NULL }, |
| 687 | |
| 688 | { ngx_string("proxy_ssl_certificate_key"), |
| 689 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 690 | ngx_conf_set_str_slot, |
| 691 | NGX_HTTP_LOC_CONF_OFFSET, |
| 692 | offsetof(ngx_http_proxy_loc_conf_t, ssl_certificate_key), |
| 693 | NULL }, |
| 694 | |
| 695 | { ngx_string("proxy_ssl_password_file"), |
| 696 | NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
| 697 | ngx_http_proxy_ssl_password_file, |
| 698 | NGX_HTTP_LOC_CONF_OFFSET, |
| 699 | 0, |
| 700 | NULL }, |
| 701 | |
Igor Sysoev | 916ee8e | 2008-08-17 17:47:52 +0000 | [diff] [blame] | 702 | #endif |
| 703 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 704 | ngx_null_command |
| 705 | }; |
| 706 | |
| 707 | |
Igor Sysoev | 8f12558 | 2006-07-28 15:16:17 +0000 | [diff] [blame] | 708 | static ngx_http_module_t ngx_http_proxy_module_ctx = { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 709 | ngx_http_proxy_add_variables, /* preconfiguration */ |
| 710 | NULL, /* postconfiguration */ |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 711 | |
Valentin Bartenev | 9a0eb4f | 2014-12-22 12:59:09 +0300 | [diff] [blame] | 712 | ngx_http_proxy_create_main_conf, /* create main configuration */ |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 713 | NULL, /* init main configuration */ |
| 714 | |
| 715 | NULL, /* create server configuration */ |
| 716 | NULL, /* merge server configuration */ |
| 717 | |
Ruslan Ermilov | b74f8ff | 2012-02-28 11:31:05 +0000 | [diff] [blame] | 718 | ngx_http_proxy_create_loc_conf, /* create location configuration */ |
| 719 | ngx_http_proxy_merge_loc_conf /* merge location configuration */ |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 720 | }; |
| 721 | |
| 722 | |
| 723 | ngx_module_t ngx_http_proxy_module = { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 724 | NGX_MODULE_V1, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 725 | &ngx_http_proxy_module_ctx, /* module context */ |
| 726 | ngx_http_proxy_commands, /* module directives */ |
| 727 | NGX_HTTP_MODULE, /* module type */ |
Igor Sysoev | e573380 | 2005-09-08 14:36:09 +0000 | [diff] [blame] | 728 | NULL, /* init master */ |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 729 | NULL, /* init module */ |
Igor Sysoev | e573380 | 2005-09-08 14:36:09 +0000 | [diff] [blame] | 730 | NULL, /* init process */ |
| 731 | NULL, /* init thread */ |
| 732 | NULL, /* exit thread */ |
| 733 | NULL, /* exit process */ |
| 734 | NULL, /* exit master */ |
| 735 | NGX_MODULE_V1_PADDING |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 736 | }; |
| 737 | |
| 738 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 739 | static char ngx_http_proxy_version[] = " HTTP/1.0" CRLF; |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 740 | static char ngx_http_proxy_version_11[] = " HTTP/1.1" CRLF; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 741 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 742 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 743 | static ngx_keyval_t ngx_http_proxy_headers[] = { |
| 744 | { ngx_string("Host"), ngx_string("$proxy_host") }, |
| 745 | { ngx_string("Connection"), ngx_string("close") }, |
Maxim Dounin | 9a483c8 | 2012-11-21 01:03:48 +0000 | [diff] [blame] | 746 | { ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") }, |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 747 | { ngx_string("Transfer-Encoding"), ngx_string("$proxy_internal_chunked") }, |
Maxim Dounin | 4a32f81 | 2014-12-09 18:20:19 +0300 | [diff] [blame] | 748 | { ngx_string("TE"), ngx_string("") }, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 749 | { ngx_string("Keep-Alive"), ngx_string("") }, |
Igor Sysoev | 1e1f4c8 | 2008-06-26 13:00:39 +0000 | [diff] [blame] | 750 | { ngx_string("Expect"), ngx_string("") }, |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 751 | { ngx_string("Upgrade"), ngx_string("") }, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 752 | { ngx_null_string, ngx_null_string } |
| 753 | }; |
| 754 | |
| 755 | |
Igor Sysoev | 2b89d20 | 2009-04-15 11:42:49 +0000 | [diff] [blame] | 756 | static ngx_str_t ngx_http_proxy_hide_headers[] = { |
| 757 | ngx_string("Date"), |
| 758 | ngx_string("Server"), |
| 759 | ngx_string("X-Pad"), |
| 760 | ngx_string("X-Accel-Expires"), |
| 761 | ngx_string("X-Accel-Redirect"), |
| 762 | ngx_string("X-Accel-Limit-Rate"), |
| 763 | ngx_string("X-Accel-Buffering"), |
| 764 | ngx_string("X-Accel-Charset"), |
| 765 | ngx_null_string |
| 766 | }; |
| 767 | |
| 768 | |
Igor Sysoev | 081662a | 2009-04-15 11:21:12 +0000 | [diff] [blame] | 769 | #if (NGX_HTTP_CACHE) |
| 770 | |
| 771 | static ngx_keyval_t ngx_http_proxy_cache_headers[] = { |
| 772 | { ngx_string("Host"), ngx_string("$proxy_host") }, |
| 773 | { ngx_string("Connection"), ngx_string("close") }, |
Maxim Dounin | 9a483c8 | 2012-11-21 01:03:48 +0000 | [diff] [blame] | 774 | { ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") }, |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 775 | { ngx_string("Transfer-Encoding"), ngx_string("$proxy_internal_chunked") }, |
Maxim Dounin | 4a32f81 | 2014-12-09 18:20:19 +0300 | [diff] [blame] | 776 | { ngx_string("TE"), ngx_string("") }, |
Igor Sysoev | 081662a | 2009-04-15 11:21:12 +0000 | [diff] [blame] | 777 | { ngx_string("Keep-Alive"), ngx_string("") }, |
| 778 | { ngx_string("Expect"), ngx_string("") }, |
Maxim Dounin | 86a8519 | 2011-11-14 13:21:10 +0000 | [diff] [blame] | 779 | { ngx_string("Upgrade"), ngx_string("") }, |
Maxim Dounin | 1ac2693 | 2013-11-18 20:48:22 +0400 | [diff] [blame] | 780 | { ngx_string("If-Modified-Since"), |
| 781 | ngx_string("$upstream_cache_last_modified") }, |
Igor Sysoev | 081662a | 2009-04-15 11:21:12 +0000 | [diff] [blame] | 782 | { ngx_string("If-Unmodified-Since"), ngx_string("") }, |
Maxim Dounin | 46ac5c7 | 2014-06-26 02:35:01 +0400 | [diff] [blame] | 783 | { ngx_string("If-None-Match"), ngx_string("$upstream_cache_etag") }, |
Igor Sysoev | 081662a | 2009-04-15 11:21:12 +0000 | [diff] [blame] | 784 | { ngx_string("If-Match"), ngx_string("") }, |
| 785 | { ngx_string("Range"), ngx_string("") }, |
| 786 | { ngx_string("If-Range"), ngx_string("") }, |
| 787 | { ngx_null_string, ngx_null_string } |
| 788 | }; |
| 789 | |
Igor Sysoev | 2b89d20 | 2009-04-15 11:42:49 +0000 | [diff] [blame] | 790 | #endif |
| 791 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 792 | |
| 793 | static ngx_http_variable_t ngx_http_proxy_vars[] = { |
| 794 | |
Igor Sysoev | 7bdb720 | 2006-04-19 15:30:56 +0000 | [diff] [blame] | 795 | { ngx_string("proxy_host"), NULL, ngx_http_proxy_host_variable, 0, |
Igor Sysoev | 2061259 | 2008-03-11 14:10:11 +0000 | [diff] [blame] | 796 | 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] | 797 | |
Igor Sysoev | 7bdb720 | 2006-04-19 15:30:56 +0000 | [diff] [blame] | 798 | { ngx_string("proxy_port"), NULL, ngx_http_proxy_port_variable, 0, |
Igor Sysoev | 2061259 | 2008-03-11 14:10:11 +0000 | [diff] [blame] | 799 | 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] | 800 | |
Igor Sysoev | 7bdb720 | 2006-04-19 15:30:56 +0000 | [diff] [blame] | 801 | { ngx_string("proxy_add_x_forwarded_for"), NULL, |
Igor Sysoev | d3283ff | 2005-12-05 13:18:09 +0000 | [diff] [blame] | 802 | 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] | 803 | |
| 804 | #if 0 |
Igor Sysoev | 7bdb720 | 2006-04-19 15:30:56 +0000 | [diff] [blame] | 805 | { 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] | 806 | #endif |
| 807 | |
Igor Sysoev | 7bdb720 | 2006-04-19 15:30:56 +0000 | [diff] [blame] | 808 | { ngx_string("proxy_internal_body_length"), NULL, |
Maxim Dounin | a38455a | 2013-05-11 21:12:24 +0400 | [diff] [blame] | 809 | ngx_http_proxy_internal_body_length_variable, 0, |
| 810 | NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 }, |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 811 | |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 812 | { ngx_string("proxy_internal_chunked"), NULL, |
| 813 | ngx_http_proxy_internal_chunked_variable, 0, |
| 814 | NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 }, |
| 815 | |
Igor Sysoev | 7bdb720 | 2006-04-19 15:30:56 +0000 | [diff] [blame] | 816 | { ngx_null_string, NULL, NULL, 0, 0, 0 } |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 817 | }; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 818 | |
| 819 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 820 | static ngx_path_init_t ngx_http_proxy_temp_path = { |
| 821 | ngx_string(NGX_HTTP_PROXY_TEMP_PATH), { 1, 2, 0 } |
| 822 | }; |
| 823 | |
| 824 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 825 | static ngx_int_t |
| 826 | ngx_http_proxy_handler(ngx_http_request_t *r) |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 827 | { |
Valentin Bartenev | 9a0eb4f | 2014-12-22 12:59:09 +0300 | [diff] [blame] | 828 | ngx_int_t rc; |
| 829 | ngx_http_upstream_t *u; |
| 830 | ngx_http_proxy_ctx_t *ctx; |
| 831 | ngx_http_proxy_loc_conf_t *plcf; |
| 832 | #if (NGX_HTTP_CACHE) |
| 833 | ngx_http_proxy_main_conf_t *pmcf; |
| 834 | #endif |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 835 | |
Igor Sysoev | 15b7420 | 2009-07-27 13:25:29 +0000 | [diff] [blame] | 836 | if (ngx_http_upstream_create(r) != NGX_OK) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 837 | return NGX_HTTP_INTERNAL_SERVER_ERROR; |
| 838 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 839 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 840 | ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_ctx_t)); |
| 841 | if (ctx == NULL) { |
Ruslan Ermilov | c17b163 | 2015-03-04 08:12:53 +0300 | [diff] [blame] | 842 | return NGX_HTTP_INTERNAL_SERVER_ERROR; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 843 | } |
| 844 | |
| 845 | ngx_http_set_ctx(r, ctx, ngx_http_proxy_module); |
| 846 | |
| 847 | plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); |
| 848 | |
Igor Sysoev | 15b7420 | 2009-07-27 13:25:29 +0000 | [diff] [blame] | 849 | u = r->upstream; |
| 850 | |
Igor Sysoev | e4994fb | 2010-08-03 12:53:06 +0000 | [diff] [blame] | 851 | if (plcf->proxy_lengths == NULL) { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 852 | ctx->vars = plcf->vars; |
Igor Sysoev | 73c3121 | 2008-12-10 14:44:48 +0000 | [diff] [blame] | 853 | u->schema = plcf->vars.schema; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 854 | #if (NGX_HTTP_SSL) |
| 855 | u->ssl = (plcf->upstream.ssl != NULL); |
| 856 | #endif |
| 857 | |
| 858 | } else { |
| 859 | if (ngx_http_proxy_eval(r, ctx, plcf) != NGX_OK) { |
| 860 | return NGX_HTTP_INTERNAL_SERVER_ERROR; |
| 861 | } |
| 862 | } |
| 863 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 864 | u->output.tag = (ngx_buf_tag_t) &ngx_http_proxy_module; |
| 865 | |
| 866 | u->conf = &plcf->upstream; |
| 867 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 868 | #if (NGX_HTTP_CACHE) |
Valentin Bartenev | 9a0eb4f | 2014-12-22 12:59:09 +0300 | [diff] [blame] | 869 | pmcf = ngx_http_get_module_main_conf(r, ngx_http_proxy_module); |
| 870 | |
| 871 | u->caches = &pmcf->caches; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 872 | u->create_key = ngx_http_proxy_create_key; |
| 873 | #endif |
Valentin Bartenev | 9a0eb4f | 2014-12-22 12:59:09 +0300 | [diff] [blame] | 874 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 875 | u->create_request = ngx_http_proxy_create_request; |
| 876 | u->reinit_request = ngx_http_proxy_reinit_request; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 877 | u->process_header = ngx_http_proxy_process_status_line; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 878 | u->abort_request = ngx_http_proxy_abort_request; |
| 879 | u->finalize_request = ngx_http_proxy_finalize_request; |
Igor Sysoev | aed1ac1 | 2010-03-25 13:27:52 +0000 | [diff] [blame] | 880 | r->state = 0; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 881 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 882 | if (plcf->redirects) { |
| 883 | u->rewrite_redirect = ngx_http_proxy_rewrite_redirect; |
| 884 | } |
| 885 | |
Valentin Bartenev | a113cb3 | 2012-02-13 11:08:05 +0000 | [diff] [blame] | 886 | if (plcf->cookie_domains || plcf->cookie_paths) { |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 887 | u->rewrite_cookie = ngx_http_proxy_rewrite_cookie; |
| 888 | } |
| 889 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 890 | u->buffering = plcf->upstream.buffering; |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 891 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 892 | u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t)); |
| 893 | if (u->pipe == NULL) { |
| 894 | return NGX_HTTP_INTERNAL_SERVER_ERROR; |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 895 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 896 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 897 | u->pipe->input_filter = ngx_http_proxy_copy_filter; |
| 898 | u->pipe->input_ctx = r; |
| 899 | |
| 900 | u->input_filter_init = ngx_http_proxy_input_filter_init; |
| 901 | u->input_filter = ngx_http_proxy_non_buffered_copy_filter; |
| 902 | u->input_filter_ctx = r; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 903 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 904 | u->accel = 1; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 905 | |
Maxim Dounin | f568ff8 | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 906 | if (!plcf->upstream.request_buffering |
| 907 | && plcf->body_values == NULL && plcf->upstream.pass_request_body |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 908 | && (!r->headers_in.chunked |
| 909 | || plcf->http_version == NGX_HTTP_VERSION_11)) |
Maxim Dounin | f568ff8 | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 910 | { |
Maxim Dounin | f568ff8 | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 911 | r->request_body_no_buffering = 1; |
| 912 | } |
| 913 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 914 | rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init); |
| 915 | |
| 916 | if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { |
| 917 | return rc; |
| 918 | } |
| 919 | |
| 920 | return NGX_DONE; |
| 921 | } |
| 922 | |
| 923 | |
| 924 | static ngx_int_t |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 925 | ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx, |
| 926 | ngx_http_proxy_loc_conf_t *plcf) |
| 927 | { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 928 | u_char *p; |
| 929 | size_t add; |
| 930 | u_short port; |
| 931 | ngx_str_t proxy; |
| 932 | ngx_url_t url; |
| 933 | ngx_http_upstream_t *u; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 934 | |
| 935 | if (ngx_http_script_run(r, &proxy, plcf->proxy_lengths->elts, 0, |
| 936 | plcf->proxy_values->elts) |
| 937 | == NULL) |
| 938 | { |
| 939 | return NGX_ERROR; |
| 940 | } |
| 941 | |
Igor Sysoev | c946802 | 2011-07-30 06:11:46 +0000 | [diff] [blame] | 942 | if (proxy.len > 7 |
| 943 | && ngx_strncasecmp(proxy.data, (u_char *) "http://", 7) == 0) |
| 944 | { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 945 | add = 7; |
| 946 | port = 80; |
| 947 | |
| 948 | #if (NGX_HTTP_SSL) |
| 949 | |
Igor Sysoev | c946802 | 2011-07-30 06:11:46 +0000 | [diff] [blame] | 950 | } else if (proxy.len > 8 |
| 951 | && ngx_strncasecmp(proxy.data, (u_char *) "https://", 8) == 0) |
| 952 | { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 953 | add = 8; |
| 954 | port = 443; |
| 955 | r->upstream->ssl = 1; |
| 956 | |
| 957 | #endif |
| 958 | |
| 959 | } else { |
| 960 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
| 961 | "invalid URL prefix in \"%V\"", &proxy); |
| 962 | return NGX_ERROR; |
| 963 | } |
| 964 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 965 | u = r->upstream; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 966 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 967 | u->schema.len = add; |
| 968 | u->schema.data = proxy.data; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 969 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 970 | ngx_memzero(&url, sizeof(ngx_url_t)); |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 971 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 972 | url.url.len = proxy.len - add; |
| 973 | url.url.data = proxy.data + add; |
| 974 | url.default_port = port; |
| 975 | url.uri_part = 1; |
| 976 | url.no_resolve = 1; |
| 977 | |
| 978 | if (ngx_parse_url(r->pool, &url) != NGX_OK) { |
| 979 | if (url.err) { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 980 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 981 | "%s in upstream \"%V\"", url.err, &url.url); |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 982 | } |
| 983 | |
| 984 | return NGX_ERROR; |
| 985 | } |
| 986 | |
Igor Sysoev | 6c71b88 | 2009-11-15 11:36:12 +0000 | [diff] [blame] | 987 | if (url.uri.len) { |
| 988 | if (url.uri.data[0] == '?') { |
| 989 | p = ngx_pnalloc(r->pool, url.uri.len + 1); |
| 990 | if (p == NULL) { |
| 991 | return NGX_ERROR; |
| 992 | } |
| 993 | |
| 994 | *p++ = '/'; |
| 995 | ngx_memcpy(p, url.uri.data, url.uri.len); |
| 996 | |
| 997 | url.uri.len++; |
| 998 | url.uri.data = p - 1; |
Igor Sysoev | 164abfb | 2008-10-24 19:34:24 +0000 | [diff] [blame] | 999 | } |
Igor Sysoev | 164abfb | 2008-10-24 19:34:24 +0000 | [diff] [blame] | 1000 | } |
| 1001 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1002 | ctx->vars.key_start = u->schema; |
| 1003 | |
| 1004 | ngx_http_proxy_set_vars(&url, &ctx->vars); |
| 1005 | |
| 1006 | u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t)); |
| 1007 | if (u->resolved == NULL) { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1008 | return NGX_ERROR; |
| 1009 | } |
| 1010 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1011 | if (url.addrs && url.addrs[0].sockaddr) { |
| 1012 | u->resolved->sockaddr = url.addrs[0].sockaddr; |
| 1013 | u->resolved->socklen = url.addrs[0].socklen; |
| 1014 | u->resolved->naddrs = 1; |
| 1015 | u->resolved->host = url.addrs[0].name; |
Igor Sysoev | 302cedc | 2008-12-23 19:35:12 +0000 | [diff] [blame] | 1016 | |
| 1017 | } else { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1018 | u->resolved->host = url.host; |
Igor Sysoev | 302cedc | 2008-12-23 19:35:12 +0000 | [diff] [blame] | 1019 | } |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1020 | |
Ruslan Ermilov | 4a3c479 | 2015-11-21 10:44:07 +0300 | [diff] [blame] | 1021 | u->resolved->port = (in_port_t) (url.no_port ? port : url.port); |
| 1022 | u->resolved->no_port = url.no_port; |
| 1023 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1024 | return NGX_OK; |
| 1025 | } |
| 1026 | |
| 1027 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1028 | #if (NGX_HTTP_CACHE) |
| 1029 | |
| 1030 | static ngx_int_t |
| 1031 | ngx_http_proxy_create_key(ngx_http_request_t *r) |
| 1032 | { |
| 1033 | size_t len, loc_len; |
| 1034 | u_char *p; |
| 1035 | uintptr_t escape; |
| 1036 | ngx_str_t *key; |
| 1037 | ngx_http_upstream_t *u; |
| 1038 | ngx_http_proxy_ctx_t *ctx; |
| 1039 | ngx_http_proxy_loc_conf_t *plcf; |
| 1040 | |
| 1041 | u = r->upstream; |
| 1042 | |
| 1043 | plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); |
| 1044 | |
| 1045 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
| 1046 | |
| 1047 | key = ngx_array_push(&r->cache->keys); |
| 1048 | if (key == NULL) { |
| 1049 | return NGX_ERROR; |
| 1050 | } |
| 1051 | |
Ruslan Ermilov | 73fb7e8 | 2012-12-06 23:03:53 +0000 | [diff] [blame] | 1052 | if (plcf->cache_key.value.data) { |
Igor Sysoev | 44a69c8 | 2009-04-06 08:58:44 +0000 | [diff] [blame] | 1053 | |
| 1054 | if (ngx_http_complex_value(r, &plcf->cache_key, key) != NGX_OK) { |
| 1055 | return NGX_ERROR; |
| 1056 | } |
| 1057 | |
| 1058 | return NGX_OK; |
| 1059 | } |
| 1060 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1061 | *key = ctx->vars.key_start; |
| 1062 | |
| 1063 | key = ngx_array_push(&r->cache->keys); |
| 1064 | if (key == NULL) { |
| 1065 | return NGX_ERROR; |
| 1066 | } |
| 1067 | |
Maxim Dounin | aa44926 | 2011-12-23 16:04:09 +0000 | [diff] [blame] | 1068 | if (plcf->proxy_lengths && ctx->vars.uri.len) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1069 | |
| 1070 | *key = ctx->vars.uri; |
| 1071 | u->uri = ctx->vars.uri; |
| 1072 | |
| 1073 | return NGX_OK; |
| 1074 | |
| 1075 | } else if (ctx->vars.uri.len == 0 && r->valid_unparsed_uri && r == r->main) |
| 1076 | { |
| 1077 | *key = r->unparsed_uri; |
| 1078 | u->uri = r->unparsed_uri; |
| 1079 | |
| 1080 | return NGX_OK; |
| 1081 | } |
| 1082 | |
| 1083 | loc_len = (r->valid_location && ctx->vars.uri.len) ? plcf->location.len : 0; |
| 1084 | |
| 1085 | if (r->quoted_uri || r->internal) { |
| 1086 | escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len, |
| 1087 | r->uri.len - loc_len, NGX_ESCAPE_URI); |
| 1088 | } else { |
| 1089 | escape = 0; |
| 1090 | } |
| 1091 | |
| 1092 | len = ctx->vars.uri.len + r->uri.len - loc_len + escape |
| 1093 | + sizeof("?") - 1 + r->args.len; |
| 1094 | |
| 1095 | p = ngx_pnalloc(r->pool, len); |
| 1096 | if (p == NULL) { |
| 1097 | return NGX_ERROR; |
| 1098 | } |
| 1099 | |
| 1100 | key->data = p; |
| 1101 | |
| 1102 | if (r->valid_location) { |
| 1103 | p = ngx_copy(p, ctx->vars.uri.data, ctx->vars.uri.len); |
| 1104 | } |
| 1105 | |
| 1106 | if (escape) { |
| 1107 | ngx_escape_uri(p, r->uri.data + loc_len, |
| 1108 | r->uri.len - loc_len, NGX_ESCAPE_URI); |
| 1109 | p += r->uri.len - loc_len + escape; |
| 1110 | |
| 1111 | } else { |
| 1112 | p = ngx_copy(p, r->uri.data + loc_len, r->uri.len - loc_len); |
| 1113 | } |
| 1114 | |
| 1115 | if (r->args.len > 0) { |
| 1116 | *p++ = '?'; |
| 1117 | p = ngx_copy(p, r->args.data, r->args.len); |
| 1118 | } |
| 1119 | |
| 1120 | key->len = p - key->data; |
| 1121 | u->uri = *key; |
| 1122 | |
| 1123 | return NGX_OK; |
| 1124 | } |
| 1125 | |
| 1126 | #endif |
| 1127 | |
| 1128 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1129 | static ngx_int_t |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1130 | ngx_http_proxy_create_request(ngx_http_request_t *r) |
| 1131 | { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1132 | size_t len, uri_len, loc_len, body_len; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1133 | uintptr_t escape; |
| 1134 | ngx_buf_t *b; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1135 | ngx_str_t method; |
| 1136 | ngx_uint_t i, unparsed_uri; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1137 | ngx_chain_t *cl, *body; |
| 1138 | ngx_list_part_t *part; |
| 1139 | ngx_table_elt_t *header; |
| 1140 | ngx_http_upstream_t *u; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1141 | ngx_http_proxy_ctx_t *ctx; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1142 | ngx_http_script_code_pt code; |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 1143 | ngx_http_proxy_headers_t *headers; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1144 | ngx_http_script_engine_t e, le; |
| 1145 | ngx_http_proxy_loc_conf_t *plcf; |
| 1146 | ngx_http_script_len_code_pt lcode; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1147 | |
| 1148 | u = r->upstream; |
| 1149 | |
| 1150 | plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); |
| 1151 | |
Roman Arutyunyan | 8898c97 | 2014-11-19 17:33:23 +0300 | [diff] [blame] | 1152 | #if (NGX_HTTP_CACHE) |
| 1153 | headers = u->cacheable ? &plcf->headers_cache : &plcf->headers; |
| 1154 | #else |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 1155 | headers = &plcf->headers; |
Roman Arutyunyan | 8898c97 | 2014-11-19 17:33:23 +0300 | [diff] [blame] | 1156 | #endif |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 1157 | |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 1158 | if (u->method.len) { |
| 1159 | /* HEAD was changed to GET to cache response */ |
| 1160 | method = u->method; |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 1161 | |
| 1162 | } else if (plcf->method.len) { |
| 1163 | method = plcf->method; |
| 1164 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1165 | } else { |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 1166 | method = r->method_name; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1167 | } |
| 1168 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 1169 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
| 1170 | |
Ruslan Ermilov | 64f528a | 2015-11-06 15:21:51 +0300 | [diff] [blame] | 1171 | if (method.len == 4 |
| 1172 | && ngx_strncasecmp(method.data, (u_char *) "HEAD", 4) == 0) |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 1173 | { |
| 1174 | ctx->head = 1; |
| 1175 | } |
| 1176 | |
Ruslan Ermilov | 64f528a | 2015-11-06 15:21:51 +0300 | [diff] [blame] | 1177 | len = method.len + 1 + sizeof(ngx_http_proxy_version) - 1 |
| 1178 | + sizeof(CRLF) - 1; |
Igor Sysoev | fa62656 | 2007-11-28 15:06:05 +0000 | [diff] [blame] | 1179 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1180 | escape = 0; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1181 | loc_len = 0; |
| 1182 | unparsed_uri = 0; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1183 | |
Maxim Dounin | aa44926 | 2011-12-23 16:04:09 +0000 | [diff] [blame] | 1184 | if (plcf->proxy_lengths && ctx->vars.uri.len) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1185 | uri_len = ctx->vars.uri.len; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1186 | |
| 1187 | } else if (ctx->vars.uri.len == 0 && r->valid_unparsed_uri && r == r->main) |
| 1188 | { |
Igor Sysoev | 8290d28 | 2006-02-03 12:58:48 +0000 | [diff] [blame] | 1189 | unparsed_uri = 1; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1190 | uri_len = r->unparsed_uri.len; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1191 | |
| 1192 | } else { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1193 | loc_len = (r->valid_location && ctx->vars.uri.len) ? |
| 1194 | plcf->location.len : 0; |
| 1195 | |
Igor Sysoev | da7b5e1 | 2010-06-15 09:31:19 +0000 | [diff] [blame] | 1196 | if (r->quoted_uri || r->space_in_uri || r->internal) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1197 | escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len, |
| 1198 | r->uri.len - loc_len, NGX_ESCAPE_URI); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1199 | } |
| 1200 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1201 | uri_len = ctx->vars.uri.len + r->uri.len - loc_len + escape |
| 1202 | + sizeof("?") - 1 + r->args.len; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1203 | } |
| 1204 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1205 | if (uri_len == 0) { |
| 1206 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
| 1207 | "zero length URI to proxy"); |
| 1208 | return NGX_ERROR; |
| 1209 | } |
| 1210 | |
| 1211 | len += uri_len; |
| 1212 | |
Maxim Dounin | 330ebdc | 2013-05-15 12:23:44 +0400 | [diff] [blame] | 1213 | ngx_memzero(&le, sizeof(ngx_http_script_engine_t)); |
| 1214 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 1215 | ngx_http_script_flush_no_cacheable_variables(r, plcf->body_flushes); |
| 1216 | ngx_http_script_flush_no_cacheable_variables(r, headers->flushes); |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1217 | |
Roman Arutyunyan | 1b79cb2 | 2014-11-19 17:33:24 +0300 | [diff] [blame] | 1218 | if (plcf->body_lengths) { |
| 1219 | le.ip = plcf->body_lengths->elts; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1220 | le.request = r; |
| 1221 | le.flushed = 1; |
| 1222 | body_len = 0; |
| 1223 | |
| 1224 | while (*(uintptr_t *) le.ip) { |
| 1225 | lcode = *(ngx_http_script_len_code_pt *) le.ip; |
| 1226 | body_len += lcode(&le); |
| 1227 | } |
| 1228 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1229 | ctx->internal_body_length = body_len; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1230 | len += body_len; |
Maxim Dounin | 9a483c8 | 2012-11-21 01:03:48 +0000 | [diff] [blame] | 1231 | |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 1232 | } else if (r->headers_in.chunked && r->reading_body) { |
| 1233 | ctx->internal_body_length = -1; |
| 1234 | ctx->internal_chunked = 1; |
| 1235 | |
Maxim Dounin | 9a483c8 | 2012-11-21 01:03:48 +0000 | [diff] [blame] | 1236 | } else { |
| 1237 | ctx->internal_body_length = r->headers_in.content_length_n; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1238 | } |
| 1239 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 1240 | le.ip = headers->lengths->elts; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1241 | le.request = r; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1242 | le.flushed = 1; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1243 | |
| 1244 | while (*(uintptr_t *) le.ip) { |
| 1245 | while (*(uintptr_t *) le.ip) { |
| 1246 | lcode = *(ngx_http_script_len_code_pt *) le.ip; |
| 1247 | len += lcode(&le); |
| 1248 | } |
| 1249 | le.ip += sizeof(uintptr_t); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1250 | } |
| 1251 | |
| 1252 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1253 | if (plcf->upstream.pass_request_headers) { |
| 1254 | part = &r->headers_in.headers.part; |
| 1255 | header = part->elts; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1256 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1257 | for (i = 0; /* void */; i++) { |
| 1258 | |
| 1259 | if (i >= part->nelts) { |
| 1260 | if (part->next == NULL) { |
| 1261 | break; |
| 1262 | } |
| 1263 | |
| 1264 | part = part->next; |
| 1265 | header = part->elts; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1266 | i = 0; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1267 | } |
| 1268 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 1269 | if (ngx_hash_find(&headers->hash, header[i].hash, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1270 | header[i].lowcase_key, header[i].key.len)) |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1271 | { |
| 1272 | continue; |
| 1273 | } |
| 1274 | |
| 1275 | len += header[i].key.len + sizeof(": ") - 1 |
| 1276 | + header[i].value.len + sizeof(CRLF) - 1; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1277 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1278 | } |
| 1279 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1280 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1281 | b = ngx_create_temp_buf(r->pool, len); |
| 1282 | if (b == NULL) { |
| 1283 | return NGX_ERROR; |
| 1284 | } |
| 1285 | |
| 1286 | cl = ngx_alloc_chain_link(r->pool); |
| 1287 | if (cl == NULL) { |
| 1288 | return NGX_ERROR; |
| 1289 | } |
| 1290 | |
| 1291 | cl->buf = b; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1292 | |
| 1293 | |
| 1294 | /* the request line */ |
| 1295 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1296 | b->last = ngx_copy(b->last, method.data, method.len); |
Ruslan Ermilov | 64f528a | 2015-11-06 15:21:51 +0300 | [diff] [blame] | 1297 | *b->last++ = ' '; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1298 | |
Igor Sysoev | a257367 | 2005-10-05 14:46:21 +0000 | [diff] [blame] | 1299 | u->uri.data = b->last; |
| 1300 | |
Maxim Dounin | aa44926 | 2011-12-23 16:04:09 +0000 | [diff] [blame] | 1301 | if (plcf->proxy_lengths && ctx->vars.uri.len) { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1302 | b->last = ngx_copy(b->last, ctx->vars.uri.data, ctx->vars.uri.len); |
| 1303 | |
| 1304 | } else if (unparsed_uri) { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1305 | b->last = ngx_copy(b->last, r->unparsed_uri.data, r->unparsed_uri.len); |
| 1306 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1307 | } else { |
Igor Sysoev | a257367 | 2005-10-05 14:46:21 +0000 | [diff] [blame] | 1308 | if (r->valid_location) { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1309 | 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] | 1310 | } |
Igor Sysoev | 82dc95e | 2005-10-03 12:53:14 +0000 | [diff] [blame] | 1311 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1312 | if (escape) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1313 | ngx_escape_uri(b->last, r->uri.data + loc_len, |
| 1314 | r->uri.len - loc_len, NGX_ESCAPE_URI); |
| 1315 | b->last += r->uri.len - loc_len + escape; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1316 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1317 | } else { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1318 | b->last = ngx_copy(b->last, r->uri.data + loc_len, |
| 1319 | r->uri.len - loc_len); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1320 | } |
| 1321 | |
| 1322 | if (r->args.len > 0) { |
| 1323 | *b->last++ = '?'; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1324 | b->last = ngx_copy(b->last, r->args.data, r->args.len); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1325 | } |
| 1326 | } |
| 1327 | |
Igor Sysoev | a257367 | 2005-10-05 14:46:21 +0000 | [diff] [blame] | 1328 | u->uri.len = b->last - u->uri.data; |
| 1329 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 1330 | if (plcf->http_version == NGX_HTTP_VERSION_11) { |
| 1331 | b->last = ngx_cpymem(b->last, ngx_http_proxy_version_11, |
| 1332 | sizeof(ngx_http_proxy_version_11) - 1); |
| 1333 | |
| 1334 | } else { |
| 1335 | b->last = ngx_cpymem(b->last, ngx_http_proxy_version, |
| 1336 | sizeof(ngx_http_proxy_version) - 1); |
| 1337 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1338 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1339 | ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1340 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 1341 | e.ip = headers->values->elts; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1342 | e.pos = b->last; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1343 | e.request = r; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1344 | e.flushed = 1; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1345 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 1346 | le.ip = headers->lengths->elts; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1347 | |
| 1348 | while (*(uintptr_t *) le.ip) { |
| 1349 | lcode = *(ngx_http_script_len_code_pt *) le.ip; |
Igor Sysoev | e31e90b | 2005-05-19 13:25:22 +0000 | [diff] [blame] | 1350 | |
| 1351 | /* skip the header line name length */ |
| 1352 | (void) lcode(&le); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1353 | |
| 1354 | if (*(ngx_http_script_len_code_pt *) le.ip) { |
| 1355 | |
| 1356 | for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) { |
| 1357 | lcode = *(ngx_http_script_len_code_pt *) le.ip; |
| 1358 | } |
| 1359 | |
| 1360 | e.skip = (len == sizeof(CRLF) - 1) ? 1 : 0; |
| 1361 | |
| 1362 | } else { |
| 1363 | e.skip = 0; |
| 1364 | } |
| 1365 | |
| 1366 | le.ip += sizeof(uintptr_t); |
| 1367 | |
| 1368 | while (*(uintptr_t *) e.ip) { |
| 1369 | code = *(ngx_http_script_code_pt *) e.ip; |
| 1370 | code((ngx_http_script_engine_t *) &e); |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1371 | } |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1372 | e.ip += sizeof(uintptr_t); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1373 | } |
| 1374 | |
| 1375 | b->last = e.pos; |
| 1376 | |
| 1377 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1378 | if (plcf->upstream.pass_request_headers) { |
| 1379 | part = &r->headers_in.headers.part; |
| 1380 | header = part->elts; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1381 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1382 | for (i = 0; /* void */; i++) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1383 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1384 | if (i >= part->nelts) { |
| 1385 | if (part->next == NULL) { |
| 1386 | break; |
| 1387 | } |
| 1388 | |
| 1389 | part = part->next; |
| 1390 | header = part->elts; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1391 | i = 0; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1392 | } |
| 1393 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 1394 | if (ngx_hash_find(&headers->hash, header[i].hash, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1395 | header[i].lowcase_key, header[i].key.len)) |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1396 | { |
| 1397 | continue; |
| 1398 | } |
| 1399 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1400 | 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] | 1401 | |
| 1402 | *b->last++ = ':'; *b->last++ = ' '; |
| 1403 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1404 | b->last = ngx_copy(b->last, header[i].value.data, |
| 1405 | header[i].value.len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1406 | |
| 1407 | *b->last++ = CR; *b->last++ = LF; |
| 1408 | |
| 1409 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 1410 | "http proxy header: \"%V: %V\"", |
| 1411 | &header[i].key, &header[i].value); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1412 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1413 | } |
| 1414 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1415 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1416 | /* add "\r\n" at the header end */ |
| 1417 | *b->last++ = CR; *b->last++ = LF; |
| 1418 | |
Roman Arutyunyan | 1b79cb2 | 2014-11-19 17:33:24 +0300 | [diff] [blame] | 1419 | if (plcf->body_values) { |
| 1420 | e.ip = plcf->body_values->elts; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1421 | e.pos = b->last; |
Maxim Dounin | abf40d0 | 2015-03-23 19:28:54 +0300 | [diff] [blame] | 1422 | e.skip = 0; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1423 | |
| 1424 | while (*(uintptr_t *) e.ip) { |
| 1425 | code = *(ngx_http_script_code_pt *) e.ip; |
| 1426 | code((ngx_http_script_engine_t *) &e); |
| 1427 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1428 | |
Igor Sysoev | b141f2b | 2005-11-15 14:49:57 +0000 | [diff] [blame] | 1429 | b->last = e.pos; |
| 1430 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1431 | |
Igor Sysoev | d02661a | 2007-12-24 17:05:31 +0000 | [diff] [blame] | 1432 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
Ruslan Ermilov | 5a3d441 | 2014-05-14 22:26:30 +0400 | [diff] [blame] | 1433 | "http proxy header:%N\"%*s\"", |
Igor Sysoev | d02661a | 2007-12-24 17:05:31 +0000 | [diff] [blame] | 1434 | (size_t) (b->last - b->pos), b->pos); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1435 | |
Maxim Dounin | f568ff8 | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 1436 | if (r->request_body_no_buffering) { |
| 1437 | |
| 1438 | u->request_bufs = cl; |
| 1439 | |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 1440 | if (ctx->internal_chunked) { |
| 1441 | u->output.output_filter = ngx_http_proxy_body_output_filter; |
| 1442 | u->output.filter_ctx = r; |
| 1443 | } |
| 1444 | |
Maxim Dounin | f568ff8 | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 1445 | } else if (plcf->body_values == NULL && plcf->upstream.pass_request_body) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1446 | |
| 1447 | body = u->request_bufs; |
| 1448 | u->request_bufs = cl; |
| 1449 | |
| 1450 | while (body) { |
| 1451 | b = ngx_alloc_buf(r->pool); |
| 1452 | if (b == NULL) { |
| 1453 | return NGX_ERROR; |
| 1454 | } |
| 1455 | |
| 1456 | ngx_memcpy(b, body->buf, sizeof(ngx_buf_t)); |
| 1457 | |
| 1458 | cl->next = ngx_alloc_chain_link(r->pool); |
| 1459 | if (cl->next == NULL) { |
| 1460 | return NGX_ERROR; |
| 1461 | } |
| 1462 | |
| 1463 | cl = cl->next; |
| 1464 | cl->buf = b; |
| 1465 | |
| 1466 | body = body->next; |
| 1467 | } |
| 1468 | |
| 1469 | } else { |
| 1470 | u->request_bufs = cl; |
| 1471 | } |
| 1472 | |
Maxim Dounin | 9bc8fc4 | 2011-08-18 16:34:24 +0000 | [diff] [blame] | 1473 | b->flush = 1; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1474 | cl->next = NULL; |
| 1475 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1476 | return NGX_OK; |
| 1477 | } |
| 1478 | |
| 1479 | |
| 1480 | static ngx_int_t |
| 1481 | ngx_http_proxy_reinit_request(ngx_http_request_t *r) |
| 1482 | { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1483 | ngx_http_proxy_ctx_t *ctx; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1484 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1485 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1486 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1487 | if (ctx == NULL) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1488 | return NGX_OK; |
| 1489 | } |
| 1490 | |
Igor Sysoev | 54b35b0 | 2010-06-15 15:15:06 +0000 | [diff] [blame] | 1491 | ctx->status.code = 0; |
| 1492 | ctx->status.count = 0; |
| 1493 | ctx->status.start = NULL; |
| 1494 | ctx->status.end = NULL; |
Maxim Dounin | df74d88 | 2012-11-21 00:59:16 +0000 | [diff] [blame] | 1495 | ctx->chunked.state = 0; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1496 | |
| 1497 | r->upstream->process_header = ngx_http_proxy_process_status_line; |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 1498 | r->upstream->pipe->input_filter = ngx_http_proxy_copy_filter; |
| 1499 | r->upstream->input_filter = ngx_http_proxy_non_buffered_copy_filter; |
Igor Sysoev | aed1ac1 | 2010-03-25 13:27:52 +0000 | [diff] [blame] | 1500 | r->state = 0; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1501 | |
| 1502 | return NGX_OK; |
| 1503 | } |
| 1504 | |
| 1505 | |
| 1506 | static ngx_int_t |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 1507 | ngx_http_proxy_body_output_filter(void *data, ngx_chain_t *in) |
| 1508 | { |
| 1509 | ngx_http_request_t *r = data; |
| 1510 | |
| 1511 | off_t size; |
| 1512 | u_char *chunk; |
| 1513 | ngx_int_t rc; |
| 1514 | ngx_buf_t *b; |
Maxim Dounin | b89196a | 2015-03-26 02:31:30 +0300 | [diff] [blame] | 1515 | ngx_chain_t *out, *cl, *tl, **ll, **fl; |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 1516 | ngx_http_proxy_ctx_t *ctx; |
| 1517 | |
| 1518 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 1519 | "proxy output filter"); |
| 1520 | |
| 1521 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
| 1522 | |
| 1523 | if (in == NULL) { |
| 1524 | out = in; |
| 1525 | goto out; |
| 1526 | } |
| 1527 | |
| 1528 | out = NULL; |
| 1529 | ll = &out; |
| 1530 | |
| 1531 | if (!ctx->header_sent) { |
| 1532 | /* first buffer contains headers, pass it unmodified */ |
| 1533 | |
| 1534 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 1535 | "proxy output header"); |
| 1536 | |
| 1537 | ctx->header_sent = 1; |
| 1538 | |
| 1539 | tl = ngx_alloc_chain_link(r->pool); |
| 1540 | if (tl == NULL) { |
| 1541 | return NGX_ERROR; |
| 1542 | } |
| 1543 | |
| 1544 | tl->buf = in->buf; |
| 1545 | *ll = tl; |
| 1546 | ll = &tl->next; |
| 1547 | |
| 1548 | in = in->next; |
| 1549 | |
| 1550 | if (in == NULL) { |
| 1551 | tl->next = NULL; |
| 1552 | goto out; |
| 1553 | } |
| 1554 | } |
| 1555 | |
| 1556 | size = 0; |
| 1557 | cl = in; |
Maxim Dounin | b89196a | 2015-03-26 02:31:30 +0300 | [diff] [blame] | 1558 | fl = ll; |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 1559 | |
| 1560 | for ( ;; ) { |
| 1561 | ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
Sergey Kandaurov | b7687bb | 2016-03-31 02:33:57 +0300 | [diff] [blame] | 1562 | "proxy output chunk: %O", ngx_buf_size(cl->buf)); |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 1563 | |
| 1564 | size += ngx_buf_size(cl->buf); |
| 1565 | |
| 1566 | if (cl->buf->flush |
| 1567 | || cl->buf->sync |
| 1568 | || ngx_buf_in_memory(cl->buf) |
| 1569 | || cl->buf->in_file) |
| 1570 | { |
| 1571 | tl = ngx_alloc_chain_link(r->pool); |
| 1572 | if (tl == NULL) { |
| 1573 | return NGX_ERROR; |
| 1574 | } |
| 1575 | |
| 1576 | tl->buf = cl->buf; |
| 1577 | *ll = tl; |
| 1578 | ll = &tl->next; |
| 1579 | } |
| 1580 | |
| 1581 | if (cl->next == NULL) { |
| 1582 | break; |
| 1583 | } |
| 1584 | |
| 1585 | cl = cl->next; |
| 1586 | } |
| 1587 | |
| 1588 | if (size) { |
| 1589 | tl = ngx_chain_get_free_buf(r->pool, &ctx->free); |
| 1590 | if (tl == NULL) { |
| 1591 | return NGX_ERROR; |
| 1592 | } |
| 1593 | |
| 1594 | b = tl->buf; |
| 1595 | chunk = b->start; |
| 1596 | |
| 1597 | if (chunk == NULL) { |
| 1598 | /* the "0000000000000000" is 64-bit hexadecimal string */ |
| 1599 | |
| 1600 | chunk = ngx_palloc(r->pool, sizeof("0000000000000000" CRLF) - 1); |
| 1601 | if (chunk == NULL) { |
| 1602 | return NGX_ERROR; |
| 1603 | } |
| 1604 | |
| 1605 | b->start = chunk; |
| 1606 | b->end = chunk + sizeof("0000000000000000" CRLF) - 1; |
| 1607 | } |
| 1608 | |
| 1609 | b->tag = (ngx_buf_tag_t) &ngx_http_proxy_body_output_filter; |
| 1610 | b->memory = 0; |
| 1611 | b->temporary = 1; |
| 1612 | b->pos = chunk; |
| 1613 | b->last = ngx_sprintf(chunk, "%xO" CRLF, size); |
| 1614 | |
Maxim Dounin | b89196a | 2015-03-26 02:31:30 +0300 | [diff] [blame] | 1615 | tl->next = *fl; |
| 1616 | *fl = tl; |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 1617 | } |
| 1618 | |
| 1619 | if (cl->buf->last_buf) { |
| 1620 | tl = ngx_chain_get_free_buf(r->pool, &ctx->free); |
| 1621 | if (tl == NULL) { |
| 1622 | return NGX_ERROR; |
| 1623 | } |
| 1624 | |
| 1625 | b = tl->buf; |
| 1626 | |
| 1627 | b->tag = (ngx_buf_tag_t) &ngx_http_proxy_body_output_filter; |
| 1628 | b->temporary = 0; |
| 1629 | b->memory = 1; |
| 1630 | b->last_buf = 1; |
| 1631 | b->pos = (u_char *) CRLF "0" CRLF CRLF; |
| 1632 | b->last = b->pos + 7; |
| 1633 | |
| 1634 | cl->buf->last_buf = 0; |
| 1635 | |
| 1636 | *ll = tl; |
| 1637 | |
| 1638 | if (size == 0) { |
| 1639 | b->pos += 2; |
| 1640 | } |
| 1641 | |
| 1642 | } else if (size > 0) { |
| 1643 | tl = ngx_chain_get_free_buf(r->pool, &ctx->free); |
| 1644 | if (tl == NULL) { |
| 1645 | return NGX_ERROR; |
| 1646 | } |
| 1647 | |
| 1648 | b = tl->buf; |
| 1649 | |
| 1650 | b->tag = (ngx_buf_tag_t) &ngx_http_proxy_body_output_filter; |
| 1651 | b->temporary = 0; |
| 1652 | b->memory = 1; |
| 1653 | b->pos = (u_char *) CRLF; |
| 1654 | b->last = b->pos + 2; |
| 1655 | |
| 1656 | *ll = tl; |
| 1657 | |
| 1658 | } else { |
| 1659 | *ll = NULL; |
| 1660 | } |
| 1661 | |
| 1662 | out: |
| 1663 | |
| 1664 | rc = ngx_chain_writer(&r->upstream->writer, out); |
| 1665 | |
| 1666 | ngx_chain_update_chains(r->pool, &ctx->free, &ctx->busy, &out, |
| 1667 | (ngx_buf_tag_t) &ngx_http_proxy_body_output_filter); |
| 1668 | |
| 1669 | return rc; |
| 1670 | } |
| 1671 | |
| 1672 | |
| 1673 | static ngx_int_t |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1674 | ngx_http_proxy_process_status_line(ngx_http_request_t *r) |
| 1675 | { |
Igor Sysoev | 1cc1b31 | 2010-06-15 15:21:37 +0000 | [diff] [blame] | 1676 | size_t len; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1677 | ngx_int_t rc; |
| 1678 | ngx_http_upstream_t *u; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1679 | ngx_http_proxy_ctx_t *ctx; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1680 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1681 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1682 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 1683 | if (ctx == NULL) { |
Igor Sysoev | 5a55d71 | 2007-12-09 08:22:35 +0000 | [diff] [blame] | 1684 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1685 | } |
| 1686 | |
Igor Sysoev | 54b35b0 | 2010-06-15 15:15:06 +0000 | [diff] [blame] | 1687 | u = r->upstream; |
| 1688 | |
| 1689 | rc = ngx_http_parse_status_line(r, &u->buffer, &ctx->status); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1690 | |
| 1691 | if (rc == NGX_AGAIN) { |
| 1692 | return rc; |
| 1693 | } |
| 1694 | |
Igor Sysoev | 54b35b0 | 2010-06-15 15:15:06 +0000 | [diff] [blame] | 1695 | if (rc == NGX_ERROR) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1696 | |
| 1697 | #if (NGX_HTTP_CACHE) |
| 1698 | |
| 1699 | if (r->cache) { |
| 1700 | r->http_version = NGX_HTTP_VERSION_9; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1701 | return NGX_OK; |
| 1702 | } |
| 1703 | |
| 1704 | #endif |
| 1705 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1706 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1707 | "upstream sent no valid HTTP/1.0 header"); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1708 | |
Igor Sysoev | 13c6874 | 2006-03-10 12:51:52 +0000 | [diff] [blame] | 1709 | #if 0 |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1710 | if (u->accel) { |
| 1711 | return NGX_HTTP_UPSTREAM_INVALID_HEADER; |
| 1712 | } |
Igor Sysoev | 13c6874 | 2006-03-10 12:51:52 +0000 | [diff] [blame] | 1713 | #endif |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1714 | |
| 1715 | r->http_version = NGX_HTTP_VERSION_9; |
Igor Sysoev | d7cf1a6 | 2007-11-06 15:01:13 +0000 | [diff] [blame] | 1716 | u->state->status = NGX_HTTP_OK; |
Maxim Dounin | f2fcf11 | 2011-09-15 19:22:35 +0000 | [diff] [blame] | 1717 | u->headers_in.connection_close = 1; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 1718 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1719 | return NGX_OK; |
| 1720 | } |
| 1721 | |
Piotr Sikora | 60d508c | 2014-02-11 21:54:42 -0800 | [diff] [blame] | 1722 | if (u->state && u->state->status == 0) { |
Igor Sysoev | 54b35b0 | 2010-06-15 15:15:06 +0000 | [diff] [blame] | 1723 | u->state->status = ctx->status.code; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 1724 | } |
| 1725 | |
Igor Sysoev | 54b35b0 | 2010-06-15 15:15:06 +0000 | [diff] [blame] | 1726 | u->headers_in.status_n = ctx->status.code; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1727 | |
Igor Sysoev | 1cc1b31 | 2010-06-15 15:21:37 +0000 | [diff] [blame] | 1728 | len = ctx->status.end - ctx->status.start; |
| 1729 | u->headers_in.status_line.len = len; |
| 1730 | |
| 1731 | u->headers_in.status_line.data = ngx_pnalloc(r->pool, len); |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 1732 | if (u->headers_in.status_line.data == NULL) { |
Igor Sysoev | 5a55d71 | 2007-12-09 08:22:35 +0000 | [diff] [blame] | 1733 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1734 | } |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 1735 | |
Igor Sysoev | 1cc1b31 | 2010-06-15 15:21:37 +0000 | [diff] [blame] | 1736 | ngx_memcpy(u->headers_in.status_line.data, ctx->status.start, len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1737 | |
| 1738 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 1739 | "http proxy status %ui \"%V\"", |
Igor Sysoev | 4e08b9c | 2006-12-20 19:38:06 +0000 | [diff] [blame] | 1740 | u->headers_in.status_n, &u->headers_in.status_line); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1741 | |
Maxim Dounin | f2fcf11 | 2011-09-15 19:22:35 +0000 | [diff] [blame] | 1742 | if (ctx->status.http_version < NGX_HTTP_VERSION_11) { |
| 1743 | u->headers_in.connection_close = 1; |
| 1744 | } |
| 1745 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1746 | u->process_header = ngx_http_proxy_process_header; |
| 1747 | |
| 1748 | return ngx_http_proxy_process_header(r); |
| 1749 | } |
| 1750 | |
| 1751 | |
| 1752 | static ngx_int_t |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1753 | ngx_http_proxy_process_header(ngx_http_request_t *r) |
| 1754 | { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1755 | ngx_int_t rc; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1756 | ngx_table_elt_t *h; |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 1757 | ngx_http_upstream_t *u; |
| 1758 | ngx_http_proxy_ctx_t *ctx; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1759 | ngx_http_upstream_header_t *hh; |
| 1760 | ngx_http_upstream_main_conf_t *umcf; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1761 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1762 | umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1763 | |
Igor Sysoev | 3b30476 | 2008-05-22 12:09:41 +0000 | [diff] [blame] | 1764 | for ( ;; ) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1765 | |
Igor Sysoev | 753792e | 2008-09-24 14:02:50 +0000 | [diff] [blame] | 1766 | rc = ngx_http_parse_header_line(r, &r->upstream->buffer, 1); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1767 | |
| 1768 | if (rc == NGX_OK) { |
| 1769 | |
| 1770 | /* a header line has been parsed successfully */ |
| 1771 | |
| 1772 | h = ngx_list_push(&r->upstream->headers_in.headers); |
| 1773 | if (h == NULL) { |
Igor Sysoev | 5a55d71 | 2007-12-09 08:22:35 +0000 | [diff] [blame] | 1774 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1775 | } |
| 1776 | |
| 1777 | h->hash = r->header_hash; |
| 1778 | |
| 1779 | h->key.len = r->header_name_end - r->header_name_start; |
| 1780 | h->value.len = r->header_end - r->header_start; |
| 1781 | |
Igor Sysoev | 7f6b2ff | 2008-06-17 15:00:30 +0000 | [diff] [blame] | 1782 | h->key.data = ngx_pnalloc(r->pool, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1783 | h->key.len + 1 + h->value.len + 1 + h->key.len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1784 | if (h->key.data == NULL) { |
Igor Sysoev | 5a55d71 | 2007-12-09 08:22:35 +0000 | [diff] [blame] | 1785 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1786 | } |
| 1787 | |
| 1788 | h->value.data = h->key.data + h->key.len + 1; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1789 | 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] | 1790 | |
Maxim Dounin | eb526b7 | 2012-03-15 11:27:12 +0000 | [diff] [blame] | 1791 | ngx_memcpy(h->key.data, r->header_name_start, h->key.len); |
| 1792 | h->key.data[h->key.len] = '\0'; |
| 1793 | ngx_memcpy(h->value.data, r->header_start, h->value.len); |
| 1794 | h->value.data[h->value.len] = '\0'; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1795 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1796 | if (h->key.len == r->lowcase_index) { |
| 1797 | ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1798 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1799 | } else { |
Igor Sysoev | 777b019 | 2008-08-04 10:07:00 +0000 | [diff] [blame] | 1800 | ngx_strlow(h->lowcase_key, h->key.data, h->key.len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1801 | } |
| 1802 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1803 | hh = ngx_hash_find(&umcf->headers_in_hash, h->hash, |
| 1804 | h->lowcase_key, h->key.len); |
| 1805 | |
| 1806 | if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { |
Igor Sysoev | 5a55d71 | 2007-12-09 08:22:35 +0000 | [diff] [blame] | 1807 | return NGX_ERROR; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1808 | } |
| 1809 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1810 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 1811 | "http proxy header: \"%V: %V\"", |
| 1812 | &h->key, &h->value); |
| 1813 | |
| 1814 | continue; |
| 1815 | } |
| 1816 | |
| 1817 | if (rc == NGX_HTTP_PARSE_HEADER_DONE) { |
| 1818 | |
| 1819 | /* a whole header has been parsed successfully */ |
| 1820 | |
| 1821 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 1822 | "http proxy header done"); |
| 1823 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1824 | /* |
| 1825 | * if no "Server" and "Date" in header line, |
| 1826 | * then add the special empty headers |
| 1827 | */ |
| 1828 | |
| 1829 | if (r->upstream->headers_in.server == NULL) { |
| 1830 | h = ngx_list_push(&r->upstream->headers_in.headers); |
| 1831 | if (h == NULL) { |
Igor Sysoev | 5a55d71 | 2007-12-09 08:22:35 +0000 | [diff] [blame] | 1832 | return NGX_ERROR; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1833 | } |
| 1834 | |
| 1835 | h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash( |
| 1836 | ngx_hash('s', 'e'), 'r'), 'v'), 'e'), 'r'); |
| 1837 | |
Igor Sysoev | 05b1a8f | 2010-05-14 09:56:37 +0000 | [diff] [blame] | 1838 | ngx_str_set(&h->key, "Server"); |
| 1839 | ngx_str_null(&h->value); |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1840 | h->lowcase_key = (u_char *) "server"; |
| 1841 | } |
| 1842 | |
| 1843 | if (r->upstream->headers_in.date == NULL) { |
| 1844 | h = ngx_list_push(&r->upstream->headers_in.headers); |
| 1845 | if (h == NULL) { |
Igor Sysoev | 5a55d71 | 2007-12-09 08:22:35 +0000 | [diff] [blame] | 1846 | return NGX_ERROR; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1847 | } |
| 1848 | |
| 1849 | h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e'); |
| 1850 | |
Igor Sysoev | 05b1a8f | 2010-05-14 09:56:37 +0000 | [diff] [blame] | 1851 | ngx_str_set(&h->key, "Date"); |
| 1852 | ngx_str_null(&h->value); |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 1853 | h->lowcase_key = (u_char *) "date"; |
| 1854 | } |
| 1855 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 1856 | /* clear content length if response is chunked */ |
| 1857 | |
| 1858 | u = r->upstream; |
| 1859 | |
| 1860 | if (u->headers_in.chunked) { |
| 1861 | u->headers_in.content_length_n = -1; |
| 1862 | } |
| 1863 | |
| 1864 | /* |
| 1865 | * set u->keepalive if response has no body; this allows to keep |
| 1866 | * connections alive in case of r->header_only or X-Accel-Redirect |
| 1867 | */ |
| 1868 | |
| 1869 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
| 1870 | |
| 1871 | if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT |
| 1872 | || u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED |
| 1873 | || ctx->head |
| 1874 | || (!u->headers_in.chunked |
| 1875 | && u->headers_in.content_length_n == 0)) |
| 1876 | { |
| 1877 | u->keepalive = !u->headers_in.connection_close; |
| 1878 | } |
| 1879 | |
Maxim Dounin | 08a73b4 | 2013-02-18 13:50:52 +0000 | [diff] [blame] | 1880 | if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS) { |
| 1881 | u->keepalive = 0; |
| 1882 | |
| 1883 | if (r->headers_in.upgrade) { |
| 1884 | u->upgrade = 1; |
| 1885 | } |
| 1886 | } |
| 1887 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1888 | return NGX_OK; |
| 1889 | } |
| 1890 | |
Igor Sysoev | 7b190b4 | 2005-06-07 15:56:31 +0000 | [diff] [blame] | 1891 | if (rc == NGX_AGAIN) { |
| 1892 | return NGX_AGAIN; |
| 1893 | } |
| 1894 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1895 | /* there was error while a header line parsing */ |
| 1896 | |
| 1897 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
Igor Sysoev | 13c6874 | 2006-03-10 12:51:52 +0000 | [diff] [blame] | 1898 | "upstream sent invalid header"); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 1899 | |
| 1900 | return NGX_HTTP_UPSTREAM_INVALID_HEADER; |
| 1901 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 1902 | } |
| 1903 | |
| 1904 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 1905 | static ngx_int_t |
| 1906 | ngx_http_proxy_input_filter_init(void *data) |
| 1907 | { |
| 1908 | ngx_http_request_t *r = data; |
| 1909 | ngx_http_upstream_t *u; |
| 1910 | ngx_http_proxy_ctx_t *ctx; |
| 1911 | |
| 1912 | u = r->upstream; |
| 1913 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
| 1914 | |
Maxim Dounin | c7bb162 | 2012-04-23 10:40:01 +0000 | [diff] [blame] | 1915 | if (ctx == NULL) { |
| 1916 | return NGX_ERROR; |
| 1917 | } |
| 1918 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 1919 | ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
Sergey Kandaurov | b7687bb | 2016-03-31 02:33:57 +0300 | [diff] [blame] | 1920 | "http proxy filter init s:%ui h:%d c:%d l:%O", |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 1921 | u->headers_in.status_n, ctx->head, u->headers_in.chunked, |
| 1922 | u->headers_in.content_length_n); |
| 1923 | |
| 1924 | /* as per RFC2616, 4.4 Message Length */ |
| 1925 | |
| 1926 | if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT |
| 1927 | || u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED |
| 1928 | || ctx->head) |
| 1929 | { |
| 1930 | /* 1xx, 204, and 304 and replies to HEAD requests */ |
| 1931 | /* no 1xx since we don't send Expect and Upgrade */ |
| 1932 | |
| 1933 | u->pipe->length = 0; |
| 1934 | u->length = 0; |
| 1935 | u->keepalive = !u->headers_in.connection_close; |
| 1936 | |
| 1937 | } else if (u->headers_in.chunked) { |
| 1938 | /* chunked */ |
| 1939 | |
| 1940 | u->pipe->input_filter = ngx_http_proxy_chunked_filter; |
| 1941 | u->pipe->length = 3; /* "0" LF LF */ |
| 1942 | |
| 1943 | u->input_filter = ngx_http_proxy_non_buffered_chunked_filter; |
Maxim Dounin | 960d0bf | 2013-07-25 15:00:12 +0400 | [diff] [blame] | 1944 | u->length = 1; |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 1945 | |
| 1946 | } else if (u->headers_in.content_length_n == 0) { |
| 1947 | /* empty body: special case as filter won't be called */ |
| 1948 | |
| 1949 | u->pipe->length = 0; |
| 1950 | u->length = 0; |
| 1951 | u->keepalive = !u->headers_in.connection_close; |
| 1952 | |
| 1953 | } else { |
| 1954 | /* content length or connection close */ |
| 1955 | |
| 1956 | u->pipe->length = u->headers_in.content_length_n; |
| 1957 | u->length = u->headers_in.content_length_n; |
| 1958 | } |
| 1959 | |
| 1960 | return NGX_OK; |
| 1961 | } |
| 1962 | |
| 1963 | |
| 1964 | static ngx_int_t |
| 1965 | ngx_http_proxy_copy_filter(ngx_event_pipe_t *p, ngx_buf_t *buf) |
| 1966 | { |
| 1967 | ngx_buf_t *b; |
| 1968 | ngx_chain_t *cl; |
| 1969 | ngx_http_request_t *r; |
| 1970 | |
| 1971 | if (buf->pos == buf->last) { |
| 1972 | return NGX_OK; |
| 1973 | } |
| 1974 | |
Valentin Bartenev | 2576530 | 2013-12-11 21:30:38 +0400 | [diff] [blame] | 1975 | cl = ngx_chain_get_free_buf(p->pool, &p->free); |
| 1976 | if (cl == NULL) { |
| 1977 | return NGX_ERROR; |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 1978 | } |
| 1979 | |
Valentin Bartenev | 2576530 | 2013-12-11 21:30:38 +0400 | [diff] [blame] | 1980 | b = cl->buf; |
| 1981 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 1982 | ngx_memcpy(b, buf, sizeof(ngx_buf_t)); |
| 1983 | b->shadow = buf; |
| 1984 | b->tag = p->tag; |
| 1985 | b->last_shadow = 1; |
| 1986 | b->recycled = 1; |
| 1987 | buf->shadow = b; |
| 1988 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 1989 | ngx_log_debug1(NGX_LOG_DEBUG_EVENT, p->log, 0, "input buf #%d", b->num); |
| 1990 | |
| 1991 | if (p->in) { |
| 1992 | *p->last_in = cl; |
| 1993 | } else { |
| 1994 | p->in = cl; |
| 1995 | } |
| 1996 | p->last_in = &cl->next; |
| 1997 | |
| 1998 | if (p->length == -1) { |
| 1999 | return NGX_OK; |
| 2000 | } |
| 2001 | |
| 2002 | p->length -= b->last - b->pos; |
| 2003 | |
| 2004 | if (p->length == 0) { |
| 2005 | r = p->input_ctx; |
| 2006 | p->upstream_done = 1; |
| 2007 | r->upstream->keepalive = !r->upstream->headers_in.connection_close; |
| 2008 | |
| 2009 | } else if (p->length < 0) { |
| 2010 | r = p->input_ctx; |
| 2011 | p->upstream_done = 1; |
| 2012 | |
Maxim Dounin | 5c56f20 | 2011-09-25 20:04:20 +0000 | [diff] [blame] | 2013 | ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, |
Maxim Dounin | b343099 | 2012-12-13 13:45:39 +0000 | [diff] [blame] | 2014 | "upstream sent more data than specified in " |
| 2015 | "\"Content-Length\" header"); |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2016 | } |
| 2017 | |
| 2018 | return NGX_OK; |
| 2019 | } |
| 2020 | |
| 2021 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2022 | static ngx_int_t |
| 2023 | ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf) |
| 2024 | { |
| 2025 | ngx_int_t rc; |
| 2026 | ngx_buf_t *b, **prev; |
| 2027 | ngx_chain_t *cl; |
| 2028 | ngx_http_request_t *r; |
| 2029 | ngx_http_proxy_ctx_t *ctx; |
| 2030 | |
| 2031 | if (buf->pos == buf->last) { |
| 2032 | return NGX_OK; |
| 2033 | } |
| 2034 | |
| 2035 | r = p->input_ctx; |
| 2036 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
| 2037 | |
Maxim Dounin | c7bb162 | 2012-04-23 10:40:01 +0000 | [diff] [blame] | 2038 | if (ctx == NULL) { |
| 2039 | return NGX_ERROR; |
| 2040 | } |
| 2041 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2042 | b = NULL; |
| 2043 | prev = &buf->shadow; |
| 2044 | |
| 2045 | for ( ;; ) { |
| 2046 | |
Maxim Dounin | df74d88 | 2012-11-21 00:59:16 +0000 | [diff] [blame] | 2047 | rc = ngx_http_parse_chunked(r, buf, &ctx->chunked); |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2048 | |
| 2049 | if (rc == NGX_OK) { |
| 2050 | |
| 2051 | /* a chunk has been parsed successfully */ |
| 2052 | |
Valentin Bartenev | 2576530 | 2013-12-11 21:30:38 +0400 | [diff] [blame] | 2053 | cl = ngx_chain_get_free_buf(p->pool, &p->free); |
| 2054 | if (cl == NULL) { |
| 2055 | return NGX_ERROR; |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2056 | } |
| 2057 | |
Valentin Bartenev | 2576530 | 2013-12-11 21:30:38 +0400 | [diff] [blame] | 2058 | b = cl->buf; |
| 2059 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2060 | ngx_memzero(b, sizeof(ngx_buf_t)); |
| 2061 | |
| 2062 | b->pos = buf->pos; |
| 2063 | b->start = buf->start; |
| 2064 | b->end = buf->end; |
| 2065 | b->tag = p->tag; |
| 2066 | b->temporary = 1; |
| 2067 | b->recycled = 1; |
| 2068 | |
| 2069 | *prev = b; |
| 2070 | prev = &b->shadow; |
| 2071 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2072 | if (p->in) { |
| 2073 | *p->last_in = cl; |
| 2074 | } else { |
| 2075 | p->in = cl; |
| 2076 | } |
| 2077 | p->last_in = &cl->next; |
| 2078 | |
| 2079 | /* STUB */ b->num = buf->num; |
| 2080 | |
| 2081 | ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0, |
| 2082 | "input buf #%d %p", b->num, b->pos); |
| 2083 | |
Maxim Dounin | df74d88 | 2012-11-21 00:59:16 +0000 | [diff] [blame] | 2084 | if (buf->last - buf->pos >= ctx->chunked.size) { |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2085 | |
Maxim Dounin | 74b7a91 | 2013-09-04 20:48:23 +0400 | [diff] [blame] | 2086 | buf->pos += (size_t) ctx->chunked.size; |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2087 | b->last = buf->pos; |
Maxim Dounin | df74d88 | 2012-11-21 00:59:16 +0000 | [diff] [blame] | 2088 | ctx->chunked.size = 0; |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2089 | |
| 2090 | continue; |
| 2091 | } |
| 2092 | |
Maxim Dounin | df74d88 | 2012-11-21 00:59:16 +0000 | [diff] [blame] | 2093 | ctx->chunked.size -= buf->last - buf->pos; |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2094 | buf->pos = buf->last; |
| 2095 | b->last = buf->last; |
| 2096 | |
| 2097 | continue; |
| 2098 | } |
| 2099 | |
| 2100 | if (rc == NGX_DONE) { |
| 2101 | |
| 2102 | /* a whole response has been parsed successfully */ |
| 2103 | |
| 2104 | p->upstream_done = 1; |
| 2105 | r->upstream->keepalive = !r->upstream->headers_in.connection_close; |
| 2106 | |
| 2107 | break; |
| 2108 | } |
| 2109 | |
| 2110 | if (rc == NGX_AGAIN) { |
| 2111 | |
| 2112 | /* set p->length, minimal amount of data we want to see */ |
| 2113 | |
Maxim Dounin | df74d88 | 2012-11-21 00:59:16 +0000 | [diff] [blame] | 2114 | p->length = ctx->chunked.length; |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2115 | |
| 2116 | break; |
| 2117 | } |
| 2118 | |
| 2119 | /* invalid response */ |
| 2120 | |
Maxim Dounin | 5c56f20 | 2011-09-25 20:04:20 +0000 | [diff] [blame] | 2121 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2122 | "upstream sent invalid chunked response"); |
| 2123 | |
| 2124 | return NGX_ERROR; |
| 2125 | } |
| 2126 | |
| 2127 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
Sergey Kandaurov | b7687bb | 2016-03-31 02:33:57 +0300 | [diff] [blame] | 2128 | "http proxy chunked state %ui, length %O", |
Maxim Dounin | df74d88 | 2012-11-21 00:59:16 +0000 | [diff] [blame] | 2129 | ctx->chunked.state, p->length); |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2130 | |
| 2131 | if (b) { |
| 2132 | b->shadow = buf; |
| 2133 | b->last_shadow = 1; |
| 2134 | |
| 2135 | ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0, |
| 2136 | "input buf %p %z", b->pos, b->last - b->pos); |
| 2137 | |
| 2138 | return NGX_OK; |
| 2139 | } |
| 2140 | |
| 2141 | /* there is no data record in the buf, add it to free chain */ |
| 2142 | |
| 2143 | if (ngx_event_pipe_add_free_buf(p, buf) != NGX_OK) { |
| 2144 | return NGX_ERROR; |
| 2145 | } |
| 2146 | |
| 2147 | return NGX_OK; |
| 2148 | } |
| 2149 | |
| 2150 | |
| 2151 | static ngx_int_t |
| 2152 | ngx_http_proxy_non_buffered_copy_filter(void *data, ssize_t bytes) |
| 2153 | { |
| 2154 | ngx_http_request_t *r = data; |
| 2155 | |
| 2156 | ngx_buf_t *b; |
| 2157 | ngx_chain_t *cl, **ll; |
| 2158 | ngx_http_upstream_t *u; |
| 2159 | |
| 2160 | u = r->upstream; |
| 2161 | |
| 2162 | for (cl = u->out_bufs, ll = &u->out_bufs; cl; cl = cl->next) { |
| 2163 | ll = &cl->next; |
| 2164 | } |
| 2165 | |
| 2166 | cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs); |
| 2167 | if (cl == NULL) { |
| 2168 | return NGX_ERROR; |
| 2169 | } |
| 2170 | |
| 2171 | *ll = cl; |
| 2172 | |
| 2173 | cl->buf->flush = 1; |
| 2174 | cl->buf->memory = 1; |
| 2175 | |
| 2176 | b = &u->buffer; |
| 2177 | |
| 2178 | cl->buf->pos = b->last; |
| 2179 | b->last += bytes; |
| 2180 | cl->buf->last = b->last; |
| 2181 | cl->buf->tag = u->output.tag; |
| 2182 | |
| 2183 | if (u->length == -1) { |
| 2184 | return NGX_OK; |
| 2185 | } |
| 2186 | |
| 2187 | u->length -= bytes; |
| 2188 | |
| 2189 | if (u->length == 0) { |
| 2190 | u->keepalive = !u->headers_in.connection_close; |
| 2191 | } |
| 2192 | |
| 2193 | return NGX_OK; |
| 2194 | } |
| 2195 | |
| 2196 | |
| 2197 | static ngx_int_t |
| 2198 | ngx_http_proxy_non_buffered_chunked_filter(void *data, ssize_t bytes) |
| 2199 | { |
| 2200 | ngx_http_request_t *r = data; |
| 2201 | |
| 2202 | ngx_int_t rc; |
| 2203 | ngx_buf_t *b, *buf; |
| 2204 | ngx_chain_t *cl, **ll; |
| 2205 | ngx_http_upstream_t *u; |
| 2206 | ngx_http_proxy_ctx_t *ctx; |
| 2207 | |
| 2208 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
Maxim Dounin | c7bb162 | 2012-04-23 10:40:01 +0000 | [diff] [blame] | 2209 | |
| 2210 | if (ctx == NULL) { |
| 2211 | return NGX_ERROR; |
| 2212 | } |
| 2213 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2214 | u = r->upstream; |
| 2215 | buf = &u->buffer; |
| 2216 | |
| 2217 | buf->pos = buf->last; |
| 2218 | buf->last += bytes; |
| 2219 | |
| 2220 | for (cl = u->out_bufs, ll = &u->out_bufs; cl; cl = cl->next) { |
| 2221 | ll = &cl->next; |
| 2222 | } |
| 2223 | |
| 2224 | for ( ;; ) { |
| 2225 | |
Maxim Dounin | df74d88 | 2012-11-21 00:59:16 +0000 | [diff] [blame] | 2226 | rc = ngx_http_parse_chunked(r, buf, &ctx->chunked); |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2227 | |
| 2228 | if (rc == NGX_OK) { |
| 2229 | |
| 2230 | /* a chunk has been parsed successfully */ |
| 2231 | |
| 2232 | cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs); |
| 2233 | if (cl == NULL) { |
| 2234 | return NGX_ERROR; |
| 2235 | } |
| 2236 | |
| 2237 | *ll = cl; |
| 2238 | ll = &cl->next; |
| 2239 | |
| 2240 | b = cl->buf; |
| 2241 | |
| 2242 | b->flush = 1; |
| 2243 | b->memory = 1; |
| 2244 | |
| 2245 | b->pos = buf->pos; |
| 2246 | b->tag = u->output.tag; |
| 2247 | |
Maxim Dounin | df74d88 | 2012-11-21 00:59:16 +0000 | [diff] [blame] | 2248 | if (buf->last - buf->pos >= ctx->chunked.size) { |
Maxim Dounin | 74b7a91 | 2013-09-04 20:48:23 +0400 | [diff] [blame] | 2249 | buf->pos += (size_t) ctx->chunked.size; |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2250 | b->last = buf->pos; |
Maxim Dounin | df74d88 | 2012-11-21 00:59:16 +0000 | [diff] [blame] | 2251 | ctx->chunked.size = 0; |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2252 | |
| 2253 | } else { |
Maxim Dounin | df74d88 | 2012-11-21 00:59:16 +0000 | [diff] [blame] | 2254 | ctx->chunked.size -= buf->last - buf->pos; |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2255 | buf->pos = buf->last; |
| 2256 | b->last = buf->last; |
| 2257 | } |
| 2258 | |
| 2259 | ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 2260 | "http proxy out buf %p %z", |
| 2261 | b->pos, b->last - b->pos); |
| 2262 | |
| 2263 | continue; |
| 2264 | } |
| 2265 | |
| 2266 | if (rc == NGX_DONE) { |
| 2267 | |
| 2268 | /* a whole response has been parsed successfully */ |
| 2269 | |
| 2270 | u->keepalive = !u->headers_in.connection_close; |
| 2271 | u->length = 0; |
| 2272 | |
| 2273 | break; |
| 2274 | } |
| 2275 | |
| 2276 | if (rc == NGX_AGAIN) { |
| 2277 | break; |
| 2278 | } |
| 2279 | |
| 2280 | /* invalid response */ |
| 2281 | |
Maxim Dounin | 5c56f20 | 2011-09-25 20:04:20 +0000 | [diff] [blame] | 2282 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2283 | "upstream sent invalid chunked response"); |
| 2284 | |
| 2285 | return NGX_ERROR; |
| 2286 | } |
| 2287 | |
| 2288 | /* provide continuous buffer for subrequests in memory */ |
| 2289 | |
| 2290 | if (r->subrequest_in_memory) { |
| 2291 | |
| 2292 | cl = u->out_bufs; |
| 2293 | |
| 2294 | if (cl) { |
| 2295 | buf->pos = cl->buf->pos; |
| 2296 | } |
| 2297 | |
| 2298 | buf->last = buf->pos; |
| 2299 | |
| 2300 | for (cl = u->out_bufs; cl; cl = cl->next) { |
| 2301 | ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
Sergey Kandaurov | b7687bb | 2016-03-31 02:33:57 +0300 | [diff] [blame] | 2302 | "http proxy in memory %p-%p %O", |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2303 | cl->buf->pos, cl->buf->last, ngx_buf_size(cl->buf)); |
| 2304 | |
| 2305 | if (buf->last == cl->buf->pos) { |
| 2306 | buf->last = cl->buf->last; |
| 2307 | continue; |
| 2308 | } |
| 2309 | |
| 2310 | buf->last = ngx_movemem(buf->last, cl->buf->pos, |
| 2311 | cl->buf->last - cl->buf->pos); |
| 2312 | |
| 2313 | cl->buf->pos = buf->last - (cl->buf->last - cl->buf->pos); |
| 2314 | cl->buf->last = buf->last; |
| 2315 | } |
| 2316 | } |
| 2317 | |
| 2318 | return NGX_OK; |
| 2319 | } |
| 2320 | |
| 2321 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2322 | static void |
| 2323 | ngx_http_proxy_abort_request(ngx_http_request_t *r) |
| 2324 | { |
| 2325 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 2326 | "abort http proxy request"); |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2327 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2328 | return; |
| 2329 | } |
| 2330 | |
| 2331 | |
| 2332 | static void |
| 2333 | 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] | 2334 | { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2335 | ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
| 2336 | "finalize http proxy request"); |
| 2337 | |
| 2338 | return; |
| 2339 | } |
| 2340 | |
| 2341 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2342 | static ngx_int_t |
| 2343 | ngx_http_proxy_host_variable(ngx_http_request_t *r, |
| 2344 | ngx_http_variable_value_t *v, uintptr_t data) |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2345 | { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2346 | ngx_http_proxy_ctx_t *ctx; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2347 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2348 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2349 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2350 | if (ctx == NULL) { |
| 2351 | v->not_found = 1; |
| 2352 | return NGX_OK; |
| 2353 | } |
| 2354 | |
| 2355 | v->len = ctx->vars.host_header.len; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2356 | v->valid = 1; |
Igor Sysoev | 2d3f3f6 | 2007-10-14 18:56:15 +0000 | [diff] [blame] | 2357 | v->no_cacheable = 0; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2358 | v->not_found = 0; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2359 | v->data = ctx->vars.host_header.data; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2360 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2361 | return NGX_OK; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2362 | } |
| 2363 | |
| 2364 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2365 | static ngx_int_t |
| 2366 | ngx_http_proxy_port_variable(ngx_http_request_t *r, |
| 2367 | ngx_http_variable_value_t *v, uintptr_t data) |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2368 | { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2369 | ngx_http_proxy_ctx_t *ctx; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2370 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2371 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2372 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2373 | if (ctx == NULL) { |
| 2374 | v->not_found = 1; |
| 2375 | return NGX_OK; |
| 2376 | } |
| 2377 | |
| 2378 | v->len = ctx->vars.port.len; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2379 | v->valid = 1; |
Igor Sysoev | 2d3f3f6 | 2007-10-14 18:56:15 +0000 | [diff] [blame] | 2380 | v->no_cacheable = 0; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2381 | v->not_found = 0; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2382 | v->data = ctx->vars.port.data; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2383 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2384 | return NGX_OK; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2385 | } |
| 2386 | |
| 2387 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2388 | static ngx_int_t |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2389 | 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] | 2390 | ngx_http_variable_value_t *v, uintptr_t data) |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2391 | { |
Ruslan Ermilov | 67a6872 | 2013-02-27 13:29:50 +0000 | [diff] [blame] | 2392 | size_t len; |
| 2393 | u_char *p; |
| 2394 | ngx_uint_t i, n; |
| 2395 | ngx_table_elt_t **h; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2396 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2397 | v->valid = 1; |
Igor Sysoev | 2d3f3f6 | 2007-10-14 18:56:15 +0000 | [diff] [blame] | 2398 | v->no_cacheable = 0; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2399 | v->not_found = 0; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2400 | |
Ruslan Ermilov | 67a6872 | 2013-02-27 13:29:50 +0000 | [diff] [blame] | 2401 | n = r->headers_in.x_forwarded_for.nelts; |
| 2402 | h = r->headers_in.x_forwarded_for.elts; |
| 2403 | |
| 2404 | len = 0; |
| 2405 | |
| 2406 | for (i = 0; i < n; i++) { |
| 2407 | len += h[i]->value.len + sizeof(", ") - 1; |
| 2408 | } |
| 2409 | |
| 2410 | if (len == 0) { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2411 | v->len = r->connection->addr_text.len; |
| 2412 | v->data = r->connection->addr_text.data; |
| 2413 | return NGX_OK; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2414 | } |
| 2415 | |
Ruslan Ermilov | 67a6872 | 2013-02-27 13:29:50 +0000 | [diff] [blame] | 2416 | len += r->connection->addr_text.len; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2417 | |
Ruslan Ermilov | 67a6872 | 2013-02-27 13:29:50 +0000 | [diff] [blame] | 2418 | p = ngx_pnalloc(r->pool, len); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2419 | if (p == NULL) { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2420 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2421 | } |
| 2422 | |
Ruslan Ermilov | 67a6872 | 2013-02-27 13:29:50 +0000 | [diff] [blame] | 2423 | v->len = len; |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2424 | v->data = p; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2425 | |
Ruslan Ermilov | 67a6872 | 2013-02-27 13:29:50 +0000 | [diff] [blame] | 2426 | for (i = 0; i < n; i++) { |
| 2427 | p = ngx_copy(p, h[i]->value.data, h[i]->value.len); |
| 2428 | *p++ = ','; *p++ = ' '; |
| 2429 | } |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2430 | |
| 2431 | ngx_memcpy(p, r->connection->addr_text.data, r->connection->addr_text.len); |
| 2432 | |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 2433 | return NGX_OK; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2434 | } |
| 2435 | |
| 2436 | |
| 2437 | static ngx_int_t |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2438 | ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r, |
| 2439 | ngx_http_variable_value_t *v, uintptr_t data) |
| 2440 | { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2441 | ngx_http_proxy_ctx_t *ctx; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2442 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 2443 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2444 | |
Maxim Dounin | 9a483c8 | 2012-11-21 01:03:48 +0000 | [diff] [blame] | 2445 | if (ctx == NULL || ctx->internal_body_length < 0) { |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2446 | v->not_found = 1; |
| 2447 | return NGX_OK; |
| 2448 | } |
| 2449 | |
| 2450 | v->valid = 1; |
Igor Sysoev | 2d3f3f6 | 2007-10-14 18:56:15 +0000 | [diff] [blame] | 2451 | v->no_cacheable = 0; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2452 | v->not_found = 0; |
| 2453 | |
Ruslan Ermilov | 9014efd | 2013-04-29 18:58:58 +0400 | [diff] [blame] | 2454 | v->data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN); |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2455 | |
| 2456 | if (v->data == NULL) { |
| 2457 | return NGX_ERROR; |
| 2458 | } |
| 2459 | |
Maxim Dounin | 9a483c8 | 2012-11-21 01:03:48 +0000 | [diff] [blame] | 2460 | v->len = ngx_sprintf(v->data, "%O", ctx->internal_body_length) - v->data; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2461 | |
| 2462 | return NGX_OK; |
| 2463 | } |
| 2464 | |
| 2465 | |
| 2466 | static ngx_int_t |
Maxim Dounin | 55344dd | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 2467 | ngx_http_proxy_internal_chunked_variable(ngx_http_request_t *r, |
| 2468 | ngx_http_variable_value_t *v, uintptr_t data) |
| 2469 | { |
| 2470 | ngx_http_proxy_ctx_t *ctx; |
| 2471 | |
| 2472 | ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
| 2473 | |
| 2474 | if (ctx == NULL || !ctx->internal_chunked) { |
| 2475 | v->not_found = 1; |
| 2476 | return NGX_OK; |
| 2477 | } |
| 2478 | |
| 2479 | v->valid = 1; |
| 2480 | v->no_cacheable = 0; |
| 2481 | v->not_found = 0; |
| 2482 | |
| 2483 | v->data = (u_char *) "chunked"; |
| 2484 | v->len = sizeof("chunked") - 1; |
| 2485 | |
| 2486 | return NGX_OK; |
| 2487 | } |
| 2488 | |
| 2489 | |
| 2490 | static ngx_int_t |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2491 | ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, ngx_table_elt_t *h, |
| 2492 | size_t prefix) |
| 2493 | { |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2494 | size_t len; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2495 | ngx_int_t rc; |
| 2496 | ngx_uint_t i; |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 2497 | ngx_http_proxy_rewrite_t *pr; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2498 | ngx_http_proxy_loc_conf_t *plcf; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2499 | |
| 2500 | plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); |
| 2501 | |
| 2502 | pr = plcf->redirects->elts; |
| 2503 | |
| 2504 | if (pr == NULL) { |
| 2505 | return NGX_DECLINED; |
| 2506 | } |
| 2507 | |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2508 | len = h->value.len - prefix; |
| 2509 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2510 | for (i = 0; i < plcf->redirects->nelts; i++) { |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2511 | rc = pr[i].handler(r, h, prefix, len, &pr[i]); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2512 | |
| 2513 | if (rc != NGX_DECLINED) { |
| 2514 | return rc; |
| 2515 | } |
| 2516 | } |
| 2517 | |
| 2518 | return NGX_DECLINED; |
| 2519 | } |
| 2520 | |
| 2521 | |
| 2522 | static ngx_int_t |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 2523 | ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r, ngx_table_elt_t *h) |
| 2524 | { |
| 2525 | size_t prefix; |
| 2526 | u_char *p; |
Valentin Bartenev | a113cb3 | 2012-02-13 11:08:05 +0000 | [diff] [blame] | 2527 | ngx_int_t rc, rv; |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 2528 | ngx_http_proxy_loc_conf_t *plcf; |
| 2529 | |
| 2530 | p = (u_char *) ngx_strchr(h->value.data, ';'); |
| 2531 | if (p == NULL) { |
| 2532 | return NGX_DECLINED; |
| 2533 | } |
| 2534 | |
| 2535 | prefix = p + 1 - h->value.data; |
| 2536 | |
Valentin Bartenev | a113cb3 | 2012-02-13 11:08:05 +0000 | [diff] [blame] | 2537 | rv = NGX_DECLINED; |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 2538 | |
| 2539 | plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); |
| 2540 | |
| 2541 | if (plcf->cookie_domains) { |
| 2542 | p = ngx_strcasestrn(h->value.data + prefix, "domain=", 7 - 1); |
| 2543 | |
| 2544 | if (p) { |
| 2545 | rc = ngx_http_proxy_rewrite_cookie_value(r, h, p + 7, |
| 2546 | plcf->cookie_domains); |
Valentin Bartenev | a113cb3 | 2012-02-13 11:08:05 +0000 | [diff] [blame] | 2547 | if (rc == NGX_ERROR) { |
| 2548 | return NGX_ERROR; |
| 2549 | } |
| 2550 | |
| 2551 | if (rc != NGX_DECLINED) { |
| 2552 | rv = rc; |
| 2553 | } |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 2554 | } |
| 2555 | } |
| 2556 | |
Valentin Bartenev | a113cb3 | 2012-02-13 11:08:05 +0000 | [diff] [blame] | 2557 | if (plcf->cookie_paths) { |
| 2558 | p = ngx_strcasestrn(h->value.data + prefix, "path=", 5 - 1); |
| 2559 | |
| 2560 | if (p) { |
| 2561 | rc = ngx_http_proxy_rewrite_cookie_value(r, h, p + 5, |
| 2562 | plcf->cookie_paths); |
| 2563 | if (rc == NGX_ERROR) { |
| 2564 | return NGX_ERROR; |
| 2565 | } |
| 2566 | |
| 2567 | if (rc != NGX_DECLINED) { |
| 2568 | rv = rc; |
| 2569 | } |
| 2570 | } |
| 2571 | } |
| 2572 | |
| 2573 | return rv; |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 2574 | } |
| 2575 | |
| 2576 | |
| 2577 | static ngx_int_t |
| 2578 | ngx_http_proxy_rewrite_cookie_value(ngx_http_request_t *r, ngx_table_elt_t *h, |
| 2579 | u_char *value, ngx_array_t *rewrites) |
| 2580 | { |
| 2581 | size_t len, prefix; |
| 2582 | u_char *p; |
| 2583 | ngx_int_t rc; |
| 2584 | ngx_uint_t i; |
| 2585 | ngx_http_proxy_rewrite_t *pr; |
| 2586 | |
| 2587 | prefix = value - h->value.data; |
| 2588 | |
| 2589 | p = (u_char *) ngx_strchr(value, ';'); |
| 2590 | |
| 2591 | len = p ? (size_t) (p - value) : (h->value.len - prefix); |
| 2592 | |
| 2593 | pr = rewrites->elts; |
| 2594 | |
| 2595 | for (i = 0; i < rewrites->nelts; i++) { |
| 2596 | rc = pr[i].handler(r, h, prefix, len, &pr[i]); |
| 2597 | |
| 2598 | if (rc != NGX_DECLINED) { |
| 2599 | return rc; |
| 2600 | } |
| 2601 | } |
| 2602 | |
| 2603 | return NGX_DECLINED; |
| 2604 | } |
| 2605 | |
| 2606 | |
| 2607 | static ngx_int_t |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 2608 | ngx_http_proxy_rewrite_complex_handler(ngx_http_request_t *r, |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2609 | ngx_table_elt_t *h, size_t prefix, size_t len, ngx_http_proxy_rewrite_t *pr) |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2610 | { |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2611 | ngx_str_t pattern, replacement; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2612 | |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 2613 | if (ngx_http_complex_value(r, &pr->pattern.complex, &pattern) != NGX_OK) { |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 2614 | return NGX_ERROR; |
| 2615 | } |
| 2616 | |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2617 | if (pattern.len > len |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 2618 | || ngx_rstrncmp(h->value.data + prefix, pattern.data, |
| 2619 | pattern.len) != 0) |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2620 | { |
| 2621 | return NGX_DECLINED; |
| 2622 | } |
| 2623 | |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 2624 | if (ngx_http_complex_value(r, &pr->replacement, &replacement) != NGX_OK) { |
| 2625 | return NGX_ERROR; |
| 2626 | } |
| 2627 | |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2628 | return ngx_http_proxy_rewrite(r, h, prefix, pattern.len, &replacement); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2629 | } |
| 2630 | |
| 2631 | |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 2632 | #if (NGX_PCRE) |
| 2633 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2634 | static ngx_int_t |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 2635 | ngx_http_proxy_rewrite_regex_handler(ngx_http_request_t *r, ngx_table_elt_t *h, |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2636 | size_t prefix, size_t len, ngx_http_proxy_rewrite_t *pr) |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2637 | { |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2638 | ngx_str_t pattern, replacement; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2639 | |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2640 | pattern.len = len; |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 2641 | pattern.data = h->value.data + prefix; |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 2642 | |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 2643 | if (ngx_http_regex_exec(r, pr->pattern.regex, &pattern) != NGX_OK) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2644 | return NGX_DECLINED; |
| 2645 | } |
| 2646 | |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 2647 | if (ngx_http_complex_value(r, &pr->replacement, &replacement) != NGX_OK) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2648 | return NGX_ERROR; |
| 2649 | } |
| 2650 | |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2651 | if (prefix == 0 && h->value.len == len) { |
Valentin Bartenev | b8ef9d9 | 2012-01-10 15:09:45 +0000 | [diff] [blame] | 2652 | h->value = replacement; |
| 2653 | return NGX_OK; |
| 2654 | } |
| 2655 | |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2656 | return ngx_http_proxy_rewrite(r, h, prefix, len, &replacement); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2657 | } |
| 2658 | |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 2659 | #endif |
| 2660 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2661 | |
| 2662 | static ngx_int_t |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 2663 | ngx_http_proxy_rewrite_domain_handler(ngx_http_request_t *r, |
| 2664 | ngx_table_elt_t *h, size_t prefix, size_t len, ngx_http_proxy_rewrite_t *pr) |
| 2665 | { |
| 2666 | u_char *p; |
| 2667 | ngx_str_t pattern, replacement; |
| 2668 | |
| 2669 | if (ngx_http_complex_value(r, &pr->pattern.complex, &pattern) != NGX_OK) { |
| 2670 | return NGX_ERROR; |
| 2671 | } |
| 2672 | |
| 2673 | p = h->value.data + prefix; |
| 2674 | |
| 2675 | if (p[0] == '.') { |
| 2676 | p++; |
| 2677 | prefix++; |
| 2678 | len--; |
| 2679 | } |
| 2680 | |
| 2681 | if (pattern.len != len || ngx_rstrncasecmp(pattern.data, p, len) != 0) { |
| 2682 | return NGX_DECLINED; |
| 2683 | } |
| 2684 | |
| 2685 | if (ngx_http_complex_value(r, &pr->replacement, &replacement) != NGX_OK) { |
| 2686 | return NGX_ERROR; |
| 2687 | } |
| 2688 | |
| 2689 | return ngx_http_proxy_rewrite(r, h, prefix, len, &replacement); |
| 2690 | } |
| 2691 | |
| 2692 | |
| 2693 | static ngx_int_t |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2694 | ngx_http_proxy_rewrite(ngx_http_request_t *r, ngx_table_elt_t *h, size_t prefix, |
| 2695 | size_t len, ngx_str_t *replacement) |
| 2696 | { |
| 2697 | u_char *p, *data; |
| 2698 | size_t new_len; |
| 2699 | |
| 2700 | new_len = replacement->len + h->value.len - len; |
| 2701 | |
| 2702 | if (replacement->len > len) { |
| 2703 | |
Valentin Bartenev | b533068 | 2013-11-18 03:06:45 +0400 | [diff] [blame] | 2704 | data = ngx_pnalloc(r->pool, new_len + 1); |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2705 | if (data == NULL) { |
| 2706 | return NGX_ERROR; |
| 2707 | } |
| 2708 | |
| 2709 | p = ngx_copy(data, h->value.data, prefix); |
| 2710 | p = ngx_copy(p, replacement->data, replacement->len); |
| 2711 | |
| 2712 | ngx_memcpy(p, h->value.data + prefix + len, |
Valentin Bartenev | b533068 | 2013-11-18 03:06:45 +0400 | [diff] [blame] | 2713 | h->value.len - len - prefix + 1); |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2714 | |
| 2715 | h->value.data = data; |
| 2716 | |
| 2717 | } else { |
| 2718 | p = ngx_copy(h->value.data + prefix, replacement->data, |
| 2719 | replacement->len); |
| 2720 | |
| 2721 | ngx_memmove(p, h->value.data + prefix + len, |
Valentin Bartenev | b533068 | 2013-11-18 03:06:45 +0400 | [diff] [blame] | 2722 | h->value.len - len - prefix + 1); |
Valentin Bartenev | 7c611aa | 2012-02-13 10:56:09 +0000 | [diff] [blame] | 2723 | } |
| 2724 | |
| 2725 | h->value.len = new_len; |
| 2726 | |
| 2727 | return NGX_OK; |
| 2728 | } |
| 2729 | |
| 2730 | |
| 2731 | static ngx_int_t |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2732 | ngx_http_proxy_add_variables(ngx_conf_t *cf) |
| 2733 | { |
| 2734 | ngx_http_variable_t *var, *v; |
| 2735 | |
| 2736 | for (v = ngx_http_proxy_vars; v->name.len; v++) { |
| 2737 | var = ngx_http_add_variable(cf, &v->name, v->flags); |
| 2738 | if (var == NULL) { |
| 2739 | return NGX_ERROR; |
| 2740 | } |
| 2741 | |
Igor Sysoev | 7bdb720 | 2006-04-19 15:30:56 +0000 | [diff] [blame] | 2742 | var->get_handler = v->get_handler; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2743 | var->data = v->data; |
| 2744 | } |
| 2745 | |
| 2746 | return NGX_OK; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2747 | } |
| 2748 | |
| 2749 | |
| 2750 | static void * |
Valentin Bartenev | 9a0eb4f | 2014-12-22 12:59:09 +0300 | [diff] [blame] | 2751 | ngx_http_proxy_create_main_conf(ngx_conf_t *cf) |
| 2752 | { |
| 2753 | ngx_http_proxy_main_conf_t *conf; |
| 2754 | |
| 2755 | conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_main_conf_t)); |
| 2756 | if (conf == NULL) { |
| 2757 | return NULL; |
| 2758 | } |
| 2759 | |
| 2760 | #if (NGX_HTTP_CACHE) |
| 2761 | if (ngx_array_init(&conf->caches, cf->pool, 4, |
| 2762 | sizeof(ngx_http_file_cache_t *)) |
| 2763 | != NGX_OK) |
| 2764 | { |
| 2765 | return NULL; |
| 2766 | } |
| 2767 | #endif |
| 2768 | |
| 2769 | return conf; |
| 2770 | } |
| 2771 | |
| 2772 | |
| 2773 | static void * |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2774 | ngx_http_proxy_create_loc_conf(ngx_conf_t *cf) |
| 2775 | { |
| 2776 | ngx_http_proxy_loc_conf_t *conf; |
| 2777 | |
| 2778 | conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_loc_conf_t)); |
| 2779 | if (conf == NULL) { |
Igor Sysoev | 260c432 | 2009-06-02 16:09:44 +0000 | [diff] [blame] | 2780 | return NULL; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2781 | } |
| 2782 | |
| 2783 | /* |
| 2784 | * set by ngx_pcalloc(): |
| 2785 | * |
| 2786 | * conf->upstream.bufs.num = 0; |
Igor Sysoev | b01c9cc | 2009-04-30 16:15:07 +0000 | [diff] [blame] | 2787 | * conf->upstream.ignore_headers = 0; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2788 | * conf->upstream.next_upstream = 0; |
Valentin Bartenev | 5de6662 | 2014-12-22 12:59:02 +0300 | [diff] [blame] | 2789 | * conf->upstream.cache_zone = NULL; |
Igor Sysoev | 5ed3691 | 2009-05-19 13:27:27 +0000 | [diff] [blame] | 2790 | * conf->upstream.cache_use_stale = 0; |
| 2791 | * conf->upstream.cache_methods = 0; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2792 | * conf->upstream.temp_path = NULL; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 2793 | * conf->upstream.hide_headers_hash = { NULL, 0 }; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2794 | * conf->upstream.uri = { 0, NULL }; |
| 2795 | * conf->upstream.location = NULL; |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 2796 | * conf->upstream.store_lengths = NULL; |
| 2797 | * conf->upstream.store_values = NULL; |
Maxim Dounin | 59ef4a3 | 2014-04-18 20:13:28 +0400 | [diff] [blame] | 2798 | * conf->upstream.ssl_name = NULL; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2799 | * |
Maxim Dounin | aa0b86f | 2013-01-22 12:36:00 +0000 | [diff] [blame] | 2800 | * conf->method = { 0, NULL }; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2801 | * conf->headers_source = NULL; |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 2802 | * conf->headers.lengths = NULL; |
| 2803 | * conf->headers.values = NULL; |
| 2804 | * conf->headers.hash = { NULL, 0 }; |
Roman Arutyunyan | 8898c97 | 2014-11-19 17:33:23 +0300 | [diff] [blame] | 2805 | * conf->headers_cache.lengths = NULL; |
| 2806 | * conf->headers_cache.values = NULL; |
| 2807 | * conf->headers_cache.hash = { NULL, 0 }; |
Roman Arutyunyan | 1b79cb2 | 2014-11-19 17:33:24 +0300 | [diff] [blame] | 2808 | * conf->body_lengths = NULL; |
| 2809 | * conf->body_values = NULL; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2810 | * conf->body_source = { 0, NULL }; |
Igor Sysoev | 931d88c | 2010-03-10 14:37:18 +0000 | [diff] [blame] | 2811 | * conf->redirects = NULL; |
Andrei Belov | 003b2cd | 2013-09-19 18:30:33 +0400 | [diff] [blame] | 2812 | * conf->ssl = 0; |
| 2813 | * conf->ssl_protocols = 0; |
Piotr Sikora | 43736b1 | 2013-09-23 15:58:28 -0700 | [diff] [blame] | 2814 | * conf->ssl_ciphers = { 0, NULL }; |
Maxim Dounin | 27475dd | 2014-04-18 20:13:30 +0400 | [diff] [blame] | 2815 | * conf->ssl_trusted_certificate = { 0, NULL }; |
| 2816 | * conf->ssl_crl = { 0, NULL }; |
Piotr Sikora | a9d9b09 | 2014-10-30 04:30:41 -0700 | [diff] [blame] | 2817 | * conf->ssl_certificate = { 0, NULL }; |
| 2818 | * conf->ssl_certificate_key = { 0, NULL }; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2819 | */ |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2820 | |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 2821 | conf->upstream.store = NGX_CONF_UNSET; |
| 2822 | conf->upstream.store_access = NGX_CONF_UNSET_UINT; |
Roman Arutyunyan | 02ce6c4 | 2014-09-12 18:50:47 +0400 | [diff] [blame] | 2823 | conf->upstream.next_upstream_tries = NGX_CONF_UNSET_UINT; |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 2824 | conf->upstream.buffering = NGX_CONF_UNSET; |
Maxim Dounin | f568ff8 | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 2825 | conf->upstream.request_buffering = NGX_CONF_UNSET; |
Igor Sysoev | 6d16e1e | 2006-04-05 13:40:54 +0000 | [diff] [blame] | 2826 | conf->upstream.ignore_client_abort = NGX_CONF_UNSET; |
Roman Arutyunyan | 2244a5e | 2014-10-14 18:32:01 +0400 | [diff] [blame] | 2827 | conf->upstream.force_ranges = NGX_CONF_UNSET; |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 2828 | |
Ruslan Ermilov | 5d143ca | 2013-01-16 09:42:57 +0000 | [diff] [blame] | 2829 | conf->upstream.local = NGX_CONF_UNSET_PTR; |
| 2830 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2831 | conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC; |
| 2832 | conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC; |
| 2833 | conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC; |
Roman Arutyunyan | 02ce6c4 | 2014-09-12 18:50:47 +0400 | [diff] [blame] | 2834 | conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2835 | |
| 2836 | conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE; |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 2837 | conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE; |
Roman Arutyunyan | 18e4d04 | 2014-10-28 12:29:59 +0300 | [diff] [blame] | 2838 | conf->upstream.limit_rate = NGX_CONF_UNSET_SIZE; |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 2839 | |
| 2840 | conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2841 | conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE; |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 2842 | conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2843 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2844 | conf->upstream.pass_request_headers = NGX_CONF_UNSET; |
| 2845 | conf->upstream.pass_request_body = NGX_CONF_UNSET; |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 2846 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2847 | #if (NGX_HTTP_CACHE) |
Valentin Bartenev | 5de6662 | 2014-12-22 12:59:02 +0300 | [diff] [blame] | 2848 | conf->upstream.cache = NGX_CONF_UNSET; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2849 | conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; |
Igor Sysoev | f7d659a | 2010-07-19 09:36:04 +0000 | [diff] [blame] | 2850 | conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR; |
Igor Sysoev | 9b2763a | 2010-05-24 11:01:05 +0000 | [diff] [blame] | 2851 | conf->upstream.no_cache = NGX_CONF_UNSET_PTR; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2852 | conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; |
Maxim Dounin | 822fe46 | 2011-12-26 11:15:23 +0000 | [diff] [blame] | 2853 | conf->upstream.cache_lock = NGX_CONF_UNSET; |
| 2854 | conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC; |
Roman Arutyunyan | 2628cc1 | 2014-11-18 20:41:12 +0300 | [diff] [blame] | 2855 | conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC; |
Maxim Dounin | 1ac2693 | 2013-11-18 20:48:22 +0400 | [diff] [blame] | 2856 | conf->upstream.cache_revalidate = NGX_CONF_UNSET; |
Roman Arutyunyan | f0ee4eb | 2015-11-11 15:47:30 +0300 | [diff] [blame] | 2857 | conf->upstream.cache_convert_head = NGX_CONF_UNSET; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2858 | #endif |
| 2859 | |
Igor Sysoev | cb54061 | 2007-12-09 18:03:20 +0000 | [diff] [blame] | 2860 | conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; |
| 2861 | conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; |
| 2862 | |
Igor Sysoev | ef809b8 | 2006-06-28 16:00:26 +0000 | [diff] [blame] | 2863 | conf->upstream.intercept_errors = NGX_CONF_UNSET; |
Maxim Dounin | 59ef4a3 | 2014-04-18 20:13:28 +0400 | [diff] [blame] | 2864 | |
Igor Sysoev | 916ee8e | 2008-08-17 17:47:52 +0000 | [diff] [blame] | 2865 | #if (NGX_HTTP_SSL) |
| 2866 | conf->upstream.ssl_session_reuse = NGX_CONF_UNSET; |
Maxim Dounin | 59ef4a3 | 2014-04-18 20:13:28 +0400 | [diff] [blame] | 2867 | conf->upstream.ssl_server_name = NGX_CONF_UNSET; |
Maxim Dounin | 27475dd | 2014-04-18 20:13:30 +0400 | [diff] [blame] | 2868 | conf->upstream.ssl_verify = NGX_CONF_UNSET; |
| 2869 | conf->ssl_verify_depth = NGX_CONF_UNSET_UINT; |
Piotr Sikora | a9d9b09 | 2014-10-30 04:30:41 -0700 | [diff] [blame] | 2870 | conf->ssl_passwords = NGX_CONF_UNSET_PTR; |
Igor Sysoev | 916ee8e | 2008-08-17 17:47:52 +0000 | [diff] [blame] | 2871 | #endif |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2872 | |
| 2873 | /* "proxy_cyclic_temp_file" is disabled */ |
| 2874 | conf->upstream.cyclic_temp_file = 0; |
| 2875 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2876 | conf->redirect = NGX_CONF_UNSET; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 2877 | conf->upstream.change_buffering = 1; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2878 | |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 2879 | conf->cookie_domains = NGX_CONF_UNSET_PTR; |
Valentin Bartenev | a113cb3 | 2012-02-13 11:08:05 +0000 | [diff] [blame] | 2880 | conf->cookie_paths = NGX_CONF_UNSET_PTR; |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 2881 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 2882 | conf->http_version = NGX_CONF_UNSET_UINT; |
| 2883 | |
Igor Sysoev | 8a19bff | 2007-04-22 20:21:59 +0000 | [diff] [blame] | 2884 | conf->headers_hash_max_size = NGX_CONF_UNSET_UINT; |
| 2885 | conf->headers_hash_bucket_size = NGX_CONF_UNSET_UINT; |
| 2886 | |
Igor Sysoev | c2f852c | 2011-07-29 15:33:03 +0000 | [diff] [blame] | 2887 | ngx_str_set(&conf->upstream.module, "proxy"); |
| 2888 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2889 | return conf; |
| 2890 | } |
| 2891 | |
| 2892 | |
| 2893 | static char * |
| 2894 | ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) |
| 2895 | { |
| 2896 | ngx_http_proxy_loc_conf_t *prev = parent; |
| 2897 | ngx_http_proxy_loc_conf_t *conf = child; |
| 2898 | |
Igor Sysoev | b249225 | 2011-02-17 11:54:35 +0000 | [diff] [blame] | 2899 | u_char *p; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2900 | size_t size; |
Roman Arutyunyan | 8898c97 | 2014-11-19 17:33:23 +0300 | [diff] [blame] | 2901 | ngx_int_t rc; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2902 | ngx_hash_init_t hash; |
Igor Sysoev | 90f9552 | 2010-08-03 09:24:25 +0000 | [diff] [blame] | 2903 | ngx_http_core_loc_conf_t *clcf; |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 2904 | ngx_http_proxy_rewrite_t *pr; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 2905 | ngx_http_script_compile_t sc; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 2906 | |
Valentin Bartenev | e764ffb | 2014-12-22 12:58:59 +0300 | [diff] [blame] | 2907 | #if (NGX_HTTP_CACHE) |
| 2908 | |
| 2909 | if (conf->upstream.store > 0) { |
Valentin Bartenev | 5de6662 | 2014-12-22 12:59:02 +0300 | [diff] [blame] | 2910 | conf->upstream.cache = 0; |
Valentin Bartenev | e764ffb | 2014-12-22 12:58:59 +0300 | [diff] [blame] | 2911 | } |
| 2912 | |
Valentin Bartenev | 5de6662 | 2014-12-22 12:59:02 +0300 | [diff] [blame] | 2913 | if (conf->upstream.cache > 0) { |
Valentin Bartenev | e764ffb | 2014-12-22 12:58:59 +0300 | [diff] [blame] | 2914 | conf->upstream.store = 0; |
| 2915 | } |
| 2916 | |
| 2917 | #endif |
| 2918 | |
Valentin Bartenev | c562b74 | 2014-10-09 20:30:11 +0400 | [diff] [blame] | 2919 | if (conf->upstream.store == NGX_CONF_UNSET) { |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 2920 | ngx_conf_merge_value(conf->upstream.store, |
Igor Sysoev | da28ef8 | 2009-05-28 13:31:43 +0000 | [diff] [blame] | 2921 | prev->upstream.store, 0); |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 2922 | |
Valentin Bartenev | a4b7b10 | 2014-12-22 12:58:56 +0300 | [diff] [blame] | 2923 | conf->upstream.store_lengths = prev->upstream.store_lengths; |
| 2924 | conf->upstream.store_values = prev->upstream.store_values; |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 2925 | } |
| 2926 | |
| 2927 | ngx_conf_merge_uint_value(conf->upstream.store_access, |
| 2928 | prev->upstream.store_access, 0600); |
Igor Sysoev | 58feb53 | 2007-07-12 11:19:05 +0000 | [diff] [blame] | 2929 | |
Roman Arutyunyan | 02ce6c4 | 2014-09-12 18:50:47 +0400 | [diff] [blame] | 2930 | ngx_conf_merge_uint_value(conf->upstream.next_upstream_tries, |
| 2931 | prev->upstream.next_upstream_tries, 0); |
| 2932 | |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 2933 | ngx_conf_merge_value(conf->upstream.buffering, |
| 2934 | prev->upstream.buffering, 1); |
| 2935 | |
Maxim Dounin | f568ff8 | 2015-03-23 21:09:19 +0300 | [diff] [blame] | 2936 | ngx_conf_merge_value(conf->upstream.request_buffering, |
| 2937 | prev->upstream.request_buffering, 1); |
| 2938 | |
Igor Sysoev | 6d16e1e | 2006-04-05 13:40:54 +0000 | [diff] [blame] | 2939 | ngx_conf_merge_value(conf->upstream.ignore_client_abort, |
| 2940 | prev->upstream.ignore_client_abort, 0); |
| 2941 | |
Roman Arutyunyan | 2244a5e | 2014-10-14 18:32:01 +0400 | [diff] [blame] | 2942 | ngx_conf_merge_value(conf->upstream.force_ranges, |
| 2943 | prev->upstream.force_ranges, 0); |
| 2944 | |
Ruslan Ermilov | 5d143ca | 2013-01-16 09:42:57 +0000 | [diff] [blame] | 2945 | ngx_conf_merge_ptr_value(conf->upstream.local, |
| 2946 | prev->upstream.local, NULL); |
| 2947 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2948 | ngx_conf_merge_msec_value(conf->upstream.connect_timeout, |
| 2949 | prev->upstream.connect_timeout, 60000); |
| 2950 | |
| 2951 | ngx_conf_merge_msec_value(conf->upstream.send_timeout, |
| 2952 | prev->upstream.send_timeout, 60000); |
| 2953 | |
| 2954 | ngx_conf_merge_msec_value(conf->upstream.read_timeout, |
| 2955 | prev->upstream.read_timeout, 60000); |
| 2956 | |
Roman Arutyunyan | 02ce6c4 | 2014-09-12 18:50:47 +0400 | [diff] [blame] | 2957 | ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout, |
| 2958 | prev->upstream.next_upstream_timeout, 0); |
| 2959 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2960 | ngx_conf_merge_size_value(conf->upstream.send_lowat, |
| 2961 | prev->upstream.send_lowat, 0); |
| 2962 | |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 2963 | ngx_conf_merge_size_value(conf->upstream.buffer_size, |
| 2964 | prev->upstream.buffer_size, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2965 | (size_t) ngx_pagesize); |
| 2966 | |
Roman Arutyunyan | 18e4d04 | 2014-10-28 12:29:59 +0300 | [diff] [blame] | 2967 | ngx_conf_merge_size_value(conf->upstream.limit_rate, |
| 2968 | prev->upstream.limit_rate, 0); |
| 2969 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2970 | ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs, |
| 2971 | 8, ngx_pagesize); |
| 2972 | |
| 2973 | if (conf->upstream.bufs.num < 2) { |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2974 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2975 | "there must be at least 2 \"proxy_buffers\""); |
| 2976 | return NGX_CONF_ERROR; |
| 2977 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2978 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2979 | |
Igor Sysoev | c31a9bb | 2005-11-26 10:11:11 +0000 | [diff] [blame] | 2980 | size = conf->upstream.buffer_size; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2981 | if (size < conf->upstream.bufs.size) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2982 | size = conf->upstream.bufs.size; |
| 2983 | } |
| 2984 | |
| 2985 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 2986 | ngx_conf_merge_size_value(conf->upstream.busy_buffers_size_conf, |
| 2987 | prev->upstream.busy_buffers_size_conf, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2988 | NGX_CONF_UNSET_SIZE); |
| 2989 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 2990 | if (conf->upstream.busy_buffers_size_conf == NGX_CONF_UNSET_SIZE) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2991 | conf->upstream.busy_buffers_size = 2 * size; |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 2992 | } else { |
| 2993 | conf->upstream.busy_buffers_size = |
| 2994 | conf->upstream.busy_buffers_size_conf; |
| 2995 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 2996 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 2997 | if (conf->upstream.busy_buffers_size < size) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 2998 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
Ruslan Ermilov | 43d2b1c | 2012-04-12 19:35:41 +0000 | [diff] [blame] | 2999 | "\"proxy_busy_buffers_size\" must be equal to or greater than " |
| 3000 | "the maximum of the value of \"proxy_buffer_size\" and " |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3001 | "one of the \"proxy_buffers\""); |
| 3002 | |
| 3003 | return NGX_CONF_ERROR; |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 3004 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3005 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 3006 | if (conf->upstream.busy_buffers_size |
| 3007 | > (conf->upstream.bufs.num - 1) * conf->upstream.bufs.size) |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3008 | { |
| 3009 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 3010 | "\"proxy_busy_buffers_size\" must be less than " |
| 3011 | "the size of all \"proxy_buffers\" minus one buffer"); |
| 3012 | |
| 3013 | return NGX_CONF_ERROR; |
| 3014 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3015 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 3016 | |
| 3017 | ngx_conf_merge_size_value(conf->upstream.temp_file_write_size_conf, |
| 3018 | prev->upstream.temp_file_write_size_conf, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3019 | NGX_CONF_UNSET_SIZE); |
| 3020 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 3021 | if (conf->upstream.temp_file_write_size_conf == NGX_CONF_UNSET_SIZE) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3022 | conf->upstream.temp_file_write_size = 2 * size; |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 3023 | } else { |
| 3024 | conf->upstream.temp_file_write_size = |
| 3025 | conf->upstream.temp_file_write_size_conf; |
| 3026 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 3027 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 3028 | if (conf->upstream.temp_file_write_size < size) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3029 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
Ruslan Ermilov | 43d2b1c | 2012-04-12 19:35:41 +0000 | [diff] [blame] | 3030 | "\"proxy_temp_file_write_size\" must be equal to or greater " |
| 3031 | "than the maximum of the value of \"proxy_buffer_size\" and " |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3032 | "one of the \"proxy_buffers\""); |
| 3033 | |
| 3034 | return NGX_CONF_ERROR; |
| 3035 | } |
| 3036 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 3037 | ngx_conf_merge_size_value(conf->upstream.max_temp_file_size_conf, |
| 3038 | prev->upstream.max_temp_file_size_conf, |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3039 | NGX_CONF_UNSET_SIZE); |
| 3040 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 3041 | if (conf->upstream.max_temp_file_size_conf == NGX_CONF_UNSET_SIZE) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3042 | conf->upstream.max_temp_file_size = 1024 * 1024 * 1024; |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 3043 | } else { |
| 3044 | conf->upstream.max_temp_file_size = |
| 3045 | conf->upstream.max_temp_file_size_conf; |
| 3046 | } |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3047 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 3048 | if (conf->upstream.max_temp_file_size != 0 |
| 3049 | && conf->upstream.max_temp_file_size < size) |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3050 | { |
| 3051 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 3052 | "\"proxy_max_temp_file_size\" must be equal to zero to disable " |
Ruslan Ermilov | 43d2b1c | 2012-04-12 19:35:41 +0000 | [diff] [blame] | 3053 | "temporary files usage or must be equal to or greater than " |
| 3054 | "the maximum of the value of \"proxy_buffer_size\" and " |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 3055 | "one of the \"proxy_buffers\""); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3056 | |
| 3057 | return NGX_CONF_ERROR; |
| 3058 | } |
| 3059 | |
Igor Sysoev | 187b7d9 | 2005-07-14 12:51:53 +0000 | [diff] [blame] | 3060 | |
Igor Sysoev | b01c9cc | 2009-04-30 16:15:07 +0000 | [diff] [blame] | 3061 | ngx_conf_merge_bitmask_value(conf->upstream.ignore_headers, |
| 3062 | prev->upstream.ignore_headers, |
| 3063 | NGX_CONF_BITMASK_SET); |
| 3064 | |
| 3065 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3066 | ngx_conf_merge_bitmask_value(conf->upstream.next_upstream, |
| 3067 | prev->upstream.next_upstream, |
| 3068 | (NGX_CONF_BITMASK_SET |
| 3069 | |NGX_HTTP_UPSTREAM_FT_ERROR |
| 3070 | |NGX_HTTP_UPSTREAM_FT_TIMEOUT)); |
| 3071 | |
Igor Sysoev | bb28b6d | 2006-07-11 13:20:19 +0000 | [diff] [blame] | 3072 | if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) { |
| 3073 | conf->upstream.next_upstream = NGX_CONF_BITMASK_SET |
| 3074 | |NGX_HTTP_UPSTREAM_FT_OFF; |
| 3075 | } |
| 3076 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3077 | if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3078 | prev->upstream.temp_path, |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3079 | &ngx_http_proxy_temp_path) |
| 3080 | != NGX_OK) |
| 3081 | { |
| 3082 | return NGX_CONF_ERROR; |
| 3083 | } |
| 3084 | |
| 3085 | |
| 3086 | #if (NGX_HTTP_CACHE) |
| 3087 | |
Valentin Bartenev | 5de6662 | 2014-12-22 12:59:02 +0300 | [diff] [blame] | 3088 | if (conf->upstream.cache == NGX_CONF_UNSET) { |
| 3089 | ngx_conf_merge_value(conf->upstream.cache, |
| 3090 | prev->upstream.cache, 0); |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3091 | |
Valentin Bartenev | 5de6662 | 2014-12-22 12:59:02 +0300 | [diff] [blame] | 3092 | conf->upstream.cache_zone = prev->upstream.cache_zone; |
Valentin Bartenev | 9a0eb4f | 2014-12-22 12:59:09 +0300 | [diff] [blame] | 3093 | conf->upstream.cache_value = prev->upstream.cache_value; |
Valentin Bartenev | 5de6662 | 2014-12-22 12:59:02 +0300 | [diff] [blame] | 3094 | } |
| 3095 | |
| 3096 | if (conf->upstream.cache_zone && conf->upstream.cache_zone->data == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3097 | ngx_shm_zone_t *shm_zone; |
| 3098 | |
Valentin Bartenev | 5de6662 | 2014-12-22 12:59:02 +0300 | [diff] [blame] | 3099 | shm_zone = conf->upstream.cache_zone; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3100 | |
| 3101 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 3102 | "\"proxy_cache\" zone \"%V\" is unknown", |
Igor Sysoev | c7f876b | 2009-04-16 19:25:09 +0000 | [diff] [blame] | 3103 | &shm_zone->shm.name); |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3104 | |
| 3105 | return NGX_CONF_ERROR; |
| 3106 | } |
| 3107 | |
| 3108 | ngx_conf_merge_uint_value(conf->upstream.cache_min_uses, |
| 3109 | prev->upstream.cache_min_uses, 1); |
| 3110 | |
| 3111 | ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale, |
| 3112 | prev->upstream.cache_use_stale, |
| 3113 | (NGX_CONF_BITMASK_SET |
| 3114 | |NGX_HTTP_UPSTREAM_FT_OFF)); |
| 3115 | |
Maxim Dounin | 2c55914 | 2012-01-16 11:01:52 +0000 | [diff] [blame] | 3116 | if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) { |
| 3117 | conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET |
| 3118 | |NGX_HTTP_UPSTREAM_FT_OFF; |
| 3119 | } |
| 3120 | |
| 3121 | if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_ERROR) { |
| 3122 | conf->upstream.cache_use_stale |= NGX_HTTP_UPSTREAM_FT_NOLIVE; |
| 3123 | } |
| 3124 | |
Igor Sysoev | 5ed3691 | 2009-05-19 13:27:27 +0000 | [diff] [blame] | 3125 | if (conf->upstream.cache_methods == 0) { |
| 3126 | conf->upstream.cache_methods = prev->upstream.cache_methods; |
| 3127 | } |
| 3128 | |
| 3129 | conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD; |
| 3130 | |
Igor Sysoev | f7d659a | 2010-07-19 09:36:04 +0000 | [diff] [blame] | 3131 | ngx_conf_merge_ptr_value(conf->upstream.cache_bypass, |
| 3132 | prev->upstream.cache_bypass, NULL); |
| 3133 | |
Igor Sysoev | 9b2763a | 2010-05-24 11:01:05 +0000 | [diff] [blame] | 3134 | ngx_conf_merge_ptr_value(conf->upstream.no_cache, |
| 3135 | prev->upstream.no_cache, NULL); |
| 3136 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3137 | ngx_conf_merge_ptr_value(conf->upstream.cache_valid, |
| 3138 | prev->upstream.cache_valid, NULL); |
| 3139 | |
Igor Sysoev | 44a69c8 | 2009-04-06 08:58:44 +0000 | [diff] [blame] | 3140 | if (conf->cache_key.value.data == NULL) { |
| 3141 | conf->cache_key = prev->cache_key; |
| 3142 | } |
| 3143 | |
Maxim Dounin | 822fe46 | 2011-12-26 11:15:23 +0000 | [diff] [blame] | 3144 | ngx_conf_merge_value(conf->upstream.cache_lock, |
| 3145 | prev->upstream.cache_lock, 0); |
| 3146 | |
| 3147 | ngx_conf_merge_msec_value(conf->upstream.cache_lock_timeout, |
| 3148 | prev->upstream.cache_lock_timeout, 5000); |
| 3149 | |
Roman Arutyunyan | 2628cc1 | 2014-11-18 20:41:12 +0300 | [diff] [blame] | 3150 | ngx_conf_merge_msec_value(conf->upstream.cache_lock_age, |
| 3151 | prev->upstream.cache_lock_age, 5000); |
| 3152 | |
Maxim Dounin | 1ac2693 | 2013-11-18 20:48:22 +0400 | [diff] [blame] | 3153 | ngx_conf_merge_value(conf->upstream.cache_revalidate, |
| 3154 | prev->upstream.cache_revalidate, 0); |
| 3155 | |
Roman Arutyunyan | f0ee4eb | 2015-11-11 15:47:30 +0300 | [diff] [blame] | 3156 | ngx_conf_merge_value(conf->upstream.cache_convert_head, |
| 3157 | prev->upstream.cache_convert_head, 1); |
| 3158 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3159 | #endif |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3160 | |
Maxim Dounin | aa0b86f | 2013-01-22 12:36:00 +0000 | [diff] [blame] | 3161 | ngx_conf_merge_str_value(conf->method, prev->method, ""); |
Igor Sysoev | 7845223 | 2005-10-12 13:50:36 +0000 | [diff] [blame] | 3162 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3163 | ngx_conf_merge_value(conf->upstream.pass_request_headers, |
| 3164 | prev->upstream.pass_request_headers, 1); |
| 3165 | ngx_conf_merge_value(conf->upstream.pass_request_body, |
| 3166 | prev->upstream.pass_request_body, 1); |
| 3167 | |
Igor Sysoev | ef809b8 | 2006-06-28 16:00:26 +0000 | [diff] [blame] | 3168 | ngx_conf_merge_value(conf->upstream.intercept_errors, |
| 3169 | prev->upstream.intercept_errors, 0); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3170 | |
Igor Sysoev | 916ee8e | 2008-08-17 17:47:52 +0000 | [diff] [blame] | 3171 | #if (NGX_HTTP_SSL) |
Maxim Dounin | 59ef4a3 | 2014-04-18 20:13:28 +0400 | [diff] [blame] | 3172 | |
Igor Sysoev | 916ee8e | 2008-08-17 17:47:52 +0000 | [diff] [blame] | 3173 | ngx_conf_merge_value(conf->upstream.ssl_session_reuse, |
| 3174 | prev->upstream.ssl_session_reuse, 1); |
Andrei Belov | 003b2cd | 2013-09-19 18:30:33 +0400 | [diff] [blame] | 3175 | |
| 3176 | ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols, |
Maxim Dounin | ae0d1e5 | 2015-05-25 17:58:20 +0300 | [diff] [blame] | 3177 | (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 |
| 3178 | |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); |
Andrei Belov | 003b2cd | 2013-09-19 18:30:33 +0400 | [diff] [blame] | 3179 | |
Piotr Sikora | 43736b1 | 2013-09-23 15:58:28 -0700 | [diff] [blame] | 3180 | ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers, |
| 3181 | "DEFAULT"); |
| 3182 | |
Maxim Dounin | 59ef4a3 | 2014-04-18 20:13:28 +0400 | [diff] [blame] | 3183 | if (conf->upstream.ssl_name == NULL) { |
| 3184 | conf->upstream.ssl_name = prev->upstream.ssl_name; |
| 3185 | } |
| 3186 | |
| 3187 | ngx_conf_merge_value(conf->upstream.ssl_server_name, |
| 3188 | prev->upstream.ssl_server_name, 0); |
Maxim Dounin | 27475dd | 2014-04-18 20:13:30 +0400 | [diff] [blame] | 3189 | ngx_conf_merge_value(conf->upstream.ssl_verify, |
| 3190 | prev->upstream.ssl_verify, 0); |
| 3191 | ngx_conf_merge_uint_value(conf->ssl_verify_depth, |
| 3192 | prev->ssl_verify_depth, 1); |
| 3193 | ngx_conf_merge_str_value(conf->ssl_trusted_certificate, |
| 3194 | prev->ssl_trusted_certificate, ""); |
| 3195 | ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, ""); |
Maxim Dounin | 59ef4a3 | 2014-04-18 20:13:28 +0400 | [diff] [blame] | 3196 | |
Piotr Sikora | a9d9b09 | 2014-10-30 04:30:41 -0700 | [diff] [blame] | 3197 | ngx_conf_merge_str_value(conf->ssl_certificate, |
| 3198 | prev->ssl_certificate, ""); |
| 3199 | ngx_conf_merge_str_value(conf->ssl_certificate_key, |
| 3200 | prev->ssl_certificate_key, ""); |
| 3201 | ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL); |
| 3202 | |
Andrei Belov | 003b2cd | 2013-09-19 18:30:33 +0400 | [diff] [blame] | 3203 | if (conf->ssl && ngx_http_proxy_set_ssl(cf, conf) != NGX_OK) { |
| 3204 | return NGX_CONF_ERROR; |
| 3205 | } |
Maxim Dounin | 59ef4a3 | 2014-04-18 20:13:28 +0400 | [diff] [blame] | 3206 | |
Igor Sysoev | 916ee8e | 2008-08-17 17:47:52 +0000 | [diff] [blame] | 3207 | #endif |
| 3208 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3209 | ngx_conf_merge_value(conf->redirect, prev->redirect, 1); |
| 3210 | |
| 3211 | if (conf->redirect) { |
| 3212 | |
| 3213 | if (conf->redirects == NULL) { |
| 3214 | conf->redirects = prev->redirects; |
| 3215 | } |
| 3216 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 3217 | if (conf->redirects == NULL && conf->url.data) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3218 | |
| 3219 | conf->redirects = ngx_array_create(cf->pool, 1, |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3220 | sizeof(ngx_http_proxy_rewrite_t)); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3221 | if (conf->redirects == NULL) { |
| 3222 | return NGX_CONF_ERROR; |
| 3223 | } |
| 3224 | |
| 3225 | pr = ngx_array_push(conf->redirects); |
| 3226 | if (pr == NULL) { |
| 3227 | return NGX_CONF_ERROR; |
| 3228 | } |
| 3229 | |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3230 | ngx_memzero(&pr->pattern.complex, |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3231 | sizeof(ngx_http_complex_value_t)); |
| 3232 | |
| 3233 | ngx_memzero(&pr->replacement, sizeof(ngx_http_complex_value_t)); |
| 3234 | |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3235 | pr->handler = ngx_http_proxy_rewrite_complex_handler; |
Igor Sysoev | afd7ec5 | 2006-05-29 17:28:12 +0000 | [diff] [blame] | 3236 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 3237 | if (conf->vars.uri.len) { |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3238 | pr->pattern.complex.value = conf->url; |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3239 | pr->replacement.value = conf->location; |
Igor Sysoev | afd7ec5 | 2006-05-29 17:28:12 +0000 | [diff] [blame] | 3240 | |
| 3241 | } else { |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3242 | pr->pattern.complex.value.len = conf->url.len |
| 3243 | + sizeof("/") - 1; |
Igor Sysoev | b249225 | 2011-02-17 11:54:35 +0000 | [diff] [blame] | 3244 | |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3245 | p = ngx_pnalloc(cf->pool, pr->pattern.complex.value.len); |
Igor Sysoev | b249225 | 2011-02-17 11:54:35 +0000 | [diff] [blame] | 3246 | if (p == NULL) { |
| 3247 | return NGX_CONF_ERROR; |
| 3248 | } |
| 3249 | |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3250 | pr->pattern.complex.value.data = p; |
Igor Sysoev | b249225 | 2011-02-17 11:54:35 +0000 | [diff] [blame] | 3251 | |
| 3252 | p = ngx_cpymem(p, conf->url.data, conf->url.len); |
| 3253 | *p = '/'; |
| 3254 | |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3255 | ngx_str_set(&pr->replacement.value, "/"); |
Igor Sysoev | afd7ec5 | 2006-05-29 17:28:12 +0000 | [diff] [blame] | 3256 | } |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3257 | } |
| 3258 | } |
| 3259 | |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 3260 | ngx_conf_merge_ptr_value(conf->cookie_domains, prev->cookie_domains, NULL); |
| 3261 | |
Valentin Bartenev | a113cb3 | 2012-02-13 11:08:05 +0000 | [diff] [blame] | 3262 | ngx_conf_merge_ptr_value(conf->cookie_paths, prev->cookie_paths, NULL); |
| 3263 | |
Maxim Dounin | 2fe0a7a | 2011-09-15 19:23:20 +0000 | [diff] [blame] | 3264 | ngx_conf_merge_uint_value(conf->http_version, prev->http_version, |
| 3265 | NGX_HTTP_VERSION_10); |
| 3266 | |
Igor Sysoev | 8a19bff | 2007-04-22 20:21:59 +0000 | [diff] [blame] | 3267 | ngx_conf_merge_uint_value(conf->headers_hash_max_size, |
| 3268 | prev->headers_hash_max_size, 512); |
| 3269 | |
| 3270 | ngx_conf_merge_uint_value(conf->headers_hash_bucket_size, |
| 3271 | prev->headers_hash_bucket_size, 64); |
| 3272 | |
| 3273 | conf->headers_hash_bucket_size = ngx_align(conf->headers_hash_bucket_size, |
| 3274 | ngx_cacheline_size); |
| 3275 | |
Igor Sysoev | cb54061 | 2007-12-09 18:03:20 +0000 | [diff] [blame] | 3276 | hash.max_size = conf->headers_hash_max_size; |
| 3277 | hash.bucket_size = conf->headers_hash_bucket_size; |
| 3278 | hash.name = "proxy_headers_hash"; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 3279 | |
Igor Sysoev | cb54061 | 2007-12-09 18:03:20 +0000 | [diff] [blame] | 3280 | if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream, |
Igor Sysoev | 0cb0c67 | 2010-07-02 10:05:40 +0000 | [diff] [blame] | 3281 | &prev->upstream, ngx_http_proxy_hide_headers, &hash) |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 3282 | != NGX_OK) |
| 3283 | { |
| 3284 | return NGX_CONF_ERROR; |
| 3285 | } |
| 3286 | |
Maxim Dounin | dbf4176 | 2014-12-09 18:22:31 +0300 | [diff] [blame] | 3287 | clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); |
| 3288 | |
| 3289 | if (clcf->noname |
| 3290 | && conf->upstream.upstream == NULL && conf->proxy_lengths == NULL) |
| 3291 | { |
Igor Sysoev | 3d2fd18 | 2006-12-04 16:46:13 +0000 | [diff] [blame] | 3292 | conf->upstream.upstream = prev->upstream.upstream; |
Maxim Dounin | f307529 | 2014-12-09 18:22:39 +0300 | [diff] [blame] | 3293 | conf->location = prev->location; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 3294 | conf->vars = prev->vars; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3295 | |
Igor Sysoev | 81cd5e4 | 2010-08-03 12:59:14 +0000 | [diff] [blame] | 3296 | conf->proxy_lengths = prev->proxy_lengths; |
| 3297 | conf->proxy_values = prev->proxy_values; |
Maxim Dounin | 18f34cf | 2014-12-09 18:21:55 +0300 | [diff] [blame] | 3298 | |
| 3299 | #if (NGX_HTTP_SSL) |
| 3300 | conf->upstream.ssl = prev->upstream.ssl; |
| 3301 | #endif |
Igor Sysoev | 81cd5e4 | 2010-08-03 12:59:14 +0000 | [diff] [blame] | 3302 | } |
| 3303 | |
Maxim Dounin | dbf4176 | 2014-12-09 18:22:31 +0300 | [diff] [blame] | 3304 | if (clcf->lmt_excpt && clcf->handler == NULL |
| 3305 | && (conf->upstream.upstream || conf->proxy_lengths)) |
| 3306 | { |
| 3307 | clcf->handler = ngx_http_proxy_handler; |
Igor Sysoev | 90f9552 | 2010-08-03 09:24:25 +0000 | [diff] [blame] | 3308 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 3309 | |
| 3310 | if (conf->body_source.data == NULL) { |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3311 | conf->body_flushes = prev->body_flushes; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 3312 | conf->body_source = prev->body_source; |
Roman Arutyunyan | 1b79cb2 | 2014-11-19 17:33:24 +0300 | [diff] [blame] | 3313 | conf->body_lengths = prev->body_lengths; |
| 3314 | conf->body_values = prev->body_values; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 3315 | } |
| 3316 | |
Roman Arutyunyan | 1b79cb2 | 2014-11-19 17:33:24 +0300 | [diff] [blame] | 3317 | if (conf->body_source.data && conf->body_lengths == NULL) { |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 3318 | |
| 3319 | ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
| 3320 | |
| 3321 | sc.cf = cf; |
| 3322 | sc.source = &conf->body_source; |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3323 | sc.flushes = &conf->body_flushes; |
Roman Arutyunyan | 1b79cb2 | 2014-11-19 17:33:24 +0300 | [diff] [blame] | 3324 | sc.lengths = &conf->body_lengths; |
| 3325 | sc.values = &conf->body_values; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 3326 | sc.complete_lengths = 1; |
| 3327 | sc.complete_values = 1; |
| 3328 | |
| 3329 | if (ngx_http_script_compile(&sc) != NGX_OK) { |
| 3330 | return NGX_CONF_ERROR; |
| 3331 | } |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 3332 | } |
| 3333 | |
Roman Arutyunyan | 62dfdf1 | 2014-11-19 17:33:21 +0300 | [diff] [blame] | 3334 | if (conf->headers_source == NULL) { |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3335 | conf->headers = prev->headers; |
Roman Arutyunyan | 8898c97 | 2014-11-19 17:33:23 +0300 | [diff] [blame] | 3336 | #if (NGX_HTTP_CACHE) |
| 3337 | conf->headers_cache = prev->headers_cache; |
| 3338 | #endif |
Roman Arutyunyan | 62dfdf1 | 2014-11-19 17:33:21 +0300 | [diff] [blame] | 3339 | conf->headers_source = prev->headers_source; |
| 3340 | } |
| 3341 | |
Roman Arutyunyan | 8898c97 | 2014-11-19 17:33:23 +0300 | [diff] [blame] | 3342 | rc = ngx_http_proxy_init_headers(cf, conf, &conf->headers, |
| 3343 | ngx_http_proxy_headers); |
| 3344 | if (rc != NGX_OK) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3345 | return NGX_CONF_ERROR; |
| 3346 | } |
| 3347 | |
Roman Arutyunyan | 8898c97 | 2014-11-19 17:33:23 +0300 | [diff] [blame] | 3348 | #if (NGX_HTTP_CACHE) |
| 3349 | |
| 3350 | if (conf->upstream.cache) { |
| 3351 | rc = ngx_http_proxy_init_headers(cf, conf, &conf->headers_cache, |
| 3352 | ngx_http_proxy_cache_headers); |
| 3353 | if (rc != NGX_OK) { |
| 3354 | return NGX_CONF_ERROR; |
| 3355 | } |
| 3356 | } |
| 3357 | |
| 3358 | #endif |
| 3359 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3360 | return NGX_CONF_OK; |
| 3361 | } |
| 3362 | |
| 3363 | |
| 3364 | static ngx_int_t |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3365 | ngx_http_proxy_init_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf, |
Roman Arutyunyan | 8898c97 | 2014-11-19 17:33:23 +0300 | [diff] [blame] | 3366 | ngx_http_proxy_headers_t *headers, ngx_keyval_t *default_headers) |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3367 | { |
| 3368 | u_char *p; |
| 3369 | size_t size; |
| 3370 | uintptr_t *code; |
| 3371 | ngx_uint_t i; |
Maxim Dounin | b5984de | 2011-11-14 13:18:15 +0000 | [diff] [blame] | 3372 | ngx_array_t headers_names, headers_merged; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3373 | ngx_keyval_t *src, *s, *h; |
| 3374 | ngx_hash_key_t *hk; |
| 3375 | ngx_hash_init_t hash; |
| 3376 | ngx_http_script_compile_t sc; |
| 3377 | ngx_http_script_copy_code_t *copy; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 3378 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3379 | if (headers->hash.buckets) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3380 | return NGX_OK; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3381 | } |
| 3382 | |
Igor Sysoev | 17483d5 | 2010-06-03 14:50:59 +0000 | [diff] [blame] | 3383 | if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) |
| 3384 | != NGX_OK) |
| 3385 | { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3386 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3387 | } |
| 3388 | |
Maxim Dounin | b5984de | 2011-11-14 13:18:15 +0000 | [diff] [blame] | 3389 | if (ngx_array_init(&headers_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t)) |
| 3390 | != NGX_OK) |
| 3391 | { |
| 3392 | return NGX_ERROR; |
| 3393 | } |
| 3394 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3395 | if (conf->headers_source == NULL) { |
| 3396 | conf->headers_source = ngx_array_create(cf->pool, 4, |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 3397 | sizeof(ngx_keyval_t)); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3398 | if (conf->headers_source == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3399 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3400 | } |
| 3401 | } |
| 3402 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3403 | headers->lengths = ngx_array_create(cf->pool, 64, 1); |
| 3404 | if (headers->lengths == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3405 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3406 | } |
| 3407 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3408 | headers->values = ngx_array_create(cf->pool, 512, 1); |
| 3409 | if (headers->values == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3410 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3411 | } |
| 3412 | |
Maxim Dounin | b5984de | 2011-11-14 13:18:15 +0000 | [diff] [blame] | 3413 | src = conf->headers_source->elts; |
| 3414 | for (i = 0; i < conf->headers_source->nelts; i++) { |
| 3415 | |
| 3416 | s = ngx_array_push(&headers_merged); |
| 3417 | if (s == NULL) { |
| 3418 | return NGX_ERROR; |
| 3419 | } |
| 3420 | |
| 3421 | *s = src[i]; |
| 3422 | } |
| 3423 | |
Roman Arutyunyan | 8898c97 | 2014-11-19 17:33:23 +0300 | [diff] [blame] | 3424 | h = default_headers; |
| 3425 | |
Igor Sysoev | 081662a | 2009-04-15 11:21:12 +0000 | [diff] [blame] | 3426 | while (h->key.len) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3427 | |
Maxim Dounin | b5984de | 2011-11-14 13:18:15 +0000 | [diff] [blame] | 3428 | src = headers_merged.elts; |
| 3429 | for (i = 0; i < headers_merged.nelts; i++) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3430 | if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) { |
| 3431 | goto next; |
| 3432 | } |
| 3433 | } |
| 3434 | |
Maxim Dounin | b5984de | 2011-11-14 13:18:15 +0000 | [diff] [blame] | 3435 | s = ngx_array_push(&headers_merged); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3436 | if (s == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3437 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3438 | } |
| 3439 | |
| 3440 | *s = *h; |
| 3441 | |
| 3442 | next: |
| 3443 | |
Igor Sysoev | 081662a | 2009-04-15 11:21:12 +0000 | [diff] [blame] | 3444 | h++; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3445 | } |
| 3446 | |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 3447 | |
Maxim Dounin | b5984de | 2011-11-14 13:18:15 +0000 | [diff] [blame] | 3448 | src = headers_merged.elts; |
| 3449 | for (i = 0; i < headers_merged.nelts; i++) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3450 | |
Igor Sysoev | 17483d5 | 2010-06-03 14:50:59 +0000 | [diff] [blame] | 3451 | hk = ngx_array_push(&headers_names); |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 3452 | if (hk == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3453 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3454 | } |
| 3455 | |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 3456 | hk->key = src[i].key; |
| 3457 | hk->key_hash = ngx_hash_key_lc(src[i].key.data, src[i].key.len); |
| 3458 | hk->value = (void *) 1; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3459 | |
Igor Sysoev | 403d244 | 2005-05-26 18:12:40 +0000 | [diff] [blame] | 3460 | if (src[i].value.len == 0) { |
| 3461 | continue; |
| 3462 | } |
| 3463 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3464 | if (ngx_http_script_variables_count(&src[i].value) == 0) { |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3465 | copy = ngx_array_push_n(headers->lengths, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3466 | sizeof(ngx_http_script_copy_code_t)); |
| 3467 | if (copy == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3468 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3469 | } |
| 3470 | |
| 3471 | copy->code = (ngx_http_script_code_pt) |
| 3472 | ngx_http_script_copy_len_code; |
| 3473 | copy->len = src[i].key.len + sizeof(": ") - 1 |
| 3474 | + src[i].value.len + sizeof(CRLF) - 1; |
| 3475 | |
| 3476 | |
| 3477 | size = (sizeof(ngx_http_script_copy_code_t) |
| 3478 | + src[i].key.len + sizeof(": ") - 1 |
| 3479 | + src[i].value.len + sizeof(CRLF) - 1 |
| 3480 | + sizeof(uintptr_t) - 1) |
| 3481 | & ~(sizeof(uintptr_t) - 1); |
| 3482 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3483 | copy = ngx_array_push_n(headers->values, size); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3484 | if (copy == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3485 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3486 | } |
| 3487 | |
| 3488 | copy->code = ngx_http_script_copy_code; |
| 3489 | copy->len = src[i].key.len + sizeof(": ") - 1 |
| 3490 | + src[i].value.len + sizeof(CRLF) - 1; |
| 3491 | |
| 3492 | p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); |
| 3493 | |
| 3494 | p = ngx_cpymem(p, src[i].key.data, src[i].key.len); |
| 3495 | *p++ = ':'; *p++ = ' '; |
| 3496 | p = ngx_cpymem(p, src[i].value.data, src[i].value.len); |
| 3497 | *p++ = CR; *p = LF; |
| 3498 | |
| 3499 | } else { |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3500 | copy = ngx_array_push_n(headers->lengths, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3501 | sizeof(ngx_http_script_copy_code_t)); |
| 3502 | if (copy == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3503 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3504 | } |
| 3505 | |
| 3506 | copy->code = (ngx_http_script_code_pt) |
| 3507 | ngx_http_script_copy_len_code; |
| 3508 | copy->len = src[i].key.len + sizeof(": ") - 1; |
| 3509 | |
| 3510 | |
| 3511 | size = (sizeof(ngx_http_script_copy_code_t) |
| 3512 | + src[i].key.len + sizeof(": ") - 1 + sizeof(uintptr_t) - 1) |
| 3513 | & ~(sizeof(uintptr_t) - 1); |
| 3514 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3515 | copy = ngx_array_push_n(headers->values, size); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3516 | if (copy == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3517 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3518 | } |
| 3519 | |
| 3520 | copy->code = ngx_http_script_copy_code; |
| 3521 | copy->len = src[i].key.len + sizeof(": ") - 1; |
| 3522 | |
| 3523 | p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); |
| 3524 | p = ngx_cpymem(p, src[i].key.data, src[i].key.len); |
| 3525 | *p++ = ':'; *p = ' '; |
| 3526 | |
| 3527 | |
| 3528 | ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
| 3529 | |
| 3530 | sc.cf = cf; |
| 3531 | sc.source = &src[i].value; |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3532 | sc.flushes = &headers->flushes; |
| 3533 | sc.lengths = &headers->lengths; |
| 3534 | sc.values = &headers->values; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3535 | |
| 3536 | if (ngx_http_script_compile(&sc) != NGX_OK) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3537 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3538 | } |
| 3539 | |
| 3540 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3541 | copy = ngx_array_push_n(headers->lengths, |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3542 | sizeof(ngx_http_script_copy_code_t)); |
| 3543 | if (copy == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3544 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3545 | } |
| 3546 | |
| 3547 | copy->code = (ngx_http_script_code_pt) |
| 3548 | ngx_http_script_copy_len_code; |
| 3549 | copy->len = sizeof(CRLF) - 1; |
| 3550 | |
| 3551 | |
| 3552 | size = (sizeof(ngx_http_script_copy_code_t) |
| 3553 | + sizeof(CRLF) - 1 + sizeof(uintptr_t) - 1) |
| 3554 | & ~(sizeof(uintptr_t) - 1); |
| 3555 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3556 | copy = ngx_array_push_n(headers->values, size); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3557 | if (copy == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3558 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3559 | } |
| 3560 | |
| 3561 | copy->code = ngx_http_script_copy_code; |
| 3562 | copy->len = sizeof(CRLF) - 1; |
| 3563 | |
| 3564 | p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t); |
| 3565 | *p++ = CR; *p = LF; |
| 3566 | } |
| 3567 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3568 | code = ngx_array_push_n(headers->lengths, sizeof(uintptr_t)); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3569 | if (code == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3570 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3571 | } |
| 3572 | |
| 3573 | *code = (uintptr_t) NULL; |
| 3574 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3575 | code = ngx_array_push_n(headers->values, sizeof(uintptr_t)); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3576 | if (code == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3577 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3578 | } |
| 3579 | |
| 3580 | *code = (uintptr_t) NULL; |
| 3581 | } |
| 3582 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3583 | code = ngx_array_push_n(headers->lengths, sizeof(uintptr_t)); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3584 | if (code == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3585 | return NGX_ERROR; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3586 | } |
| 3587 | |
| 3588 | *code = (uintptr_t) NULL; |
| 3589 | |
| 3590 | |
Roman Arutyunyan | bcf6b11 | 2014-11-19 17:33:22 +0300 | [diff] [blame] | 3591 | hash.hash = &headers->hash; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 3592 | hash.key = ngx_hash_key_lc; |
Igor Sysoev | 8a19bff | 2007-04-22 20:21:59 +0000 | [diff] [blame] | 3593 | hash.max_size = conf->headers_hash_max_size; |
| 3594 | hash.bucket_size = conf->headers_hash_bucket_size; |
| 3595 | hash.name = "proxy_headers_hash"; |
Igor Sysoev | 3338cfd | 2006-05-11 14:43:47 +0000 | [diff] [blame] | 3596 | hash.pool = cf->pool; |
| 3597 | hash.temp_pool = NULL; |
| 3598 | |
Igor Sysoev | 17483d5 | 2010-06-03 14:50:59 +0000 | [diff] [blame] | 3599 | return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3600 | } |
| 3601 | |
| 3602 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3603 | static char * |
| 3604 | ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
| 3605 | { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3606 | ngx_http_proxy_loc_conf_t *plcf = conf; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3607 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 3608 | size_t add; |
| 3609 | u_short port; |
| 3610 | ngx_str_t *value, *url; |
| 3611 | ngx_url_t u; |
| 3612 | ngx_uint_t n; |
| 3613 | ngx_http_core_loc_conf_t *clcf; |
| 3614 | ngx_http_script_compile_t sc; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3615 | |
Igor Sysoev | 73c3121 | 2008-12-10 14:44:48 +0000 | [diff] [blame] | 3616 | if (plcf->upstream.upstream || plcf->proxy_lengths) { |
Igor Sysoev | a257367 | 2005-10-05 14:46:21 +0000 | [diff] [blame] | 3617 | return "is duplicate"; |
| 3618 | } |
| 3619 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 3620 | clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); |
| 3621 | |
Igor Sysoev | 5639272 | 2009-07-20 11:44:38 +0000 | [diff] [blame] | 3622 | clcf->handler = ngx_http_proxy_handler; |
| 3623 | |
| 3624 | if (clcf->name.data[clcf->name.len - 1] == '/') { |
| 3625 | clcf->auto_redirect = 1; |
| 3626 | } |
| 3627 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3628 | value = cf->args->elts; |
| 3629 | |
| 3630 | url = &value[1]; |
| 3631 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 3632 | n = ngx_http_script_variables_count(url); |
| 3633 | |
| 3634 | if (n) { |
| 3635 | |
| 3636 | ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
| 3637 | |
| 3638 | sc.cf = cf; |
| 3639 | sc.source = url; |
| 3640 | sc.lengths = &plcf->proxy_lengths; |
| 3641 | sc.values = &plcf->proxy_values; |
| 3642 | sc.variables = n; |
| 3643 | sc.complete_lengths = 1; |
| 3644 | sc.complete_values = 1; |
Igor Sysoev | b4e5b4c | 2007-12-01 19:57:37 +0000 | [diff] [blame] | 3645 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 3646 | if (ngx_http_script_compile(&sc) != NGX_OK) { |
| 3647 | return NGX_CONF_ERROR; |
| 3648 | } |
| 3649 | |
| 3650 | #if (NGX_HTTP_SSL) |
Andrei Belov | 003b2cd | 2013-09-19 18:30:33 +0400 | [diff] [blame] | 3651 | plcf->ssl = 1; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 3652 | #endif |
| 3653 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 3654 | return NGX_CONF_OK; |
| 3655 | } |
| 3656 | |
Igor Sysoev | 722231f | 2007-02-14 18:51:19 +0000 | [diff] [blame] | 3657 | if (ngx_strncasecmp(url->data, (u_char *) "http://", 7) == 0) { |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 3658 | add = 7; |
Igor Sysoev | 43f279d | 2005-12-18 16:02:44 +0000 | [diff] [blame] | 3659 | port = 80; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 3660 | |
Igor Sysoev | 722231f | 2007-02-14 18:51:19 +0000 | [diff] [blame] | 3661 | } else if (ngx_strncasecmp(url->data, (u_char *) "https://", 8) == 0) { |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 3662 | |
| 3663 | #if (NGX_HTTP_SSL) |
Andrei Belov | 003b2cd | 2013-09-19 18:30:33 +0400 | [diff] [blame] | 3664 | plcf->ssl = 1; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 3665 | |
| 3666 | add = 8; |
Igor Sysoev | 43f279d | 2005-12-18 16:02:44 +0000 | [diff] [blame] | 3667 | port = 443; |
Igor Sysoev | 0e5dc5c | 2005-11-15 13:30:52 +0000 | [diff] [blame] | 3668 | #else |
| 3669 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 3670 | "https protocol requires SSL support"); |
| 3671 | return NGX_CONF_ERROR; |
| 3672 | #endif |
| 3673 | |
| 3674 | } else { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3675 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid URL prefix"); |
| 3676 | return NGX_CONF_ERROR; |
| 3677 | } |
| 3678 | |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 3679 | ngx_memzero(&u, sizeof(ngx_url_t)); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3680 | |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 3681 | u.url.len = url->len - add; |
| 3682 | u.url.data = url->data + add; |
Igor Sysoev | bf3aaac | 2006-12-12 16:46:16 +0000 | [diff] [blame] | 3683 | u.default_port = port; |
Igor Sysoev | 6f134cc | 2006-05-23 14:54:58 +0000 | [diff] [blame] | 3684 | u.uri_part = 1; |
Igor Sysoev | bf3aaac | 2006-12-12 16:46:16 +0000 | [diff] [blame] | 3685 | u.no_resolve = 1; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3686 | |
Igor Sysoev | 3d2fd18 | 2006-12-04 16:46:13 +0000 | [diff] [blame] | 3687 | plcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0); |
| 3688 | if (plcf->upstream.upstream == NULL) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3689 | return NGX_CONF_ERROR; |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3690 | } |
| 3691 | |
Igor Sysoev | 73c3121 | 2008-12-10 14:44:48 +0000 | [diff] [blame] | 3692 | plcf->vars.schema.len = add; |
| 3693 | plcf->vars.schema.data = url->data; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3694 | plcf->vars.key_start = plcf->vars.schema; |
| 3695 | |
| 3696 | ngx_http_proxy_set_vars(&u, &plcf->vars); |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3697 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 3698 | plcf->location = clcf->name; |
| 3699 | |
Igor Sysoev | 8889b65 | 2007-07-29 18:11:39 +0000 | [diff] [blame] | 3700 | if (clcf->named |
Igor Sysoev | a257367 | 2005-10-05 14:46:21 +0000 | [diff] [blame] | 3701 | #if (NGX_PCRE) |
Igor Sysoev | 8889b65 | 2007-07-29 18:11:39 +0000 | [diff] [blame] | 3702 | || clcf->regex |
| 3703 | #endif |
| 3704 | || clcf->noname) |
| 3705 | { |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 3706 | if (plcf->vars.uri.len) { |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 3707 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
Ruslan Ermilov | 43d2b1c | 2012-04-12 19:35:41 +0000 | [diff] [blame] | 3708 | "\"proxy_pass\" cannot have URI part in " |
Igor Sysoev | e927b1e | 2006-11-14 12:43:14 +0000 | [diff] [blame] | 3709 | "location given by regular expression, " |
Igor Sysoev | 8889b65 | 2007-07-29 18:11:39 +0000 | [diff] [blame] | 3710 | "or inside named location, " |
Ruslan Ermilov | 43d2b1c | 2012-04-12 19:35:41 +0000 | [diff] [blame] | 3711 | "or inside \"if\" statement, " |
| 3712 | "or inside \"limit_except\" block"); |
Igor Sysoev | 09c684b | 2005-11-09 17:25:55 +0000 | [diff] [blame] | 3713 | return NGX_CONF_ERROR; |
| 3714 | } |
| 3715 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 3716 | plcf->location.len = 0; |
Igor Sysoev | a257367 | 2005-10-05 14:46:21 +0000 | [diff] [blame] | 3717 | } |
| 3718 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 3719 | plcf->url = *url; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3720 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3721 | return NGX_CONF_OK; |
| 3722 | } |
| 3723 | |
| 3724 | |
| 3725 | static char * |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3726 | 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] | 3727 | { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3728 | ngx_http_proxy_loc_conf_t *plcf = conf; |
| 3729 | |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3730 | u_char *p; |
| 3731 | ngx_str_t *value; |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3732 | ngx_http_proxy_rewrite_t *pr; |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3733 | ngx_http_compile_complex_value_t ccv; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3734 | |
| 3735 | if (plcf->redirect == 0) { |
| 3736 | return NGX_CONF_OK; |
| 3737 | } |
| 3738 | |
Valentin Bartenev | 3feafa7 | 2012-01-30 11:22:56 +0000 | [diff] [blame] | 3739 | plcf->redirect = 1; |
| 3740 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3741 | value = cf->args->elts; |
| 3742 | |
Igor Sysoev | 06d4aa1 | 2009-04-30 12:43:38 +0000 | [diff] [blame] | 3743 | if (cf->args->nelts == 2) { |
| 3744 | if (ngx_strcmp(value[1].data, "off") == 0) { |
| 3745 | plcf->redirect = 0; |
| 3746 | plcf->redirects = NULL; |
| 3747 | return NGX_CONF_OK; |
| 3748 | } |
| 3749 | |
| 3750 | if (ngx_strcmp(value[1].data, "false") == 0) { |
| 3751 | ngx_conf_log_error(NGX_LOG_ERR, cf, 0, |
| 3752 | "invalid parameter \"false\", use \"off\" instead"); |
| 3753 | plcf->redirect = 0; |
| 3754 | plcf->redirects = NULL; |
| 3755 | return NGX_CONF_OK; |
| 3756 | } |
| 3757 | |
| 3758 | if (ngx_strcmp(value[1].data, "default") != 0) { |
| 3759 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 3760 | "invalid parameter \"%V\"", &value[1]); |
| 3761 | return NGX_CONF_ERROR; |
| 3762 | } |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3763 | } |
| 3764 | |
| 3765 | if (plcf->redirects == NULL) { |
| 3766 | plcf->redirects = ngx_array_create(cf->pool, 1, |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3767 | sizeof(ngx_http_proxy_rewrite_t)); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3768 | if (plcf->redirects == NULL) { |
| 3769 | return NGX_CONF_ERROR; |
| 3770 | } |
| 3771 | } |
| 3772 | |
| 3773 | pr = ngx_array_push(plcf->redirects); |
| 3774 | if (pr == NULL) { |
| 3775 | return NGX_CONF_ERROR; |
| 3776 | } |
| 3777 | |
Igor Sysoev | 06d4aa1 | 2009-04-30 12:43:38 +0000 | [diff] [blame] | 3778 | if (ngx_strcmp(value[1].data, "default") == 0) { |
Igor Sysoev | 7fa1c07 | 2010-03-10 14:41:49 +0000 | [diff] [blame] | 3779 | if (plcf->proxy_lengths) { |
| 3780 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
Ruslan Ermilov | 43d2b1c | 2012-04-12 19:35:41 +0000 | [diff] [blame] | 3781 | "\"proxy_redirect default\" cannot be used " |
Igor Sysoev | 7fa1c07 | 2010-03-10 14:41:49 +0000 | [diff] [blame] | 3782 | "with \"proxy_pass\" directive with variables"); |
| 3783 | return NGX_CONF_ERROR; |
| 3784 | } |
| 3785 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 3786 | if (plcf->url.data == NULL) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3787 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
Ruslan Ermilov | 43d2b1c | 2012-04-12 19:35:41 +0000 | [diff] [blame] | 3788 | "\"proxy_redirect default\" should be placed " |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3789 | "after the \"proxy_pass\" directive"); |
| 3790 | return NGX_CONF_ERROR; |
| 3791 | } |
| 3792 | |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3793 | pr->handler = ngx_http_proxy_rewrite_complex_handler; |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3794 | |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3795 | ngx_memzero(&pr->pattern.complex, sizeof(ngx_http_complex_value_t)); |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3796 | |
| 3797 | ngx_memzero(&pr->replacement, sizeof(ngx_http_complex_value_t)); |
Igor Sysoev | afd7ec5 | 2006-05-29 17:28:12 +0000 | [diff] [blame] | 3798 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 3799 | if (plcf->vars.uri.len) { |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3800 | pr->pattern.complex.value = plcf->url; |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3801 | pr->replacement.value = plcf->location; |
Igor Sysoev | afd7ec5 | 2006-05-29 17:28:12 +0000 | [diff] [blame] | 3802 | |
| 3803 | } else { |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3804 | pr->pattern.complex.value.len = plcf->url.len + sizeof("/") - 1; |
Igor Sysoev | b249225 | 2011-02-17 11:54:35 +0000 | [diff] [blame] | 3805 | |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3806 | p = ngx_pnalloc(cf->pool, pr->pattern.complex.value.len); |
Igor Sysoev | b249225 | 2011-02-17 11:54:35 +0000 | [diff] [blame] | 3807 | if (p == NULL) { |
| 3808 | return NGX_CONF_ERROR; |
| 3809 | } |
| 3810 | |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3811 | pr->pattern.complex.value.data = p; |
Igor Sysoev | b249225 | 2011-02-17 11:54:35 +0000 | [diff] [blame] | 3812 | |
| 3813 | p = ngx_cpymem(p, plcf->url.data, plcf->url.len); |
| 3814 | *p = '/'; |
| 3815 | |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3816 | ngx_str_set(&pr->replacement.value, "/"); |
Igor Sysoev | afd7ec5 | 2006-05-29 17:28:12 +0000 | [diff] [blame] | 3817 | } |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3818 | |
| 3819 | return NGX_CONF_OK; |
| 3820 | } |
| 3821 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3822 | |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3823 | if (value[1].data[0] == '~') { |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3824 | value[1].len--; |
| 3825 | value[1].data++; |
| 3826 | |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3827 | if (value[1].data[0] == '*') { |
| 3828 | value[1].len--; |
| 3829 | value[1].data++; |
Valentin Bartenev | 85551e5 | 2012-02-13 11:00:08 +0000 | [diff] [blame] | 3830 | |
| 3831 | if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 1) != NGX_OK) { |
| 3832 | return NGX_CONF_ERROR; |
| 3833 | } |
| 3834 | |
| 3835 | } else { |
| 3836 | if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 0) != NGX_OK) { |
| 3837 | return NGX_CONF_ERROR; |
| 3838 | } |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3839 | } |
| 3840 | |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3841 | } else { |
| 3842 | |
| 3843 | ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
| 3844 | |
| 3845 | ccv.cf = cf; |
| 3846 | ccv.value = &value[1]; |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3847 | ccv.complex_value = &pr->pattern.complex; |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3848 | |
| 3849 | if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
| 3850 | return NGX_CONF_ERROR; |
| 3851 | } |
| 3852 | |
Valentin Bartenev | 582dac1 | 2012-02-13 10:42:44 +0000 | [diff] [blame] | 3853 | pr->handler = ngx_http_proxy_rewrite_complex_handler; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3854 | } |
| 3855 | |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3856 | |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3857 | ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3858 | |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3859 | ccv.cf = cf; |
| 3860 | ccv.value = &value[2]; |
| 3861 | ccv.complex_value = &pr->replacement; |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3862 | |
Valentin Bartenev | 0be9554 | 2011-12-12 09:02:29 +0000 | [diff] [blame] | 3863 | if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
Igor Sysoev | 899b44e | 2005-05-12 14:58:06 +0000 | [diff] [blame] | 3864 | return NGX_CONF_ERROR; |
| 3865 | } |
| 3866 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 3867 | return NGX_CONF_OK; |
| 3868 | } |
| 3869 | |
| 3870 | |
Valentin Bartenev | e9df2d6 | 2012-02-13 11:04:45 +0000 | [diff] [blame] | 3871 | static char * |
| 3872 | ngx_http_proxy_cookie_domain(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
| 3873 | { |
| 3874 | ngx_http_proxy_loc_conf_t *plcf = conf; |
| 3875 | |
| 3876 | ngx_str_t *value; |
| 3877 | ngx_http_proxy_rewrite_t *pr; |
| 3878 | ngx_http_compile_complex_value_t ccv; |
| 3879 | |
| 3880 | if (plcf->cookie_domains == NULL) { |
| 3881 | return NGX_CONF_OK; |
| 3882 | } |
| 3883 | |
| 3884 | value = cf->args->elts; |
| 3885 | |
| 3886 | if (cf->args->nelts == 2) { |
| 3887 | |
| 3888 | if (ngx_strcmp(value[1].data, "off") == 0) { |
| 3889 | plcf->cookie_domains = NULL; |
| 3890 | return NGX_CONF_OK; |
| 3891 | } |
| 3892 | |
| 3893 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 3894 | "invalid parameter \"%V\"", &value[1]); |
| 3895 | return NGX_CONF_ERROR; |
| 3896 | } |
| 3897 | |
| 3898 | if (plcf->cookie_domains == NGX_CONF_UNSET_PTR) { |
| 3899 | plcf->cookie_domains = ngx_array_create(cf->pool, 1, |
| 3900 | sizeof(ngx_http_proxy_rewrite_t)); |
| 3901 | if (plcf->cookie_domains == NULL) { |
| 3902 | return NGX_CONF_ERROR; |
| 3903 | } |
| 3904 | } |
| 3905 | |
| 3906 | pr = ngx_array_push(plcf->cookie_domains); |
| 3907 | if (pr == NULL) { |
| 3908 | return NGX_CONF_ERROR; |
| 3909 | } |
| 3910 | |
| 3911 | if (value[1].data[0] == '~') { |
| 3912 | value[1].len--; |
| 3913 | value[1].data++; |
| 3914 | |
| 3915 | if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 1) != NGX_OK) { |
| 3916 | return NGX_CONF_ERROR; |
| 3917 | } |
| 3918 | |
| 3919 | } else { |
| 3920 | |
| 3921 | if (value[1].data[0] == '.') { |
| 3922 | value[1].len--; |
| 3923 | value[1].data++; |
| 3924 | } |
| 3925 | |
| 3926 | ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
| 3927 | |
| 3928 | ccv.cf = cf; |
| 3929 | ccv.value = &value[1]; |
| 3930 | ccv.complex_value = &pr->pattern.complex; |
| 3931 | |
| 3932 | if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
| 3933 | return NGX_CONF_ERROR; |
| 3934 | } |
| 3935 | |
| 3936 | pr->handler = ngx_http_proxy_rewrite_domain_handler; |
| 3937 | |
| 3938 | if (value[2].data[0] == '.') { |
| 3939 | value[2].len--; |
| 3940 | value[2].data++; |
| 3941 | } |
| 3942 | } |
| 3943 | |
| 3944 | ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
| 3945 | |
| 3946 | ccv.cf = cf; |
| 3947 | ccv.value = &value[2]; |
| 3948 | ccv.complex_value = &pr->replacement; |
| 3949 | |
| 3950 | if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
| 3951 | return NGX_CONF_ERROR; |
| 3952 | } |
| 3953 | |
| 3954 | return NGX_CONF_OK; |
| 3955 | } |
| 3956 | |
| 3957 | |
Valentin Bartenev | a113cb3 | 2012-02-13 11:08:05 +0000 | [diff] [blame] | 3958 | static char * |
| 3959 | ngx_http_proxy_cookie_path(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
| 3960 | { |
| 3961 | ngx_http_proxy_loc_conf_t *plcf = conf; |
| 3962 | |
| 3963 | ngx_str_t *value; |
| 3964 | ngx_http_proxy_rewrite_t *pr; |
| 3965 | ngx_http_compile_complex_value_t ccv; |
| 3966 | |
| 3967 | if (plcf->cookie_paths == NULL) { |
| 3968 | return NGX_CONF_OK; |
| 3969 | } |
| 3970 | |
| 3971 | value = cf->args->elts; |
| 3972 | |
| 3973 | if (cf->args->nelts == 2) { |
| 3974 | |
| 3975 | if (ngx_strcmp(value[1].data, "off") == 0) { |
| 3976 | plcf->cookie_paths = NULL; |
| 3977 | return NGX_CONF_OK; |
| 3978 | } |
| 3979 | |
| 3980 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 3981 | "invalid parameter \"%V\"", &value[1]); |
| 3982 | return NGX_CONF_ERROR; |
| 3983 | } |
| 3984 | |
| 3985 | if (plcf->cookie_paths == NGX_CONF_UNSET_PTR) { |
| 3986 | plcf->cookie_paths = ngx_array_create(cf->pool, 1, |
| 3987 | sizeof(ngx_http_proxy_rewrite_t)); |
| 3988 | if (plcf->cookie_paths == NULL) { |
| 3989 | return NGX_CONF_ERROR; |
| 3990 | } |
| 3991 | } |
| 3992 | |
| 3993 | pr = ngx_array_push(plcf->cookie_paths); |
| 3994 | if (pr == NULL) { |
| 3995 | return NGX_CONF_ERROR; |
| 3996 | } |
| 3997 | |
| 3998 | if (value[1].data[0] == '~') { |
| 3999 | value[1].len--; |
| 4000 | value[1].data++; |
| 4001 | |
| 4002 | if (value[1].data[0] == '*') { |
| 4003 | value[1].len--; |
| 4004 | value[1].data++; |
| 4005 | |
| 4006 | if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 1) != NGX_OK) { |
| 4007 | return NGX_CONF_ERROR; |
| 4008 | } |
| 4009 | |
| 4010 | } else { |
| 4011 | if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 0) != NGX_OK) { |
| 4012 | return NGX_CONF_ERROR; |
| 4013 | } |
| 4014 | } |
| 4015 | |
| 4016 | } else { |
| 4017 | |
| 4018 | ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
| 4019 | |
| 4020 | ccv.cf = cf; |
| 4021 | ccv.value = &value[1]; |
| 4022 | ccv.complex_value = &pr->pattern.complex; |
| 4023 | |
| 4024 | if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
| 4025 | return NGX_CONF_ERROR; |
| 4026 | } |
| 4027 | |
| 4028 | pr->handler = ngx_http_proxy_rewrite_complex_handler; |
| 4029 | } |
| 4030 | |
| 4031 | ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
| 4032 | |
| 4033 | ccv.cf = cf; |
| 4034 | ccv.value = &value[2]; |
| 4035 | ccv.complex_value = &pr->replacement; |
| 4036 | |
| 4037 | if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
| 4038 | return NGX_CONF_ERROR; |
| 4039 | } |
| 4040 | |
| 4041 | return NGX_CONF_OK; |
| 4042 | } |
| 4043 | |
| 4044 | |
Valentin Bartenev | 85551e5 | 2012-02-13 11:00:08 +0000 | [diff] [blame] | 4045 | static ngx_int_t |
| 4046 | ngx_http_proxy_rewrite_regex(ngx_conf_t *cf, ngx_http_proxy_rewrite_t *pr, |
| 4047 | ngx_str_t *regex, ngx_uint_t caseless) |
| 4048 | { |
| 4049 | #if (NGX_PCRE) |
| 4050 | u_char errstr[NGX_MAX_CONF_ERRSTR]; |
| 4051 | ngx_regex_compile_t rc; |
| 4052 | |
| 4053 | ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); |
| 4054 | |
| 4055 | rc.pattern = *regex; |
| 4056 | rc.err.len = NGX_MAX_CONF_ERRSTR; |
| 4057 | rc.err.data = errstr; |
| 4058 | |
| 4059 | if (caseless) { |
| 4060 | rc.options = NGX_REGEX_CASELESS; |
| 4061 | } |
| 4062 | |
| 4063 | pr->pattern.regex = ngx_http_regex_compile(cf, &rc); |
| 4064 | if (pr->pattern.regex == NULL) { |
| 4065 | return NGX_ERROR; |
| 4066 | } |
| 4067 | |
| 4068 | pr->handler = ngx_http_proxy_rewrite_regex_handler; |
| 4069 | |
| 4070 | return NGX_OK; |
| 4071 | |
| 4072 | #else |
| 4073 | |
| 4074 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 4075 | "using regex \"%V\" requires PCRE library", regex); |
| 4076 | return NGX_ERROR; |
| 4077 | |
| 4078 | #endif |
| 4079 | } |
| 4080 | |
| 4081 | |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 4082 | static char * |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 4083 | ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
| 4084 | { |
| 4085 | ngx_http_proxy_loc_conf_t *plcf = conf; |
| 4086 | |
| 4087 | ngx_str_t *value; |
| 4088 | ngx_http_script_compile_t sc; |
| 4089 | |
Valentin Bartenev | a4b7b10 | 2014-12-22 12:58:56 +0300 | [diff] [blame] | 4090 | if (plcf->upstream.store != NGX_CONF_UNSET) { |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 4091 | return "is duplicate"; |
| 4092 | } |
| 4093 | |
| 4094 | value = cf->args->elts; |
| 4095 | |
Igor Sysoev | 98f692a | 2009-05-28 13:41:44 +0000 | [diff] [blame] | 4096 | if (ngx_strcmp(value[1].data, "off") == 0) { |
| 4097 | plcf->upstream.store = 0; |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 4098 | return NGX_CONF_OK; |
| 4099 | } |
| 4100 | |
Igor Sysoev | 98f692a | 2009-05-28 13:41:44 +0000 | [diff] [blame] | 4101 | #if (NGX_HTTP_CACHE) |
Valentin Bartenev | 5de6662 | 2014-12-22 12:59:02 +0300 | [diff] [blame] | 4102 | if (plcf->upstream.cache > 0) { |
Igor Sysoev | 98f692a | 2009-05-28 13:41:44 +0000 | [diff] [blame] | 4103 | return "is incompatible with \"proxy_cache\""; |
| 4104 | } |
Igor Sysoev | 98f692a | 2009-05-28 13:41:44 +0000 | [diff] [blame] | 4105 | #endif |
| 4106 | |
Valentin Bartenev | a4b7b10 | 2014-12-22 12:58:56 +0300 | [diff] [blame] | 4107 | plcf->upstream.store = 1; |
| 4108 | |
Igor Sysoev | 98f692a | 2009-05-28 13:41:44 +0000 | [diff] [blame] | 4109 | if (ngx_strcmp(value[1].data, "on") == 0) { |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 4110 | return NGX_CONF_OK; |
| 4111 | } |
| 4112 | |
| 4113 | /* include the terminating '\0' into script */ |
| 4114 | value[1].len++; |
| 4115 | |
| 4116 | ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
| 4117 | |
| 4118 | sc.cf = cf; |
| 4119 | sc.source = &value[1]; |
| 4120 | sc.lengths = &plcf->upstream.store_lengths; |
| 4121 | sc.values = &plcf->upstream.store_values; |
Igor Sysoev | bfb23bf | 2007-10-09 20:11:03 +0000 | [diff] [blame] | 4122 | sc.variables = ngx_http_script_variables_count(&value[1]); |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 4123 | sc.complete_lengths = 1; |
| 4124 | sc.complete_values = 1; |
| 4125 | |
| 4126 | if (ngx_http_script_compile(&sc) != NGX_OK) { |
| 4127 | return NGX_CONF_ERROR; |
| 4128 | } |
| 4129 | |
| 4130 | return NGX_CONF_OK; |
| 4131 | } |
| 4132 | |
| 4133 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 4134 | #if (NGX_HTTP_CACHE) |
| 4135 | |
| 4136 | static char * |
| 4137 | ngx_http_proxy_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
| 4138 | { |
| 4139 | ngx_http_proxy_loc_conf_t *plcf = conf; |
| 4140 | |
Valentin Bartenev | 9a0eb4f | 2014-12-22 12:59:09 +0300 | [diff] [blame] | 4141 | ngx_str_t *value; |
| 4142 | ngx_http_complex_value_t cv; |
| 4143 | ngx_http_compile_complex_value_t ccv; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 4144 | |
| 4145 | value = cf->args->elts; |
| 4146 | |
Valentin Bartenev | 5de6662 | 2014-12-22 12:59:02 +0300 | [diff] [blame] | 4147 | if (plcf->upstream.cache != NGX_CONF_UNSET) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 4148 | return "is duplicate"; |
| 4149 | } |
| 4150 | |
| 4151 | if (ngx_strcmp(value[1].data, "off") == 0) { |
Valentin Bartenev | 5de6662 | 2014-12-22 12:59:02 +0300 | [diff] [blame] | 4152 | plcf->upstream.cache = 0; |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 4153 | return NGX_CONF_OK; |
| 4154 | } |
| 4155 | |
Valentin Bartenev | a4b7b10 | 2014-12-22 12:58:56 +0300 | [diff] [blame] | 4156 | if (plcf->upstream.store > 0) { |
Igor Sysoev | 98f692a | 2009-05-28 13:41:44 +0000 | [diff] [blame] | 4157 | return "is incompatible with \"proxy_store\""; |
| 4158 | } |
| 4159 | |
Valentin Bartenev | 5de6662 | 2014-12-22 12:59:02 +0300 | [diff] [blame] | 4160 | plcf->upstream.cache = 1; |
| 4161 | |
Valentin Bartenev | 9a0eb4f | 2014-12-22 12:59:09 +0300 | [diff] [blame] | 4162 | ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
| 4163 | |
| 4164 | ccv.cf = cf; |
| 4165 | ccv.value = &value[1]; |
| 4166 | ccv.complex_value = &cv; |
| 4167 | |
| 4168 | if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
| 4169 | return NGX_CONF_ERROR; |
| 4170 | } |
| 4171 | |
| 4172 | if (cv.lengths != NULL) { |
| 4173 | |
| 4174 | plcf->upstream.cache_value = ngx_palloc(cf->pool, |
| 4175 | sizeof(ngx_http_complex_value_t)); |
| 4176 | if (plcf->upstream.cache_value == NULL) { |
| 4177 | return NGX_CONF_ERROR; |
| 4178 | } |
| 4179 | |
| 4180 | *plcf->upstream.cache_value = cv; |
| 4181 | |
| 4182 | return NGX_CONF_OK; |
| 4183 | } |
| 4184 | |
Valentin Bartenev | 5de6662 | 2014-12-22 12:59:02 +0300 | [diff] [blame] | 4185 | plcf->upstream.cache_zone = ngx_shared_memory_add(cf, &value[1], 0, |
| 4186 | &ngx_http_proxy_module); |
| 4187 | if (plcf->upstream.cache_zone == NULL) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 4188 | return NGX_CONF_ERROR; |
| 4189 | } |
| 4190 | |
| 4191 | return NGX_CONF_OK; |
| 4192 | } |
| 4193 | |
Igor Sysoev | 44a69c8 | 2009-04-06 08:58:44 +0000 | [diff] [blame] | 4194 | |
| 4195 | static char * |
| 4196 | ngx_http_proxy_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
| 4197 | { |
| 4198 | ngx_http_proxy_loc_conf_t *plcf = conf; |
| 4199 | |
| 4200 | ngx_str_t *value; |
| 4201 | ngx_http_compile_complex_value_t ccv; |
| 4202 | |
| 4203 | value = cf->args->elts; |
| 4204 | |
Ruslan Ermilov | 73fb7e8 | 2012-12-06 23:03:53 +0000 | [diff] [blame] | 4205 | if (plcf->cache_key.value.data) { |
Igor Sysoev | 44a69c8 | 2009-04-06 08:58:44 +0000 | [diff] [blame] | 4206 | return "is duplicate"; |
| 4207 | } |
| 4208 | |
| 4209 | ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
| 4210 | |
| 4211 | ccv.cf = cf; |
| 4212 | ccv.value = &value[1]; |
| 4213 | ccv.complex_value = &plcf->cache_key; |
| 4214 | |
| 4215 | if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
| 4216 | return NGX_CONF_ERROR; |
| 4217 | } |
| 4218 | |
| 4219 | return NGX_CONF_OK; |
| 4220 | } |
| 4221 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 4222 | #endif |
| 4223 | |
| 4224 | |
Piotr Sikora | a9d9b09 | 2014-10-30 04:30:41 -0700 | [diff] [blame] | 4225 | #if (NGX_HTTP_SSL) |
| 4226 | |
| 4227 | static char * |
| 4228 | ngx_http_proxy_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
| 4229 | { |
| 4230 | ngx_http_proxy_loc_conf_t *plcf = conf; |
| 4231 | |
| 4232 | ngx_str_t *value; |
| 4233 | |
| 4234 | if (plcf->ssl_passwords != NGX_CONF_UNSET_PTR) { |
| 4235 | return "is duplicate"; |
| 4236 | } |
| 4237 | |
| 4238 | value = cf->args->elts; |
| 4239 | |
| 4240 | plcf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]); |
| 4241 | |
| 4242 | if (plcf->ssl_passwords == NULL) { |
| 4243 | return NGX_CONF_ERROR; |
| 4244 | } |
| 4245 | |
| 4246 | return NGX_CONF_OK; |
| 4247 | } |
| 4248 | |
| 4249 | #endif |
| 4250 | |
| 4251 | |
Igor Sysoev | fbd9b43 | 2007-07-13 08:30:34 +0000 | [diff] [blame] | 4252 | static char * |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 4253 | ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data) |
| 4254 | { |
| 4255 | #if (NGX_FREEBSD) |
| 4256 | ssize_t *np = data; |
| 4257 | |
Igor Sysoev | 08e63d4 | 2006-08-14 15:09:38 +0000 | [diff] [blame] | 4258 | if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) { |
Igor Sysoev | 02f742b | 2005-04-08 15:18:55 +0000 | [diff] [blame] | 4259 | ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
| 4260 | "\"proxy_send_lowat\" must be less than %d " |
| 4261 | "(sysctl net.inet.tcp.sendspace)", |
| 4262 | ngx_freebsd_net_inet_tcp_sendspace); |
| 4263 | |
| 4264 | return NGX_CONF_ERROR; |
| 4265 | } |
| 4266 | |
| 4267 | #elif !(NGX_HAVE_SO_SNDLOWAT) |
| 4268 | ssize_t *np = data; |
| 4269 | |
| 4270 | ngx_conf_log_error(NGX_LOG_WARN, cf, 0, |
| 4271 | "\"proxy_send_lowat\" is not supported, ignored"); |
| 4272 | |
| 4273 | *np = 0; |
| 4274 | |
| 4275 | #endif |
| 4276 | |
| 4277 | return NGX_CONF_OK; |
| 4278 | } |
Igor Sysoev | 3d2fd18 | 2006-12-04 16:46:13 +0000 | [diff] [blame] | 4279 | |
| 4280 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 4281 | #if (NGX_HTTP_SSL) |
| 4282 | |
| 4283 | static ngx_int_t |
| 4284 | ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf) |
| 4285 | { |
| 4286 | ngx_pool_cleanup_t *cln; |
| 4287 | |
| 4288 | plcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t)); |
| 4289 | if (plcf->upstream.ssl == NULL) { |
| 4290 | return NGX_ERROR; |
| 4291 | } |
| 4292 | |
| 4293 | plcf->upstream.ssl->log = cf->log; |
| 4294 | |
Andrei Belov | 003b2cd | 2013-09-19 18:30:33 +0400 | [diff] [blame] | 4295 | if (ngx_ssl_create(plcf->upstream.ssl, plcf->ssl_protocols, NULL) |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 4296 | != NGX_OK) |
| 4297 | { |
| 4298 | return NGX_ERROR; |
| 4299 | } |
| 4300 | |
Maxim Dounin | 93eb94d | 2014-04-18 20:13:24 +0400 | [diff] [blame] | 4301 | cln = ngx_pool_cleanup_add(cf->pool, 0); |
| 4302 | if (cln == NULL) { |
| 4303 | return NGX_ERROR; |
| 4304 | } |
| 4305 | |
| 4306 | cln->handler = ngx_ssl_cleanup_ctx; |
| 4307 | cln->data = plcf->upstream.ssl; |
| 4308 | |
Piotr Sikora | a9d9b09 | 2014-10-30 04:30:41 -0700 | [diff] [blame] | 4309 | if (plcf->ssl_certificate.len) { |
| 4310 | |
| 4311 | if (plcf->ssl_certificate_key.len == 0) { |
| 4312 | ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
| 4313 | "no \"proxy_ssl_certificate_key\" is defined " |
| 4314 | "for certificate \"%V\"", &plcf->ssl_certificate); |
| 4315 | return NGX_ERROR; |
| 4316 | } |
| 4317 | |
| 4318 | if (ngx_ssl_certificate(cf, plcf->upstream.ssl, &plcf->ssl_certificate, |
| 4319 | &plcf->ssl_certificate_key, plcf->ssl_passwords) |
| 4320 | != NGX_OK) |
| 4321 | { |
| 4322 | return NGX_ERROR; |
| 4323 | } |
| 4324 | } |
| 4325 | |
Piotr Sikora | 43736b1 | 2013-09-23 15:58:28 -0700 | [diff] [blame] | 4326 | if (SSL_CTX_set_cipher_list(plcf->upstream.ssl->ctx, |
| 4327 | (const char *) plcf->ssl_ciphers.data) |
| 4328 | == 0) |
| 4329 | { |
| 4330 | ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, |
| 4331 | "SSL_CTX_set_cipher_list(\"%V\") failed", |
| 4332 | &plcf->ssl_ciphers); |
| 4333 | return NGX_ERROR; |
| 4334 | } |
| 4335 | |
Maxim Dounin | 27475dd | 2014-04-18 20:13:30 +0400 | [diff] [blame] | 4336 | if (plcf->upstream.ssl_verify) { |
| 4337 | if (plcf->ssl_trusted_certificate.len == 0) { |
| 4338 | ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
| 4339 | "no proxy_ssl_trusted_certificate for proxy_ssl_verify"); |
| 4340 | return NGX_ERROR; |
| 4341 | } |
| 4342 | |
| 4343 | if (ngx_ssl_trusted_certificate(cf, plcf->upstream.ssl, |
| 4344 | &plcf->ssl_trusted_certificate, |
| 4345 | plcf->ssl_verify_depth) |
| 4346 | != NGX_OK) |
| 4347 | { |
| 4348 | return NGX_ERROR; |
| 4349 | } |
| 4350 | |
| 4351 | if (ngx_ssl_crl(cf, plcf->upstream.ssl, &plcf->ssl_crl) != NGX_OK) { |
| 4352 | return NGX_ERROR; |
| 4353 | } |
| 4354 | } |
| 4355 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 4356 | return NGX_OK; |
| 4357 | } |
| 4358 | |
| 4359 | #endif |
| 4360 | |
| 4361 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 4362 | static void |
| 4363 | 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] | 4364 | { |
Igor Sysoev | c9491d1 | 2008-08-26 14:24:14 +0000 | [diff] [blame] | 4365 | if (u->family != AF_UNIX) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 4366 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 4367 | if (u->no_port || u->port == u->default_port) { |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 4368 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 4369 | v->host_header = u->host; |
| 4370 | |
| 4371 | if (u->default_port == 80) { |
Igor Sysoev | 05b1a8f | 2010-05-14 09:56:37 +0000 | [diff] [blame] | 4372 | ngx_str_set(&v->port, "80"); |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 4373 | |
| 4374 | } else { |
Igor Sysoev | 05b1a8f | 2010-05-14 09:56:37 +0000 | [diff] [blame] | 4375 | ngx_str_set(&v->port, "443"); |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 4376 | } |
| 4377 | |
| 4378 | } else { |
Igor Sysoev | 00e0377 | 2007-11-28 19:55:31 +0000 | [diff] [blame] | 4379 | v->host_header.len = u->host.len + 1 + u->port_text.len; |
| 4380 | v->host_header.data = u->host.data; |
| 4381 | v->port = u->port_text; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 4382 | } |
| 4383 | |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 4384 | v->key_start.len += v->host_header.len; |
| 4385 | |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 4386 | } else { |
Igor Sysoev | 05b1a8f | 2010-05-14 09:56:37 +0000 | [diff] [blame] | 4387 | ngx_str_set(&v->host_header, "localhost"); |
| 4388 | ngx_str_null(&v->port); |
Igor Sysoev | 52859f2 | 2009-03-23 13:14:51 +0000 | [diff] [blame] | 4389 | v->key_start.len += sizeof("unix:") - 1 + u->host.len + 1; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 4390 | } |
| 4391 | |
| 4392 | v->uri = u->uri; |
Igor Sysoev | 96dd8af | 2007-11-27 13:34:13 +0000 | [diff] [blame] | 4393 | } |