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