Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_rewrite_module.c @ 8182:3bff3f397c05
SSL: ssl_conf_command directive.
With the ssl_conf_command directive it is now possible to set
arbitrary OpenSSL configuration parameters as long as nginx is compiled
with OpenSSL 1.0.2 or later. Full list of available configuration
commands can be found in the SSL_CONF_cmd manual page
(https://www.openssl.org/docs/man1.1.1/man3/SSL_CONF_cmd.html).
In particular, this allows configuring PrioritizeChaCha option
(ticket #1445):
ssl_conf_command Options PrioritizeChaCha;
It can be also used to configure TLSv1.3 ciphers in OpenSSL,
which fails to configure them via the SSL_CTX_set_cipher_list()
interface (ticket #1529):
ssl_conf_command Ciphersuites TLS_CHACHA20_POLY1305_SHA256;
Configuration commands are applied after nginx own configuration
for SSL, so they can be used to override anything set by nginx.
Note though that configuring OpenSSL directly with ssl_conf_command
might result in a behaviour nginx does not expect, and should be
done with care.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 22 Oct 2020 18:00:22 +0300 |
parents | db8df9cd84c8 |
children |
rev | line source |
---|---|
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
437
diff
changeset
|
1 |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
437
diff
changeset
|
2 /* |
444
42d11f017717
nginx-0.1.0-2004-09-29-20:00:49 import; remove years from copyright
Igor Sysoev <igor@sysoev.ru>
parents:
441
diff
changeset
|
3 * Copyright (C) Igor Sysoev |
4412 | 4 * Copyright (C) Nginx, Inc. |
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
437
diff
changeset
|
5 */ |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
437
diff
changeset
|
6 |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
7 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
8 #include <ngx_config.h> |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
9 #include <ngx_core.h> |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
10 #include <ngx_http.h> |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
11 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
12 |
485 | 13 typedef struct { |
577 | 14 ngx_array_t *codes; /* uintptr_t */ |
485 | 15 |
577 | 16 ngx_uint_t stack_size; |
485 | 17 |
577 | 18 ngx_flag_t log; |
635 | 19 ngx_flag_t uninitialized_variable_warn; |
485 | 20 } ngx_http_rewrite_loc_conf_t; |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
21 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
22 |
485 | 23 static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf); |
24 static char *ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, | |
487 | 25 void *parent, void *child); |
681 | 26 static ngx_int_t ngx_http_rewrite_init(ngx_conf_t *cf); |
485 | 27 static char *ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
28 static char *ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, | |
487 | 29 void *conf); |
527 | 30 static char *ngx_http_rewrite_break(ngx_conf_t *cf, ngx_command_t *cmd, |
31 void *conf); | |
485 | 32 static char *ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, |
487 | 33 void *conf); |
501 | 34 static char * ngx_http_rewrite_if_condition(ngx_conf_t *cf, |
35 ngx_http_rewrite_loc_conf_t *lcf); | |
36 static char *ngx_http_rewrite_variable(ngx_conf_t *cf, | |
37 ngx_http_rewrite_loc_conf_t *lcf, ngx_str_t *value); | |
509 | 38 static char *ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, |
501 | 39 void *conf); |
577 | 40 static char * ngx_http_rewrite_value(ngx_conf_t *cf, |
41 ngx_http_rewrite_loc_conf_t *lcf, ngx_str_t *value); | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
42 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
43 |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
44 static ngx_command_t ngx_http_rewrite_commands[] = { |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
45 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
46 { ngx_string("rewrite"), |
485 | 47 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |
48 |NGX_CONF_TAKE23, | |
49 ngx_http_rewrite, | |
50 NGX_HTTP_LOC_CONF_OFFSET, | |
51 0, | |
52 NULL }, | |
53 | |
54 { ngx_string("return"), | |
55 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF | |
3633 | 56 |NGX_CONF_TAKE12, |
485 | 57 ngx_http_rewrite_return, |
58 NGX_HTTP_LOC_CONF_OFFSET, | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
59 0, |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
60 NULL }, |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
61 |
527 | 62 { ngx_string("break"), |
63 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF | |
64 |NGX_CONF_NOARGS, | |
65 ngx_http_rewrite_break, | |
66 NGX_HTTP_LOC_CONF_OFFSET, | |
67 0, | |
68 NULL }, | |
69 | |
485 | 70 { ngx_string("if"), |
71 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE, | |
72 ngx_http_rewrite_if, | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
73 NGX_HTTP_LOC_CONF_OFFSET, |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
74 0, |
485 | 75 NULL }, |
76 | |
501 | 77 { ngx_string("set"), |
78 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF | |
79 |NGX_CONF_TAKE2, | |
80 ngx_http_rewrite_set, | |
81 NGX_HTTP_LOC_CONF_OFFSET, | |
82 0, | |
83 NULL }, | |
84 | |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
85 { ngx_string("rewrite_log"), |
635 | 86 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF |
87 |NGX_HTTP_LIF_CONF|NGX_CONF_FLAG, | |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
88 ngx_conf_set_flag_slot, |
485 | 89 NGX_HTTP_LOC_CONF_OFFSET, |
90 offsetof(ngx_http_rewrite_loc_conf_t, log), | |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
91 NULL }, |
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
92 |
635 | 93 { ngx_string("uninitialized_variable_warn"), |
94 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF | |
95 |NGX_HTTP_LIF_CONF|NGX_CONF_FLAG, | |
96 ngx_conf_set_flag_slot, | |
97 NGX_HTTP_LOC_CONF_OFFSET, | |
98 offsetof(ngx_http_rewrite_loc_conf_t, uninitialized_variable_warn), | |
99 NULL }, | |
100 | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
101 ngx_null_command |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
102 }; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
103 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
104 |
667 | 105 static ngx_http_module_t ngx_http_rewrite_module_ctx = { |
509 | 106 NULL, /* preconfiguration */ |
681 | 107 ngx_http_rewrite_init, /* postconfiguration */ |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
108 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
109 NULL, /* create main configuration */ |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
110 NULL, /* init main configuration */ |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
111 |
485 | 112 NULL, /* create server configuration */ |
113 NULL, /* merge server configuration */ | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
114 |
4499
778ef9c3fd2d
Fixed spelling in single-line comments.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
115 ngx_http_rewrite_create_loc_conf, /* create location configuration */ |
778ef9c3fd2d
Fixed spelling in single-line comments.
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
116 ngx_http_rewrite_merge_loc_conf /* merge location configuration */ |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
117 }; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
118 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
119 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
120 ngx_module_t ngx_http_rewrite_module = { |
509 | 121 NGX_MODULE_V1, |
577 | 122 &ngx_http_rewrite_module_ctx, /* module context */ |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
123 ngx_http_rewrite_commands, /* module directives */ |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
124 NGX_HTTP_MODULE, /* module type */ |
541 | 125 NULL, /* init master */ |
681 | 126 NULL, /* init module */ |
541 | 127 NULL, /* init process */ |
128 NULL, /* init thread */ | |
129 NULL, /* exit thread */ | |
130 NULL, /* exit process */ | |
131 NULL, /* exit master */ | |
132 NGX_MODULE_V1_PADDING | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
133 }; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
134 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
135 |
487 | 136 static ngx_int_t |
137 ngx_http_rewrite_handler(ngx_http_request_t *r) | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
138 { |
4208
470462cfa31b
Skipping location rewrite phase for server null location.
Igor Sysoev <igor@sysoev.ru>
parents:
4147
diff
changeset
|
139 ngx_int_t index; |
509 | 140 ngx_http_script_code_pt code; |
141 ngx_http_script_engine_t *e; | |
4208
470462cfa31b
Skipping location rewrite phase for server null location.
Igor Sysoev <igor@sysoev.ru>
parents:
4147
diff
changeset
|
142 ngx_http_core_srv_conf_t *cscf; |
470462cfa31b
Skipping location rewrite phase for server null location.
Igor Sysoev <igor@sysoev.ru>
parents:
4147
diff
changeset
|
143 ngx_http_core_main_conf_t *cmcf; |
635 | 144 ngx_http_rewrite_loc_conf_t *rlcf; |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
145 |
4208
470462cfa31b
Skipping location rewrite phase for server null location.
Igor Sysoev <igor@sysoev.ru>
parents:
4147
diff
changeset
|
146 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); |
470462cfa31b
Skipping location rewrite phase for server null location.
Igor Sysoev <igor@sysoev.ru>
parents:
4147
diff
changeset
|
147 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); |
470462cfa31b
Skipping location rewrite phase for server null location.
Igor Sysoev <igor@sysoev.ru>
parents:
4147
diff
changeset
|
148 index = cmcf->phase_engine.location_rewrite_index; |
470462cfa31b
Skipping location rewrite phase for server null location.
Igor Sysoev <igor@sysoev.ru>
parents:
4147
diff
changeset
|
149 |
470462cfa31b
Skipping location rewrite phase for server null location.
Igor Sysoev <igor@sysoev.ru>
parents:
4147
diff
changeset
|
150 if (r->phase_handler == index && r->loc_conf == cscf->ctx->loc_conf) { |
470462cfa31b
Skipping location rewrite phase for server null location.
Igor Sysoev <igor@sysoev.ru>
parents:
4147
diff
changeset
|
151 /* skipping location rewrite phase for server null location */ |
470462cfa31b
Skipping location rewrite phase for server null location.
Igor Sysoev <igor@sysoev.ru>
parents:
4147
diff
changeset
|
152 return NGX_DECLINED; |
470462cfa31b
Skipping location rewrite phase for server null location.
Igor Sysoev <igor@sysoev.ru>
parents:
4147
diff
changeset
|
153 } |
470462cfa31b
Skipping location rewrite phase for server null location.
Igor Sysoev <igor@sysoev.ru>
parents:
4147
diff
changeset
|
154 |
635 | 155 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_rewrite_module); |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
156 |
635 | 157 if (rlcf->codes == NULL) { |
485 | 158 return NGX_DECLINED; |
159 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
160 |
509 | 161 e = ngx_pcalloc(r->pool, sizeof(ngx_http_script_engine_t)); |
501 | 162 if (e == NULL) { |
485 | 163 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
164 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
165 |
509 | 166 e->sp = ngx_pcalloc(r->pool, |
635 | 167 rlcf->stack_size * sizeof(ngx_http_variable_value_t)); |
485 | 168 if (e->sp == NULL) { |
169 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
170 } | |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
171 |
635 | 172 e->ip = rlcf->codes->elts; |
509 | 173 e->request = r; |
485 | 174 e->quote = 1; |
635 | 175 e->log = rlcf->log; |
485 | 176 e->status = NGX_DECLINED; |
177 | |
178 while (*(uintptr_t *) e->ip) { | |
509 | 179 code = *(ngx_http_script_code_pt *) e->ip; |
485 | 180 code(e); |
181 } | |
182 | |
7355
b64adc956643
Rewrite: removed r->err_status special handling (ticket #1634).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6899
diff
changeset
|
183 return e->status; |
485 | 184 } |
185 | |
186 | |
573 | 187 static ngx_int_t |
188 ngx_http_rewrite_var(ngx_http_request_t *r, ngx_http_variable_value_t *v, | |
189 uintptr_t data) | |
501 | 190 { |
635 | 191 ngx_http_variable_t *var; |
192 ngx_http_core_main_conf_t *cmcf; | |
193 ngx_http_rewrite_loc_conf_t *rlcf; | |
194 | |
195 rlcf = ngx_http_get_module_loc_conf(r, ngx_http_rewrite_module); | |
196 | |
197 if (rlcf->uninitialized_variable_warn == 0) { | |
198 *v = ngx_http_variable_null_value; | |
199 return NGX_OK; | |
200 } | |
501 | 201 |
202 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
203 | |
204 var = cmcf->variables.elts; | |
205 | |
206 /* | |
207 * the ngx_http_rewrite_module sets variables directly in r->variables, | |
519 | 208 * and they should be handled by ngx_http_get_indexed_variable(), |
501 | 209 * so the handler is called only if the variable is not initialized |
210 */ | |
211 | |
635 | 212 ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, |
501 | 213 "using uninitialized \"%V\" variable", &var[data].name); |
214 | |
577 | 215 *v = ngx_http_variable_null_value; |
573 | 216 |
217 return NGX_OK; | |
501 | 218 } |
219 | |
220 | |
487 | 221 static void * |
222 ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf) | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
223 { |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
224 ngx_http_rewrite_loc_conf_t *conf; |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
225 |
501 | 226 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_rewrite_loc_conf_t)); |
227 if (conf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2547
diff
changeset
|
228 return NULL; |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
229 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
230 |
485 | 231 conf->stack_size = NGX_CONF_UNSET_UINT; |
232 conf->log = NGX_CONF_UNSET; | |
635 | 233 conf->uninitialized_variable_warn = NGX_CONF_UNSET; |
485 | 234 |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
235 return conf; |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
236 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
237 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
238 |
487 | 239 static char * |
240 ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
241 { |
485 | 242 ngx_http_rewrite_loc_conf_t *prev = parent; |
243 ngx_http_rewrite_loc_conf_t *conf = child; | |
244 | |
509 | 245 uintptr_t *code; |
485 | 246 |
247 ngx_conf_merge_value(conf->log, prev->log, 0); | |
635 | 248 ngx_conf_merge_value(conf->uninitialized_variable_warn, |
249 prev->uninitialized_variable_warn, 1); | |
663 | 250 ngx_conf_merge_uint_value(conf->stack_size, prev->stack_size, 10); |
485 | 251 |
252 if (conf->codes == NULL) { | |
253 return NGX_CONF_OK; | |
254 } | |
255 | |
256 if (conf->codes == prev->codes) { | |
257 return NGX_CONF_OK; | |
258 } | |
259 | |
501 | 260 code = ngx_array_push_n(conf->codes, sizeof(uintptr_t)); |
261 if (code == NULL) { | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
262 return NGX_CONF_ERROR; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
263 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
264 |
485 | 265 *code = (uintptr_t) NULL; |
266 | |
267 return NGX_CONF_OK; | |
268 } | |
269 | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
270 |
509 | 271 static ngx_int_t |
681 | 272 ngx_http_rewrite_init(ngx_conf_t *cf) |
577 | 273 { |
509 | 274 ngx_http_handler_pt *h; |
275 ngx_http_core_main_conf_t *cmcf; | |
276 | |
681 | 277 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
509 | 278 |
573 | 279 h = ngx_array_push(&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers); |
280 if (h == NULL) { | |
281 return NGX_ERROR; | |
282 } | |
283 | |
284 *h = ngx_http_rewrite_handler; | |
285 | |
509 | 286 h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers); |
287 if (h == NULL) { | |
288 return NGX_ERROR; | |
289 } | |
290 | |
291 *h = ngx_http_rewrite_handler; | |
292 | |
293 return NGX_OK; | |
577 | 294 } |
509 | 295 |
296 | |
487 | 297 static char * |
298 ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
485 | 299 { |
577 | 300 ngx_http_rewrite_loc_conf_t *lcf = conf; |
301 | |
3325 | 302 ngx_str_t *value; |
509 | 303 ngx_uint_t last; |
3325 | 304 ngx_regex_compile_t rc; |
509 | 305 ngx_http_script_code_pt *code; |
306 ngx_http_script_compile_t sc; | |
307 ngx_http_script_regex_code_t *regex; | |
308 ngx_http_script_regex_end_code_t *regex_end; | |
309 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
485 | 310 |
509 | 311 regex = ngx_http_script_start_code(cf->pool, &lcf->codes, |
312 sizeof(ngx_http_script_regex_code_t)); | |
485 | 313 if (regex == NULL) { |
314 return NGX_CONF_ERROR; | |
315 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
316 |
509 | 317 ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t)); |
318 | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
319 value = cf->args->elts; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
320 |
7606
db8df9cd84c8
Rewrite: disallow empty replacements.
Ruslan Ermilov <ru@nginx.com>
parents:
7355
diff
changeset
|
321 if (value[2].len == 0) { |
db8df9cd84c8
Rewrite: disallow empty replacements.
Ruslan Ermilov <ru@nginx.com>
parents:
7355
diff
changeset
|
322 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty replacement"); |
db8df9cd84c8
Rewrite: disallow empty replacements.
Ruslan Ermilov <ru@nginx.com>
parents:
7355
diff
changeset
|
323 return NGX_CONF_ERROR; |
db8df9cd84c8
Rewrite: disallow empty replacements.
Ruslan Ermilov <ru@nginx.com>
parents:
7355
diff
changeset
|
324 } |
db8df9cd84c8
Rewrite: disallow empty replacements.
Ruslan Ermilov <ru@nginx.com>
parents:
7355
diff
changeset
|
325 |
3325 | 326 ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); |
327 | |
328 rc.pattern = value[1]; | |
329 rc.err.len = NGX_MAX_CONF_ERRSTR; | |
330 rc.err.data = errstr; | |
485 | 331 |
332 /* TODO: NGX_REGEX_CASELESS */ | |
333 | |
3325 | 334 regex->regex = ngx_http_regex_compile(cf, &rc); |
485 | 335 if (regex->regex == NULL) { |
336 return NGX_CONF_ERROR; | |
337 } | |
338 | |
509 | 339 regex->code = ngx_http_script_regex_start_code; |
485 | 340 regex->uri = 1; |
341 regex->name = value[1]; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
342 |
509 | 343 if (value[2].data[value[2].len - 1] == '?') { |
344 | |
345 /* the last "?" drops the original arguments */ | |
346 value[2].len--; | |
347 | |
348 } else { | |
349 regex->add_args = 1; | |
350 } | |
351 | |
485 | 352 last = 0; |
353 | |
3524
ca24774c16e3
autodetect redirect if URI is rewritten to a string starting with $scheme
Igor Sysoev <igor@sysoev.ru>
parents:
3325
diff
changeset
|
354 if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0 |
ca24774c16e3
autodetect redirect if URI is rewritten to a string starting with $scheme
Igor Sysoev <igor@sysoev.ru>
parents:
3325
diff
changeset
|
355 || ngx_strncmp(value[2].data, "https://", sizeof("https://") - 1) == 0 |
ca24774c16e3
autodetect redirect if URI is rewritten to a string starting with $scheme
Igor Sysoev <igor@sysoev.ru>
parents:
3325
diff
changeset
|
356 || ngx_strncmp(value[2].data, "$scheme", sizeof("$scheme") - 1) == 0) |
ca24774c16e3
autodetect redirect if URI is rewritten to a string starting with $scheme
Igor Sysoev <igor@sysoev.ru>
parents:
3325
diff
changeset
|
357 { |
2054
989176d3ffc5
auto detect https redirect in rewrite
Igor Sysoev <igor@sysoev.ru>
parents:
2027
diff
changeset
|
358 regex->status = NGX_HTTP_MOVED_TEMPORARILY; |
989176d3ffc5
auto detect https redirect in rewrite
Igor Sysoev <igor@sysoev.ru>
parents:
2027
diff
changeset
|
359 regex->redirect = 1; |
989176d3ffc5
auto detect https redirect in rewrite
Igor Sysoev <igor@sysoev.ru>
parents:
2027
diff
changeset
|
360 last = 1; |
989176d3ffc5
auto detect https redirect in rewrite
Igor Sysoev <igor@sysoev.ru>
parents:
2027
diff
changeset
|
361 } |
989176d3ffc5
auto detect https redirect in rewrite
Igor Sysoev <igor@sysoev.ru>
parents:
2027
diff
changeset
|
362 |
485 | 363 if (cf->args->nelts == 4) { |
364 if (ngx_strcmp(value[3].data, "last") == 0) { | |
365 last = 1; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
366 |
487 | 367 } else if (ngx_strcmp(value[3].data, "break") == 0) { |
368 regex->break_cycle = 1; | |
369 last = 1; | |
370 | |
485 | 371 } else if (ngx_strcmp(value[3].data, "redirect") == 0) { |
372 regex->status = NGX_HTTP_MOVED_TEMPORARILY; | |
373 regex->redirect = 1; | |
374 last = 1; | |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
375 |
485 | 376 } else if (ngx_strcmp(value[3].data, "permanent") == 0) { |
377 regex->status = NGX_HTTP_MOVED_PERMANENTLY; | |
378 regex->redirect = 1; | |
379 last = 1; | |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
380 |
485 | 381 } else { |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
382 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
461 | 383 "invalid parameter \"%V\"", &value[3]); |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
384 return NGX_CONF_ERROR; |
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
385 } |
485 | 386 } |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
387 |
509 | 388 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
485 | 389 |
509 | 390 sc.cf = cf; |
391 sc.source = &value[2]; | |
392 sc.lengths = ®ex->lengths; | |
393 sc.values = &lcf->codes; | |
394 sc.variables = ngx_http_script_variables_count(&value[2]); | |
395 sc.main = regex; | |
396 sc.complete_lengths = 1; | |
397 sc.compile_args = !regex->redirect; | |
485 | 398 |
509 | 399 if (ngx_http_script_compile(&sc) != NGX_OK) { |
400 return NGX_CONF_ERROR; | |
401 } | |
485 | 402 |
509 | 403 regex = sc.main; |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
404 |
509 | 405 regex->size = sc.size; |
406 regex->args = sc.args; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
407 |
641 | 408 if (sc.variables == 0 && !sc.dup_capture) { |
509 | 409 regex->lengths = NULL; |
485 | 410 } |
411 | |
509 | 412 regex_end = ngx_http_script_add_code(lcf->codes, |
413 sizeof(ngx_http_script_regex_end_code_t), | |
414 ®ex); | |
485 | 415 if (regex_end == NULL) { |
416 return NGX_CONF_ERROR; | |
417 } | |
418 | |
509 | 419 regex_end->code = ngx_http_script_regex_end_code; |
485 | 420 regex_end->uri = regex->uri; |
421 regex_end->args = regex->args; | |
509 | 422 regex_end->add_args = regex->add_args; |
485 | 423 regex_end->redirect = regex->redirect; |
424 | |
425 if (last) { | |
517 | 426 code = ngx_http_script_add_code(lcf->codes, sizeof(uintptr_t), ®ex); |
485 | 427 if (code == NULL) { |
428 return NGX_CONF_ERROR; | |
218
05592fd7a436
nginx-0.0.1-2004-01-05-23:55:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
216
diff
changeset
|
429 } |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
430 |
3184 | 431 *code = NULL; |
485 | 432 } |
433 | |
434 regex->next = (u_char *) lcf->codes->elts + lcf->codes->nelts | |
435 - (u_char *) regex; | |
436 | |
437 return NGX_CONF_OK; | |
438 } | |
439 | |
440 | |
487 | 441 static char * |
442 ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
485 | 443 { |
577 | 444 ngx_http_rewrite_loc_conf_t *lcf = conf; |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
445 |
3633 | 446 u_char *p; |
447 ngx_str_t *value, *v; | |
448 ngx_http_script_return_code_t *ret; | |
449 ngx_http_compile_complex_value_t ccv; | |
485 | 450 |
509 | 451 ret = ngx_http_script_start_code(cf->pool, &lcf->codes, |
452 sizeof(ngx_http_script_return_code_t)); | |
485 | 453 if (ret == NULL) { |
454 return NGX_CONF_ERROR; | |
455 } | |
456 | |
457 value = cf->args->elts; | |
458 | |
3633 | 459 ngx_memzero(ret, sizeof(ngx_http_script_return_code_t)); |
460 | |
509 | 461 ret->code = ngx_http_script_return_code; |
485 | 462 |
3633 | 463 p = value[1].data; |
464 | |
465 ret->status = ngx_atoi(p, value[1].len); | |
485 | 466 |
467 if (ret->status == (uintptr_t) NGX_ERROR) { | |
3633 | 468 |
469 if (cf->args->nelts == 2 | |
470 && (ngx_strncmp(p, "http://", sizeof("http://") - 1) == 0 | |
471 || ngx_strncmp(p, "https://", sizeof("https://") - 1) == 0 | |
472 || ngx_strncmp(p, "$scheme", sizeof("$scheme") - 1) == 0)) | |
473 { | |
474 ret->status = NGX_HTTP_MOVED_TEMPORARILY; | |
475 v = &value[1]; | |
476 | |
477 } else { | |
478 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
479 "invalid return code \"%V\"", &value[1]); | |
480 return NGX_CONF_ERROR; | |
481 } | |
482 | |
483 } else { | |
484 | |
4636
ed957e0daeb4
Capped the status code that may be returned with "return" and "try_files".
Ruslan Ermilov <ru@nginx.com>
parents:
4499
diff
changeset
|
485 if (ret->status > 999) { |
ed957e0daeb4
Capped the status code that may be returned with "return" and "try_files".
Ruslan Ermilov <ru@nginx.com>
parents:
4499
diff
changeset
|
486 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
ed957e0daeb4
Capped the status code that may be returned with "return" and "try_files".
Ruslan Ermilov <ru@nginx.com>
parents:
4499
diff
changeset
|
487 "invalid return code \"%V\"", &value[1]); |
ed957e0daeb4
Capped the status code that may be returned with "return" and "try_files".
Ruslan Ermilov <ru@nginx.com>
parents:
4499
diff
changeset
|
488 return NGX_CONF_ERROR; |
ed957e0daeb4
Capped the status code that may be returned with "return" and "try_files".
Ruslan Ermilov <ru@nginx.com>
parents:
4499
diff
changeset
|
489 } |
ed957e0daeb4
Capped the status code that may be returned with "return" and "try_files".
Ruslan Ermilov <ru@nginx.com>
parents:
4499
diff
changeset
|
490 |
3633 | 491 if (cf->args->nelts == 2) { |
492 return NGX_CONF_OK; | |
493 } | |
494 | |
495 v = &value[2]; | |
496 } | |
497 | |
498 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); | |
499 | |
500 ccv.cf = cf; | |
501 ccv.value = v; | |
502 ccv.complex_value = &ret->text; | |
503 | |
504 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { | |
485 | 505 return NGX_CONF_ERROR; |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
506 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
507 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
508 return NGX_CONF_OK; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
509 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
510 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
511 |
487 | 512 static char * |
527 | 513 ngx_http_rewrite_break(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
514 { | |
515 ngx_http_rewrite_loc_conf_t *lcf = conf; | |
516 | |
517 ngx_http_script_code_pt *code; | |
518 | |
519 code = ngx_http_script_start_code(cf->pool, &lcf->codes, sizeof(uintptr_t)); | |
520 if (code == NULL) { | |
521 return NGX_CONF_ERROR; | |
522 } | |
523 | |
524 *code = ngx_http_script_break_code; | |
525 | |
526 return NGX_CONF_OK; | |
527 } | |
528 | |
529 | |
530 static char * | |
487 | 531 ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
532 { |
577 | 533 ngx_http_rewrite_loc_conf_t *lcf = conf; |
485 | 534 |
535 void *mconf; | |
536 char *rv; | |
537 u_char *elts; | |
538 ngx_uint_t i; | |
539 ngx_conf_t save; | |
540 ngx_http_module_t *module; | |
541 ngx_http_conf_ctx_t *ctx, *pctx; | |
2027 | 542 ngx_http_core_loc_conf_t *clcf, *pclcf; |
509 | 543 ngx_http_script_if_code_t *if_code; |
485 | 544 ngx_http_rewrite_loc_conf_t *nlcf; |
545 | |
501 | 546 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); |
547 if (ctx == NULL) { | |
485 | 548 return NGX_CONF_ERROR; |
549 } | |
550 | |
551 pctx = cf->ctx; | |
552 ctx->main_conf = pctx->main_conf; | |
577 | 553 ctx->srv_conf = pctx->srv_conf; |
485 | 554 |
555 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); | |
556 if (ctx->loc_conf == NULL) { | |
557 return NGX_CONF_ERROR; | |
558 } | |
559 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6244
diff
changeset
|
560 for (i = 0; cf->cycle->modules[i]; i++) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6244
diff
changeset
|
561 if (cf->cycle->modules[i]->type != NGX_HTTP_MODULE) { |
485 | 562 continue; |
563 } | |
564 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6244
diff
changeset
|
565 module = cf->cycle->modules[i]->ctx; |
577 | 566 |
485 | 567 if (module->create_loc_conf) { |
568 | |
501 | 569 mconf = module->create_loc_conf(cf); |
570 if (mconf == NULL) { | |
6474 | 571 return NGX_CONF_ERROR; |
485 | 572 } |
573 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6244
diff
changeset
|
574 ctx->loc_conf[cf->cycle->modules[i]->ctx_index] = mconf; |
485 | 575 } |
576 } | |
577 | |
578 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index]; | |
579 | |
580 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; | |
581 clcf->loc_conf = ctx->loc_conf; | |
582 clcf->name = pclcf->name; | |
583 clcf->noname = 1; | |
584 | |
2027 | 585 if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) { |
485 | 586 return NGX_CONF_ERROR; |
587 } | |
588 | |
501 | 589 if (ngx_http_rewrite_if_condition(cf, lcf) != NGX_CONF_OK) { |
485 | 590 return NGX_CONF_ERROR; |
591 } | |
592 | |
509 | 593 if_code = ngx_array_push_n(lcf->codes, sizeof(ngx_http_script_if_code_t)); |
485 | 594 if (if_code == NULL) { |
3001 | 595 return NGX_CONF_ERROR; |
485 | 596 } |
597 | |
509 | 598 if_code->code = ngx_http_script_if_code; |
485 | 599 |
600 elts = lcf->codes->elts; | |
601 | |
602 | |
631 | 603 /* the inner directives must be compiled to the same code array */ |
485 | 604 |
605 nlcf = ctx->loc_conf[ngx_http_rewrite_module.ctx_index]; | |
606 nlcf->codes = lcf->codes; | |
607 | |
608 | |
609 save = *cf; | |
610 cf->ctx = ctx; | |
611 | |
6244
055d1f63960a
Fixed segfault with incorrect location nesting.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5816
diff
changeset
|
612 if (cf->cmd_type == NGX_HTTP_SRV_CONF) { |
485 | 613 if_code->loc_conf = NULL; |
614 cf->cmd_type = NGX_HTTP_SIF_CONF; | |
615 | |
616 } else { | |
617 if_code->loc_conf = ctx->loc_conf; | |
618 cf->cmd_type = NGX_HTTP_LIF_CONF; | |
619 } | |
620 | |
621 rv = ngx_conf_parse(cf, NULL); | |
622 | |
623 *cf = save; | |
624 | |
625 if (rv != NGX_CONF_OK) { | |
626 return rv; | |
627 } | |
628 | |
629 | |
630 if (elts != lcf->codes->elts) { | |
509 | 631 if_code = (ngx_http_script_if_code_t *) |
485 | 632 ((u_char *) if_code + ((u_char *) lcf->codes->elts - elts)); |
633 } | |
634 | |
635 if_code->next = (u_char *) lcf->codes->elts + lcf->codes->nelts | |
636 - (u_char *) if_code; | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
637 |
555 | 638 /* the code array belong to parent block */ |
639 | |
640 nlcf->codes = NULL; | |
641 | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
642 return NGX_CONF_OK; |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
643 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
644 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
645 |
487 | 646 static char * |
501 | 647 ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf) |
648 { | |
631 | 649 u_char *p; |
650 size_t len; | |
3325 | 651 ngx_str_t *value; |
652 ngx_uint_t cur, last; | |
653 ngx_regex_compile_t rc; | |
577 | 654 ngx_http_script_code_pt *code; |
631 | 655 ngx_http_script_file_code_t *fop; |
509 | 656 ngx_http_script_regex_code_t *regex; |
657 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
501 | 658 |
659 value = cf->args->elts; | |
660 last = cf->args->nelts - 1; | |
661 | |
662 if (value[1].len < 1 || value[1].data[0] != '(') { | |
663 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
664 "invalid condition \"%V\"", &value[1]); | |
665 return NGX_CONF_ERROR; | |
666 } | |
667 | |
668 if (value[1].len == 1) { | |
669 cur = 2; | |
670 | |
671 } else { | |
672 cur = 1; | |
673 value[1].len--; | |
674 value[1].data++; | |
675 } | |
676 | |
677 if (value[last].len < 1 || value[last].data[value[last].len - 1] != ')') { | |
678 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
679 "invalid condition \"%V\"", &value[last]); | |
680 return NGX_CONF_ERROR; | |
681 } | |
682 | |
683 if (value[last].len == 1) { | |
684 last--; | |
685 | |
686 } else { | |
687 value[last].len--; | |
688 value[last].data[value[last].len] = '\0'; | |
689 } | |
690 | |
631 | 691 len = value[cur].len; |
692 p = value[cur].data; | |
693 | |
694 if (len > 1 && p[0] == '$') { | |
501 | 695 |
696 if (cur != last && cur + 2 != last) { | |
697 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
631 | 698 "invalid condition \"%V\"", &value[cur]); |
501 | 699 return NGX_CONF_ERROR; |
700 } | |
701 | |
577 | 702 if (ngx_http_rewrite_variable(cf, lcf, &value[cur]) != NGX_CONF_OK) { |
501 | 703 return NGX_CONF_ERROR; |
704 } | |
705 | |
706 if (cur == last) { | |
707 return NGX_CONF_OK; | |
708 } | |
709 | |
710 cur++; | |
711 | |
631 | 712 len = value[cur].len; |
713 p = value[cur].data; | |
714 | |
715 if (len == 1 && p[0] == '=') { | |
577 | 716 |
717 if (ngx_http_rewrite_value(cf, lcf, &value[last]) != NGX_CONF_OK) { | |
718 return NGX_CONF_ERROR; | |
719 } | |
720 | |
721 code = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
722 sizeof(uintptr_t)); | |
723 if (code == NULL) { | |
724 return NGX_CONF_ERROR; | |
725 } | |
726 | |
727 *code = ngx_http_script_equal_code; | |
728 | |
729 return NGX_CONF_OK; | |
501 | 730 } |
731 | |
631 | 732 if (len == 2 && p[0] == '!' && p[1] == '=') { |
733 | |
577 | 734 if (ngx_http_rewrite_value(cf, lcf, &value[last]) != NGX_CONF_OK) { |
735 return NGX_CONF_ERROR; | |
736 } | |
737 | |
738 code = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
739 sizeof(uintptr_t)); | |
740 if (code == NULL) { | |
741 return NGX_CONF_ERROR; | |
742 } | |
743 | |
744 *code = ngx_http_script_not_equal_code; | |
745 return NGX_CONF_OK; | |
501 | 746 } |
747 | |
631 | 748 if ((len == 1 && p[0] == '~') |
749 || (len == 2 && p[0] == '~' && p[1] == '*') | |
750 || (len == 2 && p[0] == '!' && p[1] == '~') | |
751 || (len == 3 && p[0] == '!' && p[1] == '~' && p[2] == '*')) | |
577 | 752 { |
753 regex = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
754 sizeof(ngx_http_script_regex_code_t)); | |
755 if (regex == NULL) { | |
756 return NGX_CONF_ERROR; | |
757 } | |
509 | 758 |
577 | 759 ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t)); |
760 | |
3325 | 761 ngx_memzero(&rc, sizeof(ngx_regex_compile_t)); |
577 | 762 |
3325 | 763 rc.pattern = value[last]; |
764 rc.options = (p[len - 1] == '*') ? NGX_REGEX_CASELESS : 0; | |
765 rc.err.len = NGX_MAX_CONF_ERRSTR; | |
766 rc.err.data = errstr; | |
501 | 767 |
3325 | 768 regex->regex = ngx_http_regex_compile(cf, &rc); |
577 | 769 if (regex->regex == NULL) { |
770 return NGX_CONF_ERROR; | |
771 } | |
772 | |
773 regex->code = ngx_http_script_regex_start_code; | |
774 regex->next = sizeof(ngx_http_script_regex_code_t); | |
775 regex->test = 1; | |
631 | 776 if (p[0] == '!') { |
777 regex->negative_test = 1; | |
778 } | |
577 | 779 regex->name = value[last]; |
501 | 780 |
577 | 781 return NGX_CONF_OK; |
501 | 782 } |
783 | |
577 | 784 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
785 "unexpected \"%V\" in condition", &value[cur]); | |
786 return NGX_CONF_ERROR; | |
631 | 787 |
788 } else if ((len == 2 && p[0] == '-') | |
789 || (len == 3 && p[0] == '!' && p[1] == '-')) | |
790 { | |
791 if (cur + 1 != last) { | |
792 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
793 "invalid condition \"%V\"", &value[cur]); | |
794 return NGX_CONF_ERROR; | |
795 } | |
796 | |
797 value[last].data[value[last].len] = '\0'; | |
798 value[last].len++; | |
799 | |
800 if (ngx_http_rewrite_value(cf, lcf, &value[last]) != NGX_CONF_OK) { | |
801 return NGX_CONF_ERROR; | |
802 } | |
803 | |
804 fop = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
805 sizeof(ngx_http_script_file_code_t)); | |
806 if (fop == NULL) { | |
807 return NGX_CONF_ERROR; | |
808 } | |
809 | |
810 fop->code = ngx_http_script_file_code; | |
811 | |
812 if (p[1] == 'f') { | |
813 fop->op = ngx_http_script_file_plain; | |
814 return NGX_CONF_OK; | |
815 } | |
816 | |
669 | 817 if (p[1] == 'd') { |
818 fop->op = ngx_http_script_file_dir; | |
819 return NGX_CONF_OK; | |
820 } | |
821 | |
822 if (p[1] == 'e') { | |
823 fop->op = ngx_http_script_file_exists; | |
824 return NGX_CONF_OK; | |
825 } | |
826 | |
827 if (p[1] == 'x') { | |
828 fop->op = ngx_http_script_file_exec; | |
829 return NGX_CONF_OK; | |
830 } | |
831 | |
631 | 832 if (p[0] == '!') { |
833 if (p[2] == 'f') { | |
834 fop->op = ngx_http_script_file_not_plain; | |
835 return NGX_CONF_OK; | |
836 } | |
669 | 837 |
838 if (p[2] == 'd') { | |
839 fop->op = ngx_http_script_file_not_dir; | |
840 return NGX_CONF_OK; | |
841 } | |
842 | |
843 if (p[2] == 'e') { | |
844 fop->op = ngx_http_script_file_not_exists; | |
845 return NGX_CONF_OK; | |
846 } | |
847 | |
848 if (p[2] == 'x') { | |
849 fop->op = ngx_http_script_file_not_exec; | |
850 return NGX_CONF_OK; | |
851 } | |
631 | 852 } |
853 | |
854 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
855 "invalid condition \"%V\"", &value[cur]); | |
856 return NGX_CONF_ERROR; | |
501 | 857 } |
858 | |
859 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
860 "invalid condition \"%V\"", &value[cur]); | |
861 | |
862 return NGX_CONF_ERROR; | |
863 } | |
864 | |
865 | |
866 static char * | |
867 ngx_http_rewrite_variable(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf, | |
868 ngx_str_t *value) | |
869 { | |
509 | 870 ngx_int_t index; |
871 ngx_http_script_var_code_t *var_code; | |
501 | 872 |
873 value->len--; | |
874 value->data++; | |
875 | |
577 | 876 index = ngx_http_get_variable_index(cf, value); |
501 | 877 |
577 | 878 if (index == NGX_ERROR) { |
879 return NGX_CONF_ERROR; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
880 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
881 |
577 | 882 var_code = ngx_http_script_start_code(cf->pool, &lcf->codes, |
883 sizeof(ngx_http_script_var_code_t)); | |
884 if (var_code == NULL) { | |
885 return NGX_CONF_ERROR; | |
485 | 886 } |
887 | |
577 | 888 var_code->code = ngx_http_script_var_code; |
889 var_code->index = index; | |
485 | 890 |
891 return NGX_CONF_OK; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
892 } |
485 | 893 |
894 | |
501 | 895 static char * |
896 ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
897 { | |
577 | 898 ngx_http_rewrite_loc_conf_t *lcf = conf; |
501 | 899 |
637 | 900 ngx_int_t index; |
901 ngx_str_t *value; | |
902 ngx_http_variable_t *v; | |
903 ngx_http_script_var_code_t *vcode; | |
904 ngx_http_script_var_handler_code_t *vhcode; | |
501 | 905 |
906 value = cf->args->elts; | |
907 | |
4972
8b635cf36ccc
Added checks that disallow adding a variable with an empty name.
Ruslan Ermilov <ru@nginx.com>
parents:
4963
diff
changeset
|
908 if (value[1].data[0] != '$') { |
501 | 909 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
910 "invalid variable name \"%V\"", &value[1]); | |
911 return NGX_CONF_ERROR; | |
912 } | |
913 | |
914 value[1].len--; | |
915 value[1].data++; | |
916 | |
6899
d2b2ff157da5
Variables: generic prefix variables.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6474
diff
changeset
|
917 v = ngx_http_add_variable(cf, &value[1], |
d2b2ff157da5
Variables: generic prefix variables.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6474
diff
changeset
|
918 NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_WEAK); |
501 | 919 if (v == NULL) { |
920 return NGX_CONF_ERROR; | |
921 } | |
922 | |
509 | 923 index = ngx_http_get_variable_index(cf, &value[1]); |
924 if (index == NGX_ERROR) { | |
925 return NGX_CONF_ERROR; | |
926 } | |
501 | 927 |
6899
d2b2ff157da5
Variables: generic prefix variables.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6474
diff
changeset
|
928 if (v->get_handler == NULL) { |
637 | 929 v->get_handler = ngx_http_rewrite_var; |
555 | 930 v->data = index; |
931 } | |
509 | 932 |
577 | 933 if (ngx_http_rewrite_value(cf, lcf, &value[2]) != NGX_CONF_OK) { |
934 return NGX_CONF_ERROR; | |
515 | 935 } |
501 | 936 |
637 | 937 if (v->set_handler) { |
938 vhcode = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
939 sizeof(ngx_http_script_var_handler_code_t)); | |
940 if (vhcode == NULL) { | |
941 return NGX_CONF_ERROR; | |
942 } | |
943 | |
944 vhcode->code = ngx_http_script_var_set_handler_code; | |
945 vhcode->handler = v->set_handler; | |
946 vhcode->data = v->data; | |
947 | |
948 return NGX_CONF_OK; | |
949 } | |
950 | |
951 vcode = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
952 sizeof(ngx_http_script_var_code_t)); | |
953 if (vcode == NULL) { | |
501 | 954 return NGX_CONF_ERROR; |
955 } | |
956 | |
637 | 957 vcode->code = ngx_http_script_set_var_code; |
958 vcode->index = (uintptr_t) index; | |
501 | 959 |
960 return NGX_CONF_OK; | |
961 } | |
577 | 962 |
963 | |
964 static char * | |
965 ngx_http_rewrite_value(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf, | |
966 ngx_str_t *value) | |
967 { | |
968 ngx_int_t n; | |
969 ngx_http_script_compile_t sc; | |
970 ngx_http_script_value_code_t *val; | |
971 ngx_http_script_complex_value_code_t *complex; | |
972 | |
973 n = ngx_http_script_variables_count(value); | |
974 | |
975 if (n == 0) { | |
976 val = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
977 sizeof(ngx_http_script_value_code_t)); | |
978 if (val == NULL) { | |
979 return NGX_CONF_ERROR; | |
980 } | |
981 | |
982 n = ngx_atoi(value->data, value->len); | |
983 | |
984 if (n == NGX_ERROR) { | |
985 n = 0; | |
986 } | |
987 | |
988 val->code = ngx_http_script_value_code; | |
989 val->value = (uintptr_t) n; | |
990 val->text_len = (uintptr_t) value->len; | |
991 val->text_data = (uintptr_t) value->data; | |
992 | |
993 return NGX_CONF_OK; | |
994 } | |
995 | |
996 complex = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
997 sizeof(ngx_http_script_complex_value_code_t)); | |
998 if (complex == NULL) { | |
999 return NGX_CONF_ERROR; | |
1000 } | |
1001 | |
1002 complex->code = ngx_http_script_complex_value_code; | |
1003 complex->lengths = NULL; | |
1004 | |
1005 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); | |
1006 | |
1007 sc.cf = cf; | |
1008 sc.source = value; | |
1009 sc.lengths = &complex->lengths; | |
1010 sc.values = &lcf->codes; | |
1011 sc.variables = n; | |
1012 sc.complete_lengths = 1; | |
1013 | |
1014 if (ngx_http_script_compile(&sc) != NGX_OK) { | |
1015 return NGX_CONF_ERROR; | |
1016 } | |
1017 | |
1018 return NGX_CONF_OK; | |
1019 } |