Mercurial > hg > nginx
annotate src/http/modules/ngx_http_rewrite_handler.c @ 485:4ebe09b07e30 release-0.1.17
nginx-0.1.17-RELEASE import
*) Change: the ngx_http_rewrite_module was rewritten from the scratch.
Now it is possible to redirect, to return the error codes, to check
the variables and referrers. The directives can be used inside
locations. The redirect directive was canceled.
*) Feature: the ngx_http_geo_module.
*) Feature: the proxy_set_x_var and fastcgi_set_var directives.
*) Bugfix: the location configuration with "=" modifier may be used in
another location.
*) Bugfix: the correct content type was set only for requests that use
small caps letters in extension.
*) Bugfix: if the proxy_pass or fastcgi_pass directives were set in the
location, and access was denied, and the error was redirected to a
static page, then the segmentation fault occurred.
*) Bugfix: if in a proxied "Location" header was a relative URL, then a
host name and a slash were added to them; the bug had appeared in
0.1.14.
*) Bugfix: the system error message was not logged on Linux.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 03 Feb 2005 19:33:37 +0000 |
parents | 621229427cba |
children | 31ff3e943e16 |
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 ngx_http_rewrite_engine_s ngx_http_rewrite_engine_t; |
13 | |
14 typedef void (*ngx_http_rewrite_code_pt) (ngx_http_rewrite_engine_t *e); | |
15 | |
16 | |
17 typedef struct { | |
18 ngx_str_t name; | |
19 ngx_uint_t wildcard; | |
20 } ngx_http_rewrite_referer_t; | |
21 | |
22 | |
23 typedef struct { | |
24 ngx_array_t *codes; /* uintptr_t */ | |
25 ngx_array_t *referers; /* ngx_http_rewrite_referer_t */ | |
26 | |
27 ngx_uint_t max_captures; | |
28 ngx_uint_t stack_size; | |
29 | |
30 ngx_flag_t log; | |
31 | |
32 ngx_flag_t no_referer; | |
33 } 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
|
34 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
35 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
36 typedef struct { |
485 | 37 ngx_http_rewrite_code_pt code; |
38 ngx_regex_t *regex; | |
39 uintptr_t size; | |
40 uintptr_t ncaptures; | |
41 uintptr_t status; | |
42 uintptr_t next; | |
43 | |
44 uintptr_t uri:1; | |
45 | |
46 /* add the r->args to the new arguments */ | |
47 uintptr_t args:1; | |
48 | |
49 uintptr_t redirect:1; | |
50 | |
51 ngx_str_t name; | |
52 } ngx_http_rewrite_regex_code_t; | |
53 | |
54 | |
55 typedef struct { | |
56 ngx_http_rewrite_code_pt code; | |
57 | |
58 uintptr_t uri:1; | |
59 | |
60 /* add the r->args to the new arguments */ | |
61 uintptr_t args:1; | |
62 | |
63 uintptr_t redirect:1; | |
64 } ngx_http_rewrite_regex_end_code_t; | |
65 | |
66 typedef struct { | |
67 ngx_http_rewrite_code_pt code; | |
68 uintptr_t n; | |
69 } ngx_http_rewrite_copy_capture_code_t; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
70 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
71 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
72 typedef struct { |
485 | 73 ngx_http_rewrite_code_pt code; |
74 uintptr_t len; | |
75 } ngx_http_rewrite_copy_code_t; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
76 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
77 |
485 | 78 typedef struct { |
79 ngx_http_rewrite_code_pt code; | |
80 uintptr_t status; | |
81 uintptr_t null; | |
82 } ngx_http_rewrite_return_code_t; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
83 |
485 | 84 |
85 typedef struct { | |
86 ngx_http_rewrite_code_pt code; | |
87 uintptr_t next; | |
88 void **loc_conf; | |
89 } ngx_http_rewrite_if_code_t; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
90 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
91 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
92 typedef struct { |
485 | 93 ngx_http_rewrite_code_pt code; |
94 uintptr_t index; | |
95 } ngx_http_rewrite_var_code_t; | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
96 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
97 |
485 | 98 struct ngx_http_rewrite_engine_s { |
99 u_char *ip; | |
100 uintptr_t *sp; | |
101 | |
102 ngx_str_t buf; | |
103 ngx_str_t *line; | |
104 | |
105 u_char *pos; | |
106 | |
107 /* the start of the rewritten arguments */ | |
108 u_char *args; | |
109 | |
110 unsigned quote:1; | |
111 | |
112 ngx_int_t status; | |
113 | |
114 int *captures; | |
115 | |
116 ngx_http_request_t *request; | |
117 ngx_http_rewrite_loc_conf_t *conf; | |
118 }; | |
216
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 |
485 | 121 static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle); |
122 static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf); | |
123 static char *ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, | |
124 void *parent, void *child); | |
125 static char *ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
126 static char *ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, | |
127 void *conf); | |
128 static char *ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, | |
129 void *conf); | |
130 static char *ngx_http_rewrite_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, | |
131 void *conf); | |
132 static void *ngx_http_rewrite_start_code(ngx_pool_t *pool, | |
133 ngx_array_t **codes, size_t size); | |
134 static void *ngx_http_rewrite_add_code(ngx_array_t *codes, size_t size, | |
135 u_char **main); | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
136 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
137 |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
138 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
|
139 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
140 { ngx_string("rewrite"), |
485 | 141 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |
142 |NGX_CONF_TAKE23, | |
143 ngx_http_rewrite, | |
144 NGX_HTTP_LOC_CONF_OFFSET, | |
145 0, | |
146 NULL }, | |
147 | |
148 { ngx_string("return"), | |
149 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF | |
150 |NGX_CONF_TAKE1, | |
151 ngx_http_rewrite_return, | |
152 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
|
153 0, |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
154 NULL }, |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
155 |
485 | 156 { ngx_string("if"), |
157 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE, | |
158 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
|
159 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
|
160 0, |
485 | 161 NULL }, |
162 | |
163 { ngx_string("valid_referers"), | |
164 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
165 ngx_http_rewrite_valid_referers, | |
166 NGX_HTTP_LOC_CONF_OFFSET, | |
167 0, | |
168 NULL }, | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
169 |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
170 { ngx_string("rewrite_log"), |
485 | 171 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |
172 |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
|
173 ngx_conf_set_flag_slot, |
485 | 174 NGX_HTTP_LOC_CONF_OFFSET, |
175 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
|
176 NULL }, |
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
177 |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
178 ngx_null_command |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
179 }; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
180 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
181 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
182 ngx_http_module_t ngx_http_rewrite_module_ctx = { |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
183 NULL, /* pre conf */ |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
184 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
185 NULL, /* create main configuration */ |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
186 NULL, /* init main configuration */ |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
187 |
485 | 188 NULL, /* create server configuration */ |
189 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
|
190 |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
191 ngx_http_rewrite_create_loc_conf, /* create location configration */ |
485 | 192 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
|
193 }; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
194 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
195 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
196 ngx_module_t ngx_http_rewrite_module = { |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
197 NGX_MODULE, |
485 | 198 &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
|
199 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
|
200 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
|
201 ngx_http_rewrite_init, /* init module */ |
485 | 202 NULL /* init process */ |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
203 }; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
204 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
205 |
485 | 206 #define ngx_http_rewrite_exit (u_char *) &ngx_http_rewrite_exit_code |
207 | |
208 uintptr_t ngx_http_rewrite_exit_code = (uintptr_t) NULL; | |
209 | |
210 | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
211 static ngx_int_t ngx_http_rewrite_handler(ngx_http_request_t *r) |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
212 { |
485 | 213 ngx_http_rewrite_code_pt code; |
214 ngx_http_rewrite_engine_t *e; | |
215 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
|
216 |
485 | 217 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
|
218 |
485 | 219 if (cf->codes == NULL) { |
220 return NGX_DECLINED; | |
221 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
222 |
485 | 223 if (!(e = ngx_palloc(r->pool, sizeof(ngx_http_rewrite_engine_t)))) { |
224 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
225 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
226 |
485 | 227 e->sp = ngx_palloc(r->pool, cf->stack_size * sizeof(ngx_int_t)); |
228 if (e->sp == NULL) { | |
229 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
230 } | |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
231 |
485 | 232 if (cf->max_captures) { |
233 e->captures = ngx_palloc(r->pool, cf->max_captures * sizeof(int)); | |
234 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
|
235 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
|
236 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
237 |
485 | 238 } else { |
239 e->captures = NULL; | |
240 } | |
241 | |
242 e->ip = cf->codes->elts; | |
243 e->buf.len = 0; | |
244 e->buf.data = NULL; | |
245 e->line = NULL; | |
246 e->pos = NULL; | |
247 e->args = NULL; | |
248 e->quote = 1; | |
249 e->status = NGX_DECLINED; | |
250 e->request = r; | |
251 e->conf = cf; | |
252 | |
253 while (*(uintptr_t *) e->ip) { | |
254 code = *(ngx_http_rewrite_code_pt *) e->ip; | |
255 code(e); | |
256 } | |
257 | |
258 return e->status; | |
259 } | |
260 | |
261 | |
262 static void ngx_http_rewrite_regex_start_code(ngx_http_rewrite_engine_t *e) | |
263 { | |
264 ngx_int_t rc; | |
265 ngx_uint_t n; | |
266 ngx_http_request_t *r; | |
267 ngx_http_rewrite_regex_code_t *code; | |
268 | |
269 code = (ngx_http_rewrite_regex_code_t *) e->ip; | |
270 | |
271 r = e->request; | |
272 | |
273 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
274 "http rewrite start: \"%V\"", &code->name); | |
275 | |
276 if (code->uri) { | |
277 e->line = &r->uri; | |
278 } else { | |
279 e->line = *(ngx_str_t **) e->sp--; | |
280 } | |
281 | |
282 rc = ngx_regex_exec(code->regex, e->line, e->captures, code->ncaptures); | |
283 | |
284 if (rc == NGX_REGEX_NO_MATCHED) { | |
285 if (e->conf->log) { | |
286 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, | |
287 "\"%V\" does not match \"%V\"", &code->name, e->line); | |
288 } | |
289 | |
290 e->ip += code->next; | |
291 return; | |
292 } | |
293 | |
294 if (rc < 0) { | |
295 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | |
296 ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"", | |
297 rc, e->line, &code->name); | |
298 | |
299 e->ip = ngx_http_rewrite_exit; | |
300 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
301 return; | |
302 } | |
303 | |
304 if (e->conf->log) { | |
305 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, | |
306 "\"%V\" matches \"%V\"", &code->name, e->line); | |
307 } | |
308 | |
309 if (code->status) { | |
310 e->status = code->status; | |
311 | |
312 if (!code->redirect) { | |
313 e->ip = ngx_http_rewrite_exit; | |
314 return; | |
315 } | |
316 } | |
317 | |
318 e->buf.len = code->size; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
319 |
485 | 320 if (code->uri) { |
321 r->uri_changed = 1; | |
322 | |
323 if (rc && (r->quoted_uri || r->plus_in_uri)) { | |
324 e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len, | |
325 NGX_ESCAPE_ARGS); | |
326 } | |
327 } | |
328 | |
329 for (n = 1; n < (ngx_uint_t) rc; n++) { | |
330 e->buf.len += e->captures[2 * n + 1] - e->captures[2 * n]; | |
331 } | |
332 | |
333 if (code->args && r->args.len) { | |
334 e->buf.len += r->args.len + 1; | |
335 } | |
336 | |
337 if (!(e->buf.data = ngx_palloc(r->pool, e->buf.len))) { | |
338 e->ip = ngx_http_rewrite_exit; | |
339 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
340 return; | |
341 } | |
342 | |
343 e->quote = code->redirect; | |
344 | |
345 e->pos = e->buf.data; | |
346 | |
347 e->ip += sizeof(ngx_http_rewrite_regex_code_t); | |
348 } | |
349 | |
350 | |
351 static void ngx_http_rewrite_regex_end_code(ngx_http_rewrite_engine_t *e) | |
352 { | |
353 ngx_http_request_t *r; | |
354 ngx_http_rewrite_regex_end_code_t *code; | |
355 | |
356 code = (ngx_http_rewrite_regex_end_code_t *) e->ip; | |
357 | |
358 r = e->request; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
359 |
485 | 360 e->quote = 0; |
361 | |
362 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
363 "http rewrite end"); | |
364 | |
365 if (e->args) { | |
366 e->buf.len = e->args - e->buf.data; | |
367 | |
368 if (code->args && r->args.len) { | |
369 *e->pos++ = '&'; | |
370 e->pos = ngx_cpymem(e->pos, r->args.data, r->args.len); | |
371 } | |
372 | |
373 r->args.len = e->pos - e->args; | |
374 r->args.data = e->args; | |
375 | |
376 e->args = NULL; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
377 |
485 | 378 } else { |
379 if (code->args && r->args.len) { | |
380 *e->pos++ = '&'; | |
381 e->pos = ngx_cpymem(e->pos, r->args.data, r->args.len); | |
382 } | |
383 | |
384 e->buf.len = e->pos - e->buf.data; | |
385 } | |
483 | 386 |
485 | 387 if (!code->redirect) { |
388 if (e->conf->log) { | |
389 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, | |
390 "rewritten data: \"%V\", args: \"%V\"", | |
391 &e->buf, &r->args); | |
392 } | |
393 | |
394 if (code->uri) { | |
395 r->uri = e->buf; | |
396 | |
397 if (ngx_http_set_exten(r) != NGX_OK) { | |
398 e->ip = ngx_http_rewrite_exit; | |
399 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
400 return; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
401 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
402 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
403 |
485 | 404 e->ip += sizeof(ngx_http_rewrite_regex_end_code_t); |
405 return; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
406 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
407 |
485 | 408 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, |
409 "rewritten redirect: \"%V\"", &e->buf); | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
410 |
485 | 411 if (!(r->headers_out.location = ngx_list_push(&r->headers_out.headers))) { |
412 e->ip = ngx_http_rewrite_exit; | |
413 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
414 return; | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
415 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
416 |
485 | 417 if (e->buf.data[0] != '/') { |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
418 r->headers_out.location->key.len = sizeof("Location") - 1; |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
419 r->headers_out.location->key.data = (u_char *) "Location"; |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
420 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
421 |
485 | 422 r->headers_out.location->value = e->buf; |
423 | |
424 e->ip += sizeof(ngx_http_rewrite_regex_end_code_t); | |
425 } | |
426 | |
427 | |
428 static void ngx_http_rewrite_copy_capture_code(ngx_http_rewrite_engine_t *e) | |
429 { | |
430 ngx_http_rewrite_copy_capture_code_t *code; | |
431 | |
432 code = (ngx_http_rewrite_copy_capture_code_t *) e->ip; | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
433 |
485 | 434 e->ip += sizeof(ngx_http_rewrite_copy_capture_code_t); |
435 | |
436 if ((e->args || e->quote) | |
437 && (e->request->quoted_uri || e->request->plus_in_uri)) | |
438 { | |
439 e->pos = (u_char *) ngx_escape_uri(e->pos, | |
440 &e->line->data[e->captures[code->n]], | |
441 e->captures[code->n + 1] - e->captures[code->n], | |
442 NGX_ESCAPE_ARGS); | |
443 } else { | |
444 e->pos = ngx_cpymem(e->pos, &e->line->data[e->captures[code->n]], | |
445 e->captures[code->n + 1] - e->captures[code->n]); | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
446 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
447 |
485 | 448 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, |
449 "http rewrite capture: \"%V\"", &e->buf); | |
450 } | |
451 | |
452 | |
453 static void ngx_http_rewrite_copy_code(ngx_http_rewrite_engine_t *e) | |
454 { | |
455 ngx_http_rewrite_copy_code_t *code; | |
456 | |
457 code = (ngx_http_rewrite_copy_code_t *) e->ip; | |
458 | |
459 e->pos = ngx_cpymem(e->pos, e->ip + sizeof(ngx_http_rewrite_copy_code_t), | |
460 code->len); | |
461 | |
462 e->ip += sizeof(ngx_http_rewrite_copy_code_t) | |
463 + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1)); | |
464 | |
465 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
466 "http rewrite copy: \"%V\"", &e->buf); | |
467 } | |
468 | |
469 | |
470 static void ngx_http_rewrite_start_args_code(ngx_http_rewrite_engine_t *e) | |
471 { | |
472 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
473 "http rewrite args"); | |
474 | |
475 e->args = e->pos; | |
476 e->ip += sizeof(uintptr_t); | |
477 } | |
478 | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
479 |
485 | 480 static void ngx_http_rewrite_return_code(ngx_http_rewrite_engine_t *e) |
481 { | |
482 ngx_http_rewrite_return_code_t *code; | |
483 | |
484 code = (ngx_http_rewrite_return_code_t *) e->ip; | |
485 | |
486 e->status = code->status; | |
487 | |
488 e->ip += sizeof(ngx_http_rewrite_return_code_t) - sizeof(uintptr_t); | |
489 } | |
490 | |
491 | |
492 static void ngx_http_rewrite_if_code(ngx_http_rewrite_engine_t *e) | |
493 { | |
494 ngx_http_rewrite_if_code_t *code; | |
495 | |
496 code = (ngx_http_rewrite_if_code_t *) e->ip; | |
497 | |
498 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
499 "http rewrite if"); | |
500 | |
501 if (*e->sp--) { | |
502 if (code->loc_conf) { | |
503 e->request->loc_conf = code->loc_conf; | |
504 } | |
505 | |
506 e->ip += sizeof(ngx_http_rewrite_if_code_t); | |
507 return; | |
508 } | |
509 | |
510 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
511 "http rewrite if false"); | |
512 | |
513 e->ip += code->next; | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
514 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
515 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
516 |
485 | 517 static void ngx_http_rewrite_var_code(ngx_http_rewrite_engine_t *e) |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
518 { |
485 | 519 ngx_http_variable_value_t *value; |
520 ngx_http_rewrite_var_code_t *code; | |
521 | |
522 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
523 "http rewrite var"); | |
524 | |
525 code = (ngx_http_rewrite_var_code_t *) e->ip; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
526 |
485 | 527 e->sp++; |
528 | |
529 e->ip += sizeof(ngx_http_rewrite_var_code_t); | |
530 | |
531 if (!(value = ngx_http_get_variable(e->request, code->index))) { | |
532 *e->sp = (uintptr_t) 0; | |
533 return; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
534 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
535 |
485 | 536 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, |
537 "http rewrite var: %p", value->value); | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
538 |
485 | 539 *e->sp = value->value; |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
540 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
541 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
542 |
485 | 543 static void ngx_http_rewrite_invalid_referer_code(ngx_http_rewrite_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
|
544 { |
485 | 545 u_char *ref; |
546 size_t len; | |
547 ngx_uint_t i, n; | |
548 ngx_http_request_t *r; | |
549 ngx_http_rewrite_referer_t *refs; | |
550 ngx_http_rewrite_loc_conf_t *cf; | |
551 | |
552 r = e->request; | |
553 | |
554 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
555 "http rewrite invalid referer"); | |
556 | |
557 cf = ngx_http_get_module_loc_conf(r, ngx_http_rewrite_module); | |
558 | |
559 e->sp++; | |
560 e->ip += sizeof(uintptr_t); | |
561 | |
562 if (cf->referers == NULL) { | |
563 *e->sp = (uintptr_t) 0; | |
564 return; | |
565 } | |
566 | |
567 if (r->headers_in.referer == NULL) { | |
568 if (cf->no_referer) { | |
569 *e->sp = (uintptr_t) 0; | |
570 return; | |
571 } else { | |
572 *e->sp = (uintptr_t) 1; | |
573 return; | |
574 } | |
575 } | |
576 | |
577 len = r->headers_in.referer->value.len; | |
578 ref = r->headers_in.referer->value.data; | |
579 | |
580 if (len < sizeof("http://i.ru") - 1 | |
581 || (ngx_strncasecmp(ref, "http://", 7) != 0)) | |
582 { | |
583 *e->sp = (uintptr_t) 1; | |
584 return; | |
585 } | |
586 | |
587 len -= 7; | |
588 ref += 7; | |
589 | |
590 refs = cf->referers->elts; | |
591 for (i = 0; i < cf->referers->nelts; i++ ){ | |
592 | |
593 if (refs[i].name.len > len) { | |
594 continue; | |
595 } | |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
596 |
485 | 597 if (refs[i].wildcard) { |
598 for (n = 0; n < len; n++) { | |
599 if (ref[n] == '/' || ref[n] == ':') { | |
600 break; | |
601 } | |
602 | |
603 if (ref[n] != '.') { | |
604 continue; | |
605 } | |
606 | |
607 if (ngx_strncmp(&ref[n], refs[i].name.data, | |
608 refs[i].name.len) == 0) | |
609 { | |
610 *e->sp = (uintptr_t) 0; | |
611 return; | |
612 } | |
613 } | |
614 | |
615 } else { | |
616 if (ngx_strncasecmp(refs[i].name.data, ref, refs[i].name.len) == 0) | |
617 { | |
618 *e->sp = (uintptr_t) 0; | |
619 return; | |
620 } | |
621 } | |
622 } | |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
623 |
485 | 624 *e->sp = (uintptr_t) 1; |
625 } | |
626 | |
627 | |
628 static void ngx_http_rewrite_nop_code(ngx_http_rewrite_engine_t *e) | |
629 { | |
630 e->ip += sizeof(uintptr_t); | |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
631 } |
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
632 |
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
633 |
485 | 634 static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle) |
635 { | |
636 ngx_http_handler_pt *h; | |
637 ngx_http_core_main_conf_t *cmcf; | |
638 | |
639 cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); | |
640 | |
641 h = ngx_push_array(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers); | |
642 if (h == NULL) { | |
643 return NGX_ERROR; | |
644 } | |
645 | |
646 *h = ngx_http_rewrite_handler; | |
647 | |
648 return NGX_OK; | |
649 } | |
650 | |
651 | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
652 static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf) |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
653 { |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
654 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
|
655 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
656 if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_rewrite_loc_conf_t)))) { |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
657 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
|
658 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
659 |
485 | 660 conf->stack_size = NGX_CONF_UNSET_UINT; |
661 conf->log = NGX_CONF_UNSET; | |
662 conf->no_referer = NGX_CONF_UNSET; | |
663 | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
664 return conf; |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
665 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
666 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
667 |
485 | 668 static char *ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, |
669 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
|
670 { |
485 | 671 ngx_http_rewrite_loc_conf_t *prev = parent; |
672 ngx_http_rewrite_loc_conf_t *conf = child; | |
673 | |
674 uintptr_t *code, *last; | |
675 ngx_http_rewrite_regex_code_t *regex; | |
676 | |
677 ngx_conf_merge_value(conf->log, prev->log, 0); | |
678 ngx_conf_merge_unsigned_value(conf->stack_size, prev->stack_size, 10); | |
679 | |
680 if (conf->referers == NULL) { | |
681 conf->referers = prev->referers; | |
682 ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0); | |
683 } | |
684 | |
685 if (conf->codes == NULL) { | |
686 return NGX_CONF_OK; | |
687 } | |
688 | |
689 if (conf->codes == prev->codes) { | |
690 return NGX_CONF_OK; | |
691 } | |
692 | |
693 code = conf->codes->elts; | |
694 last = (uintptr_t *) ((u_char *) code + conf->codes->nelts); | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
695 |
485 | 696 while (code < last) { |
697 if (*code == (uintptr_t) NULL) { | |
698 return NGX_CONF_OK; | |
699 } | |
700 | |
701 if (*code == (uintptr_t) &ngx_http_rewrite_regex_start_code) { | |
702 regex = (ngx_http_rewrite_regex_code_t *) code; | |
703 if (conf->max_captures < regex->ncaptures) { | |
704 conf->max_captures = regex->ncaptures; | |
705 } | |
706 code = (uintptr_t *) ((u_char *) code + regex->next); | |
707 } | |
708 | |
709 if (*code == (uintptr_t) &ngx_http_rewrite_if_code) { | |
710 code += sizeof(ngx_http_rewrite_if_code_t) / sizeof(uintptr_t); | |
711 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
712 |
485 | 713 if (*code == (uintptr_t) &ngx_http_rewrite_return_code) { |
714 code += sizeof(ngx_http_rewrite_return_code_t) / sizeof(uintptr_t); | |
715 } | |
716 | |
717 if (*code == (uintptr_t) &ngx_http_rewrite_var_code) { | |
718 code += sizeof(ngx_http_rewrite_var_code_t) / sizeof(uintptr_t); | |
719 } | |
720 | |
721 if (*code == (uintptr_t) &ngx_http_rewrite_invalid_referer_code) { | |
722 code++; | |
723 } | |
724 | |
725 if (*code == (uintptr_t) &ngx_http_rewrite_nop_code) { | |
726 code++; | |
727 } | |
728 } | |
729 | |
730 if (!(code = ngx_array_push_n(conf->codes, sizeof(uintptr_t)))) { | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
731 return NGX_CONF_ERROR; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
732 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
733 |
485 | 734 *code = (uintptr_t) NULL; |
735 | |
736 return NGX_CONF_OK; | |
737 } | |
738 | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
739 |
485 | 740 static char *ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
741 { | |
742 ngx_http_rewrite_loc_conf_t *lcf = conf; | |
743 | |
744 u_char *data; | |
745 size_t len, size; | |
746 ngx_str_t *value, err; | |
747 ngx_uint_t i, n, last; | |
748 ngx_http_rewrite_code_pt *code; | |
749 ngx_http_rewrite_copy_code_t *copy; | |
750 ngx_http_rewrite_regex_code_t *regex; | |
751 ngx_http_rewrite_regex_end_code_t *regex_end; | |
752 ngx_http_rewrite_copy_capture_code_t *copy_capture; | |
753 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
754 | |
755 regex = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
756 sizeof(ngx_http_rewrite_regex_code_t)); | |
757 if (regex == NULL) { | |
758 return NGX_CONF_ERROR; | |
759 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
760 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
761 value = cf->args->elts; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
762 |
485 | 763 err.len = NGX_MAX_CONF_ERRSTR; |
764 err.data = errstr; | |
765 | |
766 /* TODO: NGX_REGEX_CASELESS */ | |
767 | |
768 regex->regex = ngx_regex_compile(&value[1], 0, cf->pool, &err); | |
769 | |
770 if (regex->regex == NULL) { | |
771 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | |
772 return NGX_CONF_ERROR; | |
773 } | |
774 | |
775 regex->code = ngx_http_rewrite_regex_start_code; | |
776 regex->size = 0; | |
777 regex->ncaptures = 0; | |
778 regex->status = 0; | |
779 regex->uri = 1; | |
780 regex->args = 1; | |
781 regex->redirect = 0; | |
782 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
|
783 |
485 | 784 last = 0; |
785 | |
786 if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0) { | |
787 regex->status = NGX_HTTP_MOVED_TEMPORARILY; | |
788 regex->redirect = 1; | |
789 last = 1; | |
790 } | |
791 | |
792 if (cf->args->nelts == 4) { | |
793 if (ngx_strcmp(value[3].data, "last") == 0) { | |
794 last = 1; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
795 |
485 | 796 } else if (ngx_strcmp(value[3].data, "redirect") == 0) { |
797 regex->status = NGX_HTTP_MOVED_TEMPORARILY; | |
798 regex->redirect = 1; | |
799 last = 1; | |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
800 |
485 | 801 } else if (ngx_strcmp(value[3].data, "permanent") == 0) { |
802 regex->status = NGX_HTTP_MOVED_PERMANENTLY; | |
803 regex->redirect = 1; | |
804 last = 1; | |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
805 |
485 | 806 } else { |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
807 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
461 | 808 "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
|
809 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
|
810 } |
485 | 811 } |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
812 |
485 | 813 i = 0; |
814 | |
815 while (i < value[2].len) { | |
816 | |
817 data = &value[2].data[i]; | |
483 | 818 |
485 | 819 if (value[2].data[i] == '$' && i < value[2].len |
820 && value[2].data[i + 1] >= '1' && value[2].data[i + 1] <= '9') | |
821 { | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
822 |
485 | 823 /* the "$1" - "$9" captures */ |
824 | |
825 copy_capture = ngx_http_rewrite_add_code(lcf->codes, | |
826 sizeof(ngx_http_rewrite_copy_capture_code_t), | |
827 (u_char **) ®ex); | |
828 if (copy_capture == NULL) { | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
829 return NGX_CONF_ERROR; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
830 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
831 |
485 | 832 i++; |
833 | |
834 copy_capture->code = ngx_http_rewrite_copy_capture_code; | |
835 copy_capture->n = value[2].data[i] - '0'; | |
836 | |
837 if (regex->ncaptures < copy_capture->n) { | |
838 regex->ncaptures = copy_capture->n; | |
839 } | |
840 | |
841 copy_capture->n *= 2; | |
842 | |
843 i++; | |
844 | |
845 continue; | |
846 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
847 |
485 | 848 if (value[2].data[i] == '?') { |
849 | |
850 /* the arguments */ | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
851 |
485 | 852 if (i == value[2].len - 1) { |
853 /* the last "?" drops the original arguments */ | |
854 regex->args = 0; | |
855 break; | |
856 } | |
857 | |
858 if (!regex->redirect) { | |
859 code = ngx_http_rewrite_add_code(lcf->codes, sizeof(uintptr_t), | |
860 (u_char **) ®ex); | |
861 if (code == NULL) { | |
862 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
|
863 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
864 |
485 | 865 *code = ngx_http_rewrite_start_args_code; |
866 | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
867 i++; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
868 |
483 | 869 continue; |
870 } | |
485 | 871 } |
872 | |
873 i++; | |
874 | |
875 /* the substituion strings */ | |
876 | |
877 while (i < value[2].len && value[2].data[i] != '$') { | |
483 | 878 |
879 if (value[2].data[i] == '?') { | |
880 | |
485 | 881 if (i == value[2].len - 1) { |
882 /* | |
883 * the last "?" drops the original arguments, | |
884 * and it should not be copied to a substituion | |
885 */ | |
886 regex->args = 0; | |
887 break; | |
888 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
889 |
485 | 890 if (!regex->redirect) { |
891 break; | |
892 } | |
483 | 893 } |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
894 |
483 | 895 i++; |
485 | 896 } |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
897 |
485 | 898 len = &value[2].data[i] - data; |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
899 |
485 | 900 if (len == 0) { |
901 continue; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
902 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
903 |
485 | 904 regex->size += len; |
905 | |
906 size = (len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1); | |
481 | 907 |
485 | 908 copy = ngx_http_rewrite_add_code(lcf->codes, |
909 sizeof(ngx_http_rewrite_copy_code_t) + size, | |
910 (u_char **) ®ex); | |
911 if (copy == NULL) { | |
481 | 912 return NGX_CONF_ERROR; |
913 } | |
914 | |
485 | 915 copy->code = ngx_http_rewrite_copy_code; |
916 copy->len = len; | |
917 | |
918 ngx_memcpy((u_char *) copy + sizeof(ngx_http_rewrite_copy_code_t), | |
919 data, len); | |
920 } | |
921 | |
922 n = ngx_regex_capture_count(regex->regex); | |
923 | |
924 if (regex->ncaptures > n) { | |
925 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
926 "pattern \"%V\" has less captures " | |
927 "than referrenced in substitution \"%V\"", | |
928 &value[1], &value[2]); | |
929 return NGX_CONF_ERROR; | |
930 } | |
931 | |
932 if (regex->ncaptures < n) { | |
933 regex->ncaptures = n; | |
934 } | |
481 | 935 |
485 | 936 if (regex->ncaptures) { |
937 regex->ncaptures = (regex->ncaptures + 1) * 3; | |
938 } | |
939 | |
940 regex_end = ngx_http_rewrite_add_code(lcf->codes, | |
941 sizeof(ngx_http_rewrite_regex_end_code_t), | |
942 (u_char **) ®ex); | |
943 if (regex_end == NULL) { | |
944 return NGX_CONF_ERROR; | |
945 } | |
946 | |
947 regex_end->code = ngx_http_rewrite_regex_end_code; | |
948 regex_end->uri = regex->uri; | |
949 regex_end->args = regex->args; | |
950 regex_end->redirect = regex->redirect; | |
951 | |
952 if (last) { | |
953 code = ngx_http_rewrite_add_code(lcf->codes, sizeof(uintptr_t), | |
954 (u_char **) ®ex); | |
955 if (code == NULL) { | |
956 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
|
957 } |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
958 |
485 | 959 *code = (uintptr_t) NULL; |
960 } | |
961 | |
962 regex->next = (u_char *) lcf->codes->elts + lcf->codes->nelts | |
963 - (u_char *) regex; | |
964 | |
965 return NGX_CONF_OK; | |
966 } | |
967 | |
968 | |
969 | |
970 static char *ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, | |
971 void *conf) | |
972 { | |
973 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
|
974 |
485 | 975 ngx_str_t *value; |
976 ngx_http_rewrite_return_code_t *ret; | |
977 | |
978 ret = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
979 sizeof(ngx_http_rewrite_return_code_t)); | |
980 if (ret == NULL) { | |
981 return NGX_CONF_ERROR; | |
982 } | |
983 | |
984 value = cf->args->elts; | |
985 | |
986 ret->code = ngx_http_rewrite_return_code; | |
987 ret->null = (uintptr_t) NULL; | |
988 | |
989 ret->status = ngx_atoi(value[1].data, value[1].len); | |
990 | |
991 if (ret->status == (uintptr_t) NGX_ERROR) { | |
992 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
|
993 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
994 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
995 return NGX_CONF_OK; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
996 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
997 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
998 |
485 | 999 static char *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
|
1000 { |
485 | 1001 ngx_http_rewrite_loc_conf_t *lcf = conf; |
1002 | |
1003 void *mconf; | |
1004 char *rv; | |
1005 u_char *elts; | |
1006 ngx_str_t *value; | |
1007 ngx_uint_t i; | |
1008 ngx_conf_t save; | |
1009 ngx_http_rewrite_code_pt *code; | |
1010 ngx_http_module_t *module; | |
1011 ngx_http_conf_ctx_t *ctx, *pctx; | |
1012 ngx_http_variable_t *var; | |
1013 ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp; | |
1014 ngx_http_core_main_conf_t *cmcf; | |
1015 ngx_http_rewrite_if_code_t *if_code; | |
1016 ngx_http_rewrite_var_code_t *var_code; | |
1017 ngx_http_rewrite_loc_conf_t *nlcf; | |
1018 | |
1019 if (!(ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)))) { | |
1020 return NGX_CONF_ERROR; | |
1021 } | |
1022 | |
1023 pctx = cf->ctx; | |
1024 ctx->main_conf = pctx->main_conf; | |
1025 ctx->srv_conf = pctx->srv_conf; | |
1026 | |
1027 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); | |
1028 if (ctx->loc_conf == NULL) { | |
1029 return NGX_CONF_ERROR; | |
1030 } | |
1031 | |
1032 for (i = 0; ngx_modules[i]; i++) { | |
1033 if (ngx_modules[i]->type != NGX_HTTP_MODULE) { | |
1034 continue; | |
1035 } | |
1036 | |
1037 module = ngx_modules[i]->ctx; | |
1038 | |
1039 if (module->create_loc_conf) { | |
1040 | |
1041 if (!(mconf = module->create_loc_conf(cf))) { | |
1042 return NGX_CONF_ERROR; | |
1043 } | |
1044 | |
1045 ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf; | |
1046 } | |
1047 } | |
1048 | |
1049 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index]; | |
1050 | |
1051 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; | |
1052 clcf->loc_conf = ctx->loc_conf; | |
1053 clcf->name = pclcf->name; | |
1054 clcf->noname = 1; | |
1055 | |
1056 if (pclcf->locations.elts == NULL) { | |
1057 if (ngx_array_init(&pclcf->locations, cf->pool, 4, sizeof(void *)) | |
1058 == NGX_ERROR) | |
1059 { | |
1060 return NGX_CONF_ERROR; | |
1061 } | |
1062 } | |
1063 | |
1064 if (!(clcfp = ngx_push_array(&pclcf->locations))) { | |
1065 return NGX_CONF_ERROR; | |
1066 } | |
1067 | |
1068 *clcfp = clcf; | |
1069 | |
1070 | |
1071 /* STUB: "if ($var)" */ | |
1072 | |
1073 value = cf->args->elts; | |
1074 | |
1075 if (value[1].len < 2 | |
1076 || value[1].data[0] != '(' | |
1077 || value[1].data[1] != '$' | |
1078 || value[1].data[value[1].len - 1] != ')') | |
1079 { | |
1080 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1081 "invalid condition \"%V\"", &value[1]); | |
1082 return NGX_CONF_ERROR; | |
1083 } | |
1084 | |
1085 value[1].len -= 3; | |
1086 value[1].data += 2; | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
1087 |
485 | 1088 if (value[1].len == sizeof("invalid_referer") - 1 |
1089 && ngx_strncmp(value[1].data, "invalid_referer", | |
1090 sizeof("invalid_referer") - 1) == 0) | |
1091 { | |
1092 code = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
1093 sizeof(ngx_http_rewrite_code_pt)); | |
1094 if (code == NULL) { | |
1095 return NGX_CONF_ERROR; | |
1096 } | |
1097 | |
1098 *code = ngx_http_rewrite_invalid_referer_code; | |
1099 | |
1100 } else { | |
1101 | |
1102 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | |
1103 | |
1104 var = cmcf->variables.elts; | |
1105 for (i = 0; i < cmcf->variables.nelts; i++) { | |
1106 if (var[i].name.len != value[1].len) { | |
1107 continue; | |
1108 } | |
1109 | |
1110 if (ngx_strncasecmp(var[i].name.data, value[1].data, | |
1111 var[i].name.len) == 0) | |
1112 { | |
1113 break; | |
1114 } | |
1115 } | |
1116 | |
1117 if (i == cmcf->variables.nelts) { | |
1118 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1119 "unknown variable name \"%V\"", &value[1]); | |
1120 return NGX_CONF_ERROR; | |
1121 } | |
1122 | |
1123 var_code = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
1124 sizeof(ngx_http_rewrite_var_code_t)); | |
1125 if (var_code == NULL) { | |
1126 return NGX_CONF_ERROR; | |
1127 } | |
1128 | |
1129 var_code->code = ngx_http_rewrite_var_code; | |
1130 var_code->index = var[i].index; | |
1131 } | |
1132 | |
1133 if_code = ngx_array_push_n(lcf->codes, sizeof(ngx_http_rewrite_if_code_t)); | |
1134 if (if_code == NULL) { | |
1135 return NULL; | |
1136 } | |
1137 | |
1138 if_code->code = ngx_http_rewrite_if_code; | |
1139 | |
1140 elts = lcf->codes->elts; | |
1141 | |
1142 | |
1143 /* the inside directives must compile to the same code array */ | |
1144 | |
1145 nlcf = ctx->loc_conf[ngx_http_rewrite_module.ctx_index]; | |
1146 nlcf->codes = lcf->codes; | |
1147 | |
1148 | |
1149 save = *cf; | |
1150 cf->ctx = ctx; | |
1151 | |
1152 if (pclcf->name.len == 0) { | |
1153 if_code->loc_conf = NULL; | |
1154 cf->cmd_type = NGX_HTTP_SIF_CONF; | |
1155 | |
1156 } else { | |
1157 if_code->loc_conf = ctx->loc_conf; | |
1158 cf->cmd_type = NGX_HTTP_LIF_CONF; | |
1159 } | |
1160 | |
1161 rv = ngx_conf_parse(cf, NULL); | |
1162 | |
1163 *cf = save; | |
1164 | |
1165 if (rv != NGX_CONF_OK) { | |
1166 return rv; | |
1167 } | |
1168 | |
1169 | |
1170 if (elts != lcf->codes->elts) { | |
1171 if_code = (ngx_http_rewrite_if_code_t *) | |
1172 ((u_char *) if_code + ((u_char *) lcf->codes->elts - elts)); | |
1173 } | |
1174 | |
1175 if_code->next = (u_char *) lcf->codes->elts + lcf->codes->nelts | |
1176 - (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
|
1177 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
1178 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
|
1179 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
1180 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
1181 |
485 | 1182 static char *ngx_http_rewrite_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, |
1183 void *conf) | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1184 { |
485 | 1185 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
|
1186 |
485 | 1187 ngx_uint_t i, server_names; |
1188 ngx_str_t *value; | |
1189 ngx_http_server_name_t *sn; | |
1190 ngx_http_core_srv_conf_t *cscf; | |
1191 ngx_http_rewrite_referer_t *ref; | |
1192 | |
1193 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
|
1194 |
485 | 1195 if (lcf->referers == NULL) { |
1196 lcf->referers = ngx_array_create(cf->pool, | |
1197 cf->args->nelts + cscf->server_names.nelts, | |
1198 sizeof(ngx_http_rewrite_referer_t)); | |
1199 if (lcf->referers == NULL) { | |
1200 return NGX_CONF_ERROR; | |
1201 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1202 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1203 |
485 | 1204 value = cf->args->elts; |
1205 server_names = 0; | |
1206 | |
1207 for (i = 1; i < cf->args->nelts; i++) { | |
1208 if (value[i].len == 0) { | |
1209 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1210 "invalid referer \"%V\"", &value[i]); | |
1211 return NGX_CONF_ERROR; | |
1212 } | |
1213 | |
1214 if (ngx_strcmp(value[i].data, "none") == 0) { | |
1215 lcf->no_referer = 1; | |
1216 continue; | |
1217 } | |
1218 | |
1219 if (ngx_strcmp(value[i].data, "server_names") == 0) { | |
1220 server_names = 1; | |
1221 continue; | |
1222 } | |
1223 | |
1224 if (!(ref = ngx_array_push(lcf->referers))) { | |
1225 return NGX_CONF_ERROR; | |
1226 } | |
1227 | |
1228 if (value[i].data[0] != '*') { | |
1229 ref->name = value[i]; | |
1230 ref->wildcard = 0; | |
1231 continue; | |
1232 } | |
1233 | |
1234 if (value[i].data[1] != '.') { | |
1235 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1236 "invalid wildcard referer \"%V\"", &value[i]); | |
1237 return NGX_CONF_ERROR; | |
1238 } | |
1239 | |
1240 ref->name.len = value[i].len - 1; | |
1241 ref->name.data = value[i].data + 1; | |
1242 ref->wildcard = 1; | |
1243 } | |
1244 | |
1245 if (!server_names) { | |
1246 return NGX_CONF_OK; | |
1247 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1248 |
485 | 1249 sn = cscf->server_names.elts; |
1250 for (i = 0; i < cscf->server_names.nelts; i++) { | |
1251 if (!(ref = ngx_array_push(lcf->referers))) { | |
1252 return NGX_CONF_ERROR; | |
1253 } | |
1254 | |
1255 ref->name.len = sn[i].name.len + 1; | |
1256 if (!(ref->name.data = ngx_palloc(cf->pool, ref->name.len))) { | |
1257 return NGX_CONF_ERROR; | |
1258 } | |
1259 | |
1260 ngx_memcpy(ref->name.data, sn[i].name.data, sn[i].name.len); | |
1261 ref->name.data[sn[i].name.len] = '/'; | |
1262 ref->wildcard = sn[i].wildcard; | |
1263 } | |
1264 | |
1265 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
|
1266 } |
485 | 1267 |
1268 | |
1269 static void *ngx_http_rewrite_start_code(ngx_pool_t *pool, | |
1270 ngx_array_t **codes, size_t size) | |
1271 { | |
1272 if (*codes == NULL) { | |
1273 if (!(*codes = ngx_array_create(pool, 256, 1))) { | |
1274 return NULL; | |
1275 } | |
1276 } | |
1277 | |
1278 return ngx_array_push_n(*codes, size); | |
1279 } | |
1280 | |
1281 | |
1282 static void *ngx_http_rewrite_add_code(ngx_array_t *codes, size_t size, | |
1283 u_char **main) | |
1284 { | |
1285 u_char *elts; | |
1286 void *new; | |
1287 | |
1288 elts = codes->elts; | |
1289 | |
1290 if (!(new = ngx_array_push_n(codes, size))) { | |
1291 return NGX_CONF_ERROR; | |
1292 } | |
1293 | |
1294 if (elts != codes->elts) { | |
1295 *main += (u_char *) codes->elts - elts; | |
1296 } | |
1297 | |
1298 return new; | |
1299 } |