Mercurial > hg > nginx
annotate src/http/modules/ngx_http_rewrite_module.c @ 509:9b8c906f6e63 release-0.1.29
nginx-0.1.29-RELEASE import
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; the bug had appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 12 May 2005 14:58:06 +0000 |
parents | cd3117ad9aab |
children | 417a087c9c4d |
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 |
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
|
4 */ |
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 |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
6 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
7 #include <ngx_config.h> |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
8 #include <ngx_core.h> |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
9 #include <ngx_http.h> |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
10 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
11 |
485 | 12 typedef struct { |
509 | 13 ngx_str_t name; |
14 ngx_uint_t wildcard; | |
485 | 15 } ngx_http_rewrite_referer_t; |
16 | |
17 | |
18 typedef struct { | |
509 | 19 ngx_str_t *name; |
20 ngx_http_variable_value_t *value; | |
501 | 21 } ngx_http_rewrite_variable_t; |
22 | |
23 | |
24 typedef struct { | |
509 | 25 ngx_array_t *codes; /* uintptr_t */ |
26 ngx_array_t *referers; /* ngx_http_rewrite_referer_t */ | |
485 | 27 |
509 | 28 ngx_uint_t max_captures; |
29 ngx_uint_t stack_size; | |
485 | 30 |
509 | 31 ngx_flag_t log; |
485 | 32 |
509 | 33 ngx_flag_t no_referer; |
34 ngx_flag_t blocked_referer; | |
485 | 35 } 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
|
36 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
37 |
485 | 38 static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf); |
39 static char *ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, | |
487 | 40 void *parent, void *child); |
509 | 41 static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle); |
485 | 42 static char *ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
43 static char *ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, | |
487 | 44 void *conf); |
485 | 45 static char *ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, |
487 | 46 void *conf); |
501 | 47 static char * ngx_http_rewrite_if_condition(ngx_conf_t *cf, |
48 ngx_http_rewrite_loc_conf_t *lcf); | |
49 static char *ngx_http_rewrite_variable(ngx_conf_t *cf, | |
50 ngx_http_rewrite_loc_conf_t *lcf, ngx_str_t *value); | |
487 | 51 static char *ngx_http_rewrite_valid_referers(ngx_conf_t *cf, |
52 ngx_command_t *cmd, void *conf); | |
509 | 53 static char *ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, |
501 | 54 void *conf); |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
55 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
56 |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
57 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
|
58 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
59 { ngx_string("rewrite"), |
485 | 60 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |
61 |NGX_CONF_TAKE23, | |
62 ngx_http_rewrite, | |
63 NGX_HTTP_LOC_CONF_OFFSET, | |
64 0, | |
65 NULL }, | |
66 | |
67 { ngx_string("return"), | |
68 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF | |
69 |NGX_CONF_TAKE1, | |
70 ngx_http_rewrite_return, | |
71 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
|
72 0, |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
73 NULL }, |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
74 |
485 | 75 { ngx_string("if"), |
76 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE, | |
77 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
|
78 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
|
79 0, |
485 | 80 NULL }, |
81 | |
82 { ngx_string("valid_referers"), | |
83 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
84 ngx_http_rewrite_valid_referers, | |
85 NGX_HTTP_LOC_CONF_OFFSET, | |
86 0, | |
87 NULL }, | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
88 |
501 | 89 { ngx_string("set"), |
90 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF | |
91 |NGX_CONF_TAKE2, | |
92 ngx_http_rewrite_set, | |
93 NGX_HTTP_LOC_CONF_OFFSET, | |
94 0, | |
95 NULL }, | |
96 | |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
97 { ngx_string("rewrite_log"), |
485 | 98 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |
99 |NGX_CONF_TAKE1, | |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
100 ngx_conf_set_flag_slot, |
485 | 101 NGX_HTTP_LOC_CONF_OFFSET, |
102 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
|
103 NULL }, |
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
104 |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
105 ngx_null_command |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
106 }; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
107 |
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 ngx_http_module_t ngx_http_rewrite_module_ctx = { |
509 | 110 NULL, /* preconfiguration */ |
111 NULL, /* postconfiguration */ | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
112 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
113 NULL, /* create main configuration */ |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
114 NULL, /* init main configuration */ |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
115 |
485 | 116 NULL, /* create server configuration */ |
117 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
|
118 |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
119 ngx_http_rewrite_create_loc_conf, /* create location configration */ |
485 | 120 ngx_http_rewrite_merge_loc_conf /* merge location configration */ |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
121 }; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
122 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
123 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
124 ngx_module_t ngx_http_rewrite_module = { |
509 | 125 NGX_MODULE_V1, |
485 | 126 &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
|
127 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
|
128 NGX_HTTP_MODULE, /* module type */ |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
129 ngx_http_rewrite_init, /* init module */ |
485 | 130 NULL /* init process */ |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
131 }; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
132 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
133 |
501 | 134 static ngx_http_variable_value_t ngx_http_rewrite_null_value = |
509 | 135 { 0, ngx_string("") }; |
501 | 136 |
485 | 137 |
487 | 138 static ngx_int_t |
139 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
|
140 { |
509 | 141 ngx_http_script_code_pt code; |
142 ngx_http_script_engine_t *e; | |
485 | 143 ngx_http_rewrite_loc_conf_t *cf; |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
144 |
485 | 145 cf = 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
|
146 |
485 | 147 if (cf->codes == NULL) { |
148 return NGX_DECLINED; | |
149 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
150 |
509 | 151 e = ngx_pcalloc(r->pool, sizeof(ngx_http_script_engine_t)); |
501 | 152 if (e == NULL) { |
485 | 153 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
154 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
155 |
509 | 156 e->sp = ngx_pcalloc(r->pool, |
157 cf->stack_size * sizeof(ngx_http_variable_value_t)); | |
485 | 158 if (e->sp == NULL) { |
159 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
160 } | |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
161 |
485 | 162 if (cf->max_captures) { |
163 e->captures = ngx_palloc(r->pool, cf->max_captures * sizeof(int)); | |
164 if (e->captures == NULL) { | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
165 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
166 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
167 |
485 | 168 } else { |
169 e->captures = NULL; | |
170 } | |
171 | |
172 e->ip = cf->codes->elts; | |
509 | 173 e->request = r; |
485 | 174 e->quote = 1; |
509 | 175 e->log = cf->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 | |
183 return e->status; | |
184 } | |
185 | |
186 | |
487 | 187 static void |
509 | 188 ngx_http_rewrite_invalid_referer_code(ngx_http_script_engine_t *e) |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
189 { |
485 | 190 u_char *ref; |
191 size_t len; | |
192 ngx_uint_t i, n; | |
193 ngx_http_request_t *r; | |
194 ngx_http_rewrite_referer_t *refs; | |
195 ngx_http_rewrite_loc_conf_t *cf; | |
196 | |
197 r = e->request; | |
198 | |
199 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
200 "http rewrite invalid referer"); | |
201 | |
202 cf = ngx_http_get_module_loc_conf(r, ngx_http_rewrite_module); | |
203 | |
204 e->ip += sizeof(uintptr_t); | |
205 | |
206 if (cf->referers == NULL) { | |
501 | 207 e->sp->value = 0; |
208 e->sp->text.len = 0; | |
209 e->sp->text.data = (u_char *) ""; | |
210 e->sp++; | |
211 | |
485 | 212 return; |
213 } | |
214 | |
215 if (r->headers_in.referer == NULL) { | |
216 if (cf->no_referer) { | |
501 | 217 e->sp->value = 0; |
218 e->sp->text.len = 0; | |
219 e->sp->text.data = (u_char *) ""; | |
220 e->sp++; | |
221 | |
485 | 222 return; |
505 | 223 |
485 | 224 } else { |
501 | 225 e->sp->value = 1; |
226 e->sp->text.len = 1; | |
227 e->sp->text.data = (u_char *) "1"; | |
228 e->sp++; | |
229 | |
485 | 230 return; |
231 } | |
232 } | |
233 | |
234 len = r->headers_in.referer->value.len; | |
235 ref = r->headers_in.referer->value.data; | |
236 | |
237 if (len < sizeof("http://i.ru") - 1 | |
238 || (ngx_strncasecmp(ref, "http://", 7) != 0)) | |
239 { | |
505 | 240 if (cf->blocked_referer) { |
241 e->sp->value = 0; | |
242 e->sp->text.len = 0; | |
243 e->sp->text.data = (u_char *) "0"; | |
244 e->sp++; | |
245 | |
246 return; | |
501 | 247 |
505 | 248 } else { |
249 e->sp->value = 1; | |
250 e->sp->text.len = 1; | |
251 e->sp->text.data = (u_char *) "1"; | |
252 e->sp++; | |
253 | |
254 return; | |
255 } | |
485 | 256 } |
257 | |
258 len -= 7; | |
259 ref += 7; | |
260 | |
261 refs = cf->referers->elts; | |
262 for (i = 0; i < cf->referers->nelts; i++ ){ | |
263 | |
264 if (refs[i].name.len > len) { | |
265 continue; | |
266 } | |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
267 |
485 | 268 if (refs[i].wildcard) { |
269 for (n = 0; n < len; n++) { | |
270 if (ref[n] == '/' || ref[n] == ':') { | |
271 break; | |
272 } | |
273 | |
274 if (ref[n] != '.') { | |
275 continue; | |
276 } | |
277 | |
278 if (ngx_strncmp(&ref[n], refs[i].name.data, | |
279 refs[i].name.len) == 0) | |
280 { | |
501 | 281 e->sp->value = 0; |
282 e->sp->text.len = 0; | |
283 e->sp->text.data = (u_char *) ""; | |
284 e->sp++; | |
285 | |
485 | 286 return; |
287 } | |
288 } | |
289 | |
290 } else { | |
291 if (ngx_strncasecmp(refs[i].name.data, ref, refs[i].name.len) == 0) | |
292 { | |
501 | 293 e->sp->value = 0; |
294 e->sp->text.len = 0; | |
295 e->sp->text.data = (u_char *) ""; | |
296 e->sp++; | |
297 | |
485 | 298 return; |
299 } | |
300 } | |
301 } | |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
302 |
501 | 303 e->sp->value = 1; |
304 e->sp->text.len = 1; | |
305 e->sp->text.data = (u_char *) "1"; | |
306 e->sp++; | |
485 | 307 } |
308 | |
309 | |
501 | 310 static ngx_http_variable_value_t * |
311 ngx_http_rewrite_var(ngx_http_request_t *r, uintptr_t data) | |
312 { | |
313 ngx_http_variable_t *var; | |
314 ngx_http_core_main_conf_t *cmcf; | |
315 | |
316 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
317 | |
318 var = cmcf->variables.elts; | |
319 | |
320 /* | |
321 * the ngx_http_rewrite_module sets variables directly in r->variables, | |
322 * and they should be handle by ngx_http_get_indexed_variable(), | |
323 * so the handler is called only if the variable is not initialized | |
324 */ | |
325 | |
326 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | |
327 "using uninitialized \"%V\" variable", &var[data].name); | |
328 | |
329 return &ngx_http_rewrite_null_value; | |
330 } | |
331 | |
332 | |
487 | 333 static void * |
334 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
|
335 { |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
336 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
|
337 |
501 | 338 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_rewrite_loc_conf_t)); |
339 if (conf == NULL) { | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
340 return NGX_CONF_ERROR; |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
341 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
342 |
485 | 343 conf->stack_size = NGX_CONF_UNSET_UINT; |
344 conf->log = NGX_CONF_UNSET; | |
345 conf->no_referer = NGX_CONF_UNSET; | |
505 | 346 conf->blocked_referer = NGX_CONF_UNSET; |
485 | 347 |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
348 return conf; |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
349 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
350 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
351 |
487 | 352 static char * |
353 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
|
354 { |
485 | 355 ngx_http_rewrite_loc_conf_t *prev = parent; |
356 ngx_http_rewrite_loc_conf_t *conf = child; | |
357 | |
509 | 358 uintptr_t *code; |
485 | 359 |
360 ngx_conf_merge_value(conf->log, prev->log, 0); | |
361 ngx_conf_merge_unsigned_value(conf->stack_size, prev->stack_size, 10); | |
362 | |
363 if (conf->referers == NULL) { | |
364 conf->referers = prev->referers; | |
365 ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0); | |
505 | 366 ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0); |
485 | 367 } |
368 | |
499 | 369 if (conf->no_referer == NGX_CONF_UNSET) { |
370 conf->no_referer = 0; | |
371 } | |
372 | |
505 | 373 if (conf->blocked_referer == NGX_CONF_UNSET) { |
374 conf->blocked_referer = 0; | |
375 } | |
376 | |
485 | 377 if (conf->codes == NULL) { |
378 return NGX_CONF_OK; | |
379 } | |
380 | |
381 if (conf->codes == prev->codes) { | |
382 return NGX_CONF_OK; | |
383 } | |
384 | |
501 | 385 code = ngx_array_push_n(conf->codes, sizeof(uintptr_t)); |
386 if (code == NULL) { | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
387 return NGX_CONF_ERROR; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
388 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
389 |
485 | 390 *code = (uintptr_t) NULL; |
391 | |
392 return NGX_CONF_OK; | |
393 } | |
394 | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
395 |
509 | 396 static ngx_int_t |
397 ngx_http_rewrite_init(ngx_cycle_t *cycle) | |
398 { | |
399 ngx_http_handler_pt *h; | |
400 ngx_http_core_main_conf_t *cmcf; | |
401 | |
402 cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); | |
403 | |
404 h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers); | |
405 if (h == NULL) { | |
406 return NGX_ERROR; | |
407 } | |
408 | |
409 *h = ngx_http_rewrite_handler; | |
410 | |
411 return NGX_OK; | |
412 } | |
413 | |
414 | |
487 | 415 static char * |
416 ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
485 | 417 { |
418 ngx_http_rewrite_loc_conf_t *lcf = conf; | |
419 | |
509 | 420 ngx_str_t *value, err; |
421 ngx_int_t n; | |
422 ngx_uint_t last; | |
423 ngx_http_script_code_pt *code; | |
424 ngx_http_script_compile_t sc; | |
425 ngx_http_script_regex_code_t *regex; | |
426 ngx_http_script_regex_end_code_t *regex_end; | |
427 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
485 | 428 |
509 | 429 regex = ngx_http_script_start_code(cf->pool, &lcf->codes, |
430 sizeof(ngx_http_script_regex_code_t)); | |
485 | 431 if (regex == NULL) { |
432 return NGX_CONF_ERROR; | |
433 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
434 |
509 | 435 ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t)); |
436 | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
437 value = cf->args->elts; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
438 |
485 | 439 err.len = NGX_MAX_CONF_ERRSTR; |
440 err.data = errstr; | |
441 | |
442 /* TODO: NGX_REGEX_CASELESS */ | |
443 | |
444 regex->regex = ngx_regex_compile(&value[1], 0, cf->pool, &err); | |
445 | |
446 if (regex->regex == NULL) { | |
447 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | |
448 return NGX_CONF_ERROR; | |
449 } | |
450 | |
509 | 451 regex->code = ngx_http_script_regex_start_code; |
485 | 452 regex->uri = 1; |
453 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
|
454 |
509 | 455 if (value[2].data[value[2].len - 1] == '?') { |
456 | |
457 /* the last "?" drops the original arguments */ | |
458 value[2].len--; | |
459 | |
460 } else { | |
461 regex->add_args = 1; | |
462 } | |
463 | |
485 | 464 last = 0; |
465 | |
466 if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0) { | |
467 regex->status = NGX_HTTP_MOVED_TEMPORARILY; | |
468 regex->redirect = 1; | |
469 last = 1; | |
470 } | |
471 | |
472 if (cf->args->nelts == 4) { | |
473 if (ngx_strcmp(value[3].data, "last") == 0) { | |
474 last = 1; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
475 |
487 | 476 } else if (ngx_strcmp(value[3].data, "break") == 0) { |
477 regex->break_cycle = 1; | |
478 last = 1; | |
479 | |
485 | 480 } else if (ngx_strcmp(value[3].data, "redirect") == 0) { |
481 regex->status = NGX_HTTP_MOVED_TEMPORARILY; | |
482 regex->redirect = 1; | |
483 last = 1; | |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
484 |
485 | 485 } else if (ngx_strcmp(value[3].data, "permanent") == 0) { |
486 regex->status = NGX_HTTP_MOVED_PERMANENTLY; | |
487 regex->redirect = 1; | |
488 last = 1; | |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
489 |
485 | 490 } else { |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
491 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
461 | 492 "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
|
493 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
|
494 } |
485 | 495 } |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
496 |
509 | 497 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); |
485 | 498 |
509 | 499 sc.cf = cf; |
500 sc.source = &value[2]; | |
501 sc.lengths = ®ex->lengths; | |
502 sc.values = &lcf->codes; | |
503 sc.variables = ngx_http_script_variables_count(&value[2]); | |
504 sc.main = regex; | |
505 sc.complete_lengths = 1; | |
506 sc.compile_args = !regex->redirect; | |
485 | 507 |
509 | 508 if (ngx_http_script_compile(&sc) != NGX_OK) { |
509 return NGX_CONF_ERROR; | |
510 } | |
485 | 511 |
509 | 512 regex = sc.main; |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
513 |
509 | 514 regex->ncaptures = sc.ncaptures; |
515 regex->size = sc.size; | |
516 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
|
517 |
509 | 518 if (sc.variables == 0) { |
519 regex->lengths = NULL; | |
485 | 520 } |
521 | |
522 n = ngx_regex_capture_count(regex->regex); | |
523 | |
501 | 524 if (n < 0) { |
525 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
526 ngx_regex_capture_count_n " failed for " | |
527 "pattern \"%V\"", &value[1]); | |
528 return NGX_CONF_ERROR; | |
529 } | |
530 | |
531 if (regex->ncaptures > (ngx_uint_t) n) { | |
485 | 532 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
533 "pattern \"%V\" has less captures " | |
534 "than referrenced in substitution \"%V\"", | |
535 &value[1], &value[2]); | |
536 return NGX_CONF_ERROR; | |
537 } | |
538 | |
501 | 539 if (regex->ncaptures < (ngx_uint_t) n) { |
540 regex->ncaptures = (ngx_uint_t) n; | |
485 | 541 } |
481 | 542 |
485 | 543 if (regex->ncaptures) { |
544 regex->ncaptures = (regex->ncaptures + 1) * 3; | |
545 } | |
546 | |
509 | 547 if (lcf->max_captures < regex->ncaptures) { |
548 lcf->max_captures = regex->ncaptures; | |
549 } | |
550 | |
551 regex_end = ngx_http_script_add_code(lcf->codes, | |
552 sizeof(ngx_http_script_regex_end_code_t), | |
553 ®ex); | |
485 | 554 if (regex_end == NULL) { |
555 return NGX_CONF_ERROR; | |
556 } | |
557 | |
509 | 558 regex_end->code = ngx_http_script_regex_end_code; |
485 | 559 regex_end->uri = regex->uri; |
560 regex_end->args = regex->args; | |
509 | 561 regex_end->add_args = regex->add_args; |
485 | 562 regex_end->redirect = regex->redirect; |
563 | |
564 if (last) { | |
509 | 565 code = ngx_http_script_add_code(lcf->codes, sizeof(uintptr_t), |
566 ®ex); | |
485 | 567 if (code == NULL) { |
568 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
|
569 } |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
570 |
485 | 571 *code = (uintptr_t) NULL; |
572 } | |
573 | |
574 regex->next = (u_char *) lcf->codes->elts + lcf->codes->nelts | |
575 - (u_char *) regex; | |
576 | |
577 return NGX_CONF_OK; | |
578 } | |
579 | |
580 | |
487 | 581 static char * |
582 ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
485 | 583 { |
584 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
|
585 |
509 | 586 ngx_str_t *value; |
587 ngx_http_script_return_code_t *ret; | |
485 | 588 |
509 | 589 ret = ngx_http_script_start_code(cf->pool, &lcf->codes, |
590 sizeof(ngx_http_script_return_code_t)); | |
485 | 591 if (ret == NULL) { |
592 return NGX_CONF_ERROR; | |
593 } | |
594 | |
595 value = cf->args->elts; | |
596 | |
509 | 597 ret->code = ngx_http_script_return_code; |
485 | 598 ret->null = (uintptr_t) NULL; |
599 | |
600 ret->status = ngx_atoi(value[1].data, value[1].len); | |
601 | |
602 if (ret->status == (uintptr_t) NGX_ERROR) { | |
603 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
|
604 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
605 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
606 return NGX_CONF_OK; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
607 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
608 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
609 |
487 | 610 static char * |
611 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
|
612 { |
485 | 613 ngx_http_rewrite_loc_conf_t *lcf = conf; |
614 | |
615 void *mconf; | |
616 char *rv; | |
617 u_char *elts; | |
618 ngx_uint_t i; | |
619 ngx_conf_t save; | |
620 ngx_http_module_t *module; | |
621 ngx_http_conf_ctx_t *ctx, *pctx; | |
622 ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp; | |
509 | 623 ngx_http_script_if_code_t *if_code; |
485 | 624 ngx_http_rewrite_loc_conf_t *nlcf; |
625 | |
501 | 626 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); |
627 if (ctx == NULL) { | |
485 | 628 return NGX_CONF_ERROR; |
629 } | |
630 | |
631 pctx = cf->ctx; | |
632 ctx->main_conf = pctx->main_conf; | |
633 ctx->srv_conf = pctx->srv_conf; | |
634 | |
635 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); | |
636 if (ctx->loc_conf == NULL) { | |
637 return NGX_CONF_ERROR; | |
638 } | |
639 | |
640 for (i = 0; ngx_modules[i]; i++) { | |
641 if (ngx_modules[i]->type != NGX_HTTP_MODULE) { | |
642 continue; | |
643 } | |
644 | |
645 module = ngx_modules[i]->ctx; | |
646 | |
647 if (module->create_loc_conf) { | |
648 | |
501 | 649 mconf = module->create_loc_conf(cf); |
650 if (mconf == NULL) { | |
485 | 651 return NGX_CONF_ERROR; |
652 } | |
653 | |
654 ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf; | |
655 } | |
656 } | |
657 | |
658 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index]; | |
659 | |
660 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; | |
661 clcf->loc_conf = ctx->loc_conf; | |
662 clcf->name = pclcf->name; | |
663 clcf->noname = 1; | |
664 | |
665 if (pclcf->locations.elts == NULL) { | |
666 if (ngx_array_init(&pclcf->locations, cf->pool, 4, sizeof(void *)) | |
667 == NGX_ERROR) | |
668 { | |
669 return NGX_CONF_ERROR; | |
670 } | |
671 } | |
672 | |
501 | 673 clcfp = ngx_array_push(&pclcf->locations); |
674 if (clcfp == NULL) { | |
485 | 675 return NGX_CONF_ERROR; |
676 } | |
677 | |
678 *clcfp = clcf; | |
679 | |
680 | |
501 | 681 if (ngx_http_rewrite_if_condition(cf, lcf) != NGX_CONF_OK) { |
485 | 682 return NGX_CONF_ERROR; |
683 } | |
684 | |
509 | 685 if_code = ngx_array_push_n(lcf->codes, sizeof(ngx_http_script_if_code_t)); |
485 | 686 if (if_code == NULL) { |
687 return NULL; | |
688 } | |
689 | |
509 | 690 if_code->code = ngx_http_script_if_code; |
485 | 691 |
692 elts = lcf->codes->elts; | |
693 | |
694 | |
695 /* the inside directives must compile to the same code array */ | |
696 | |
697 nlcf = ctx->loc_conf[ngx_http_rewrite_module.ctx_index]; | |
698 nlcf->codes = lcf->codes; | |
699 | |
700 | |
701 save = *cf; | |
702 cf->ctx = ctx; | |
703 | |
704 if (pclcf->name.len == 0) { | |
705 if_code->loc_conf = NULL; | |
706 cf->cmd_type = NGX_HTTP_SIF_CONF; | |
707 | |
708 } else { | |
709 if_code->loc_conf = ctx->loc_conf; | |
710 cf->cmd_type = NGX_HTTP_LIF_CONF; | |
711 } | |
712 | |
713 rv = ngx_conf_parse(cf, NULL); | |
714 | |
715 *cf = save; | |
716 | |
717 if (rv != NGX_CONF_OK) { | |
718 return rv; | |
719 } | |
720 | |
721 | |
722 if (elts != lcf->codes->elts) { | |
509 | 723 if_code = (ngx_http_script_if_code_t *) |
485 | 724 ((u_char *) if_code + ((u_char *) lcf->codes->elts - elts)); |
725 } | |
726 | |
727 if_code->next = (u_char *) lcf->codes->elts + lcf->codes->nelts | |
728 - (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
|
729 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
730 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
|
731 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
732 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
733 |
487 | 734 static char * |
501 | 735 ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf) |
736 { | |
509 | 737 ngx_str_t *value, err; |
738 ngx_uint_t cur, last; | |
739 ngx_http_script_regex_code_t *regex; | |
740 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
501 | 741 |
742 value = cf->args->elts; | |
743 last = cf->args->nelts - 1; | |
744 | |
745 if (value[1].len < 1 || value[1].data[0] != '(') { | |
746 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
747 "invalid condition \"%V\"", &value[1]); | |
748 return NGX_CONF_ERROR; | |
749 } | |
750 | |
751 if (value[1].len == 1) { | |
752 cur = 2; | |
753 | |
754 } else { | |
755 cur = 1; | |
756 value[1].len--; | |
757 value[1].data++; | |
758 } | |
759 | |
760 if (value[last].len < 1 || value[last].data[value[last].len - 1] != ')') { | |
761 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
762 "invalid condition \"%V\"", &value[last]); | |
763 return NGX_CONF_ERROR; | |
764 } | |
765 | |
766 if (value[last].len == 1) { | |
767 last--; | |
768 | |
769 } else { | |
770 value[last].len--; | |
771 value[last].data[value[last].len] = '\0'; | |
772 } | |
773 | |
774 if (value[cur].len > 1 && value[cur].data[0] == '$') { | |
775 | |
776 if (cur != last && cur + 2 != last) { | |
777 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
778 "invalid condition \"%V\"", &value[cur]); | |
779 return NGX_CONF_ERROR; | |
780 } | |
781 | |
782 if (ngx_http_rewrite_variable(cf, lcf, &value[cur])!= NGX_CONF_OK) { | |
783 return NGX_CONF_ERROR; | |
784 } | |
785 | |
786 if (cur == last) { | |
787 return NGX_CONF_OK; | |
788 } | |
789 | |
790 cur++; | |
791 | |
792 if ((value[cur].len == 1 && value[cur].data[0] != '~') | |
793 || (value[cur].len == 2 | |
794 && value[cur].data[0] != '~' && value[cur].data[1] != '*')) | |
795 { | |
796 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
797 "unexpected \"%V\" in condition", &value[cur]); | |
798 return NGX_CONF_ERROR; | |
799 } | |
800 | |
509 | 801 regex = ngx_http_script_start_code(cf->pool, &lcf->codes, |
802 sizeof(ngx_http_script_regex_code_t)); | |
501 | 803 if (regex == NULL) { |
804 return NGX_CONF_ERROR; | |
805 } | |
806 | |
509 | 807 ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t)); |
808 | |
501 | 809 err.len = NGX_MAX_CONF_ERRSTR; |
810 err.data = errstr; | |
811 | |
812 regex->regex = ngx_regex_compile(&value[last], | |
813 (value[cur].len == 2) ? NGX_REGEX_CASELESS : 0, | |
814 cf->pool, &err); | |
815 | |
816 if (regex->regex == NULL) { | |
817 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | |
818 return NGX_CONF_ERROR; | |
819 } | |
820 | |
509 | 821 regex->code = ngx_http_script_regex_start_code; |
822 regex->next = sizeof(ngx_http_script_regex_code_t); | |
501 | 823 regex->test = 1; |
824 regex->name = value[last]; | |
825 | |
826 return NGX_CONF_OK; | |
827 } | |
828 | |
829 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
830 "invalid condition \"%V\"", &value[cur]); | |
831 | |
832 return NGX_CONF_ERROR; | |
833 } | |
834 | |
835 | |
836 static char * | |
837 ngx_http_rewrite_variable(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf, | |
838 ngx_str_t *value) | |
839 { | |
509 | 840 ngx_int_t index; |
841 ngx_http_script_code_pt *code; | |
842 ngx_http_script_var_code_t *var_code; | |
501 | 843 |
844 value->len--; | |
845 value->data++; | |
846 | |
847 if (value->len == sizeof("invalid_referer") - 1 | |
848 && ngx_strncmp(value->data, "invalid_referer", | |
849 sizeof("invalid_referer") - 1) == 0) | |
850 { | |
509 | 851 code = ngx_http_script_start_code(cf->pool, &lcf->codes, |
852 sizeof(ngx_http_script_code_pt)); | |
501 | 853 if (code == NULL) { |
854 return NGX_CONF_ERROR; | |
855 } | |
856 | |
857 *code = ngx_http_rewrite_invalid_referer_code; | |
858 | |
859 } else { | |
509 | 860 index = ngx_http_get_variable_index(cf, value); |
501 | 861 |
509 | 862 if (index == NGX_ERROR) { |
501 | 863 return NGX_CONF_ERROR; |
864 } | |
865 | |
509 | 866 var_code = ngx_http_script_start_code(cf->pool, &lcf->codes, |
867 sizeof(ngx_http_script_var_code_t)); | |
501 | 868 if (var_code == NULL) { |
869 return NGX_CONF_ERROR; | |
870 } | |
871 | |
509 | 872 var_code->code = ngx_http_script_var_code; |
873 var_code->index = index; | |
501 | 874 } |
875 | |
876 return NGX_CONF_OK; | |
877 } | |
878 | |
879 | |
880 static char * | |
487 | 881 ngx_http_rewrite_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
882 { |
485 | 883 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
|
884 |
485 | 885 ngx_uint_t i, server_names; |
886 ngx_str_t *value; | |
887 ngx_http_server_name_t *sn; | |
888 ngx_http_core_srv_conf_t *cscf; | |
889 ngx_http_rewrite_referer_t *ref; | |
890 | |
891 cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module); | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
892 |
485 | 893 if (lcf->referers == NULL) { |
894 lcf->referers = ngx_array_create(cf->pool, | |
895 cf->args->nelts + cscf->server_names.nelts, | |
896 sizeof(ngx_http_rewrite_referer_t)); | |
897 if (lcf->referers == NULL) { | |
898 return NGX_CONF_ERROR; | |
899 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
900 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
901 |
485 | 902 value = cf->args->elts; |
903 server_names = 0; | |
904 | |
905 for (i = 1; i < cf->args->nelts; i++) { | |
906 if (value[i].len == 0) { | |
907 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
908 "invalid referer \"%V\"", &value[i]); | |
909 return NGX_CONF_ERROR; | |
910 } | |
911 | |
912 if (ngx_strcmp(value[i].data, "none") == 0) { | |
913 lcf->no_referer = 1; | |
914 continue; | |
915 } | |
916 | |
505 | 917 if (ngx_strcmp(value[i].data, "blocked") == 0) { |
918 lcf->blocked_referer = 1; | |
919 continue; | |
920 } | |
921 | |
485 | 922 if (ngx_strcmp(value[i].data, "server_names") == 0) { |
923 server_names = 1; | |
924 continue; | |
925 } | |
926 | |
501 | 927 ref = ngx_array_push(lcf->referers); |
928 if (ref == NULL) { | |
485 | 929 return NGX_CONF_ERROR; |
930 } | |
931 | |
932 if (value[i].data[0] != '*') { | |
933 ref->name = value[i]; | |
934 ref->wildcard = 0; | |
935 continue; | |
936 } | |
937 | |
938 if (value[i].data[1] != '.') { | |
939 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
940 "invalid wildcard referer \"%V\"", &value[i]); | |
941 return NGX_CONF_ERROR; | |
942 } | |
943 | |
944 ref->name.len = value[i].len - 1; | |
945 ref->name.data = value[i].data + 1; | |
946 ref->wildcard = 1; | |
947 } | |
948 | |
949 if (!server_names) { | |
950 return NGX_CONF_OK; | |
951 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
952 |
485 | 953 sn = cscf->server_names.elts; |
954 for (i = 0; i < cscf->server_names.nelts; i++) { | |
501 | 955 ref = ngx_array_push(lcf->referers); |
956 if (ref == NULL) { | |
485 | 957 return NGX_CONF_ERROR; |
958 } | |
959 | |
960 ref->name.len = sn[i].name.len + 1; | |
501 | 961 ref->name.data = ngx_palloc(cf->pool, ref->name.len); |
962 if (ref->name.data == NULL) { | |
485 | 963 return NGX_CONF_ERROR; |
964 } | |
965 | |
966 ngx_memcpy(ref->name.data, sn[i].name.data, sn[i].name.len); | |
967 ref->name.data[sn[i].name.len] = '/'; | |
968 ref->wildcard = sn[i].wildcard; | |
969 } | |
970 | |
971 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
|
972 } |
485 | 973 |
974 | |
501 | 975 static char * |
976 ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
977 { | |
978 ngx_http_rewrite_loc_conf_t *lcf = conf; | |
979 | |
509 | 980 ngx_int_t n, index; |
981 ngx_str_t *value; | |
982 ngx_http_variable_t *v; | |
983 ngx_http_script_var_code_t *var; | |
984 ngx_http_script_value_code_t *val; | |
501 | 985 |
986 value = cf->args->elts; | |
987 | |
988 if (value[1].data[0] != '$') { | |
989 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
990 "invalid variable name \"%V\"", &value[1]); | |
991 return NGX_CONF_ERROR; | |
992 } | |
993 | |
994 value[1].len--; | |
995 value[1].data++; | |
996 | |
509 | 997 v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGABLE); |
501 | 998 if (v == NULL) { |
999 return NGX_CONF_ERROR; | |
1000 } | |
1001 | |
509 | 1002 index = ngx_http_get_variable_index(cf, &value[1]); |
1003 if (index == NGX_ERROR) { | |
1004 return NGX_CONF_ERROR; | |
1005 } | |
501 | 1006 |
509 | 1007 v->handler = ngx_http_rewrite_var; |
1008 v->data = index; | |
1009 | |
1010 val = ngx_http_script_start_code(cf->pool, &lcf->codes, | |
1011 sizeof(ngx_http_script_value_code_t)); | |
501 | 1012 if (val == NULL) { |
1013 return NGX_CONF_ERROR; | |
1014 } | |
1015 | |
1016 n = ngx_atoi(value[2].data, value[2].len); | |
1017 | |
1018 if (n == NGX_ERROR) { | |
1019 n = 0; | |
1020 } | |
1021 | |
509 | 1022 val->code = ngx_http_script_value_code; |
501 | 1023 val->value = (uintptr_t) n; |
1024 val->text_len = (uintptr_t) value[2].len; | |
1025 val->text_data = (uintptr_t) value[2].data; | |
1026 | |
509 | 1027 var = ngx_http_script_start_code(cf->pool, &lcf->codes, |
1028 sizeof(ngx_http_script_var_code_t)); | |
501 | 1029 if (var == NULL) { |
1030 return NGX_CONF_ERROR; | |
1031 } | |
1032 | |
509 | 1033 var->code = ngx_http_script_set_var_code; |
1034 var->index = (uintptr_t) index; | |
501 | 1035 |
1036 return NGX_CONF_OK; | |
1037 } |