Mercurial > hg > nginx
annotate src/http/modules/ngx_http_rewrite_handler.c @ 499:64d9afb209da release-0.1.24
nginx-0.1.24-RELEASE import
*) Feature: the ngx_http_ssi_filter_module supports the QUERY_STRING
and DOCUMENT_URI variables.
*) Bugfix: the ngx_http_autoindex_module may some times return the 404
response for existent directory, if this directory was used in
"alias" directive.
*) Bugfix: the ngx_http_ssi_filter_module ran incorrectly for large
responses.
*) Bugfix: the lack of the "Referer" header line was always accounted
as valid referrer.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 04 Mar 2005 14:06:57 +0000 |
parents | 31ff3e943e16 |
children |
rev | line source |
---|---|
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
437
diff
changeset
|
1 |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
437
diff
changeset
|
2 /* |
444
42d11f017717
nginx-0.1.0-2004-09-29-20:00:49 import; remove years from copyright
Igor Sysoev <igor@sysoev.ru>
parents:
441
diff
changeset
|
3 * Copyright (C) Igor Sysoev |
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 | |
499 | 543 if (!(value = ngx_http_get_indexed_variable(e->request, code->index))) { |
485 | 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 | |
499 | 701 if (conf->no_referer == NGX_CONF_UNSET) { |
702 conf->no_referer = 0; | |
703 } | |
704 | |
485 | 705 if (conf->codes == NULL) { |
706 return NGX_CONF_OK; | |
707 } | |
708 | |
709 if (conf->codes == prev->codes) { | |
710 return NGX_CONF_OK; | |
711 } | |
712 | |
713 code = conf->codes->elts; | |
714 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
|
715 |
485 | 716 while (code < last) { |
717 if (*code == (uintptr_t) NULL) { | |
718 return NGX_CONF_OK; | |
719 } | |
720 | |
721 if (*code == (uintptr_t) &ngx_http_rewrite_regex_start_code) { | |
722 regex = (ngx_http_rewrite_regex_code_t *) code; | |
723 if (conf->max_captures < regex->ncaptures) { | |
724 conf->max_captures = regex->ncaptures; | |
725 } | |
726 code = (uintptr_t *) ((u_char *) code + regex->next); | |
727 } | |
728 | |
729 if (*code == (uintptr_t) &ngx_http_rewrite_if_code) { | |
730 code += sizeof(ngx_http_rewrite_if_code_t) / sizeof(uintptr_t); | |
731 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
732 |
485 | 733 if (*code == (uintptr_t) &ngx_http_rewrite_return_code) { |
734 code += sizeof(ngx_http_rewrite_return_code_t) / sizeof(uintptr_t); | |
735 } | |
736 | |
737 if (*code == (uintptr_t) &ngx_http_rewrite_var_code) { | |
738 code += sizeof(ngx_http_rewrite_var_code_t) / sizeof(uintptr_t); | |
739 } | |
740 | |
741 if (*code == (uintptr_t) &ngx_http_rewrite_invalid_referer_code) { | |
742 code++; | |
743 } | |
744 | |
745 if (*code == (uintptr_t) &ngx_http_rewrite_nop_code) { | |
746 code++; | |
747 } | |
748 } | |
749 | |
750 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
|
751 return NGX_CONF_ERROR; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
752 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
753 |
485 | 754 *code = (uintptr_t) NULL; |
755 | |
756 return NGX_CONF_OK; | |
757 } | |
758 | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
759 |
487 | 760 static char * |
761 ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
485 | 762 { |
763 ngx_http_rewrite_loc_conf_t *lcf = conf; | |
764 | |
765 u_char *data; | |
766 size_t len, size; | |
767 ngx_str_t *value, err; | |
768 ngx_uint_t i, n, last; | |
769 ngx_http_rewrite_code_pt *code; | |
770 ngx_http_rewrite_copy_code_t *copy; | |
771 ngx_http_rewrite_regex_code_t *regex; | |
772 ngx_http_rewrite_regex_end_code_t *regex_end; | |
773 ngx_http_rewrite_copy_capture_code_t *copy_capture; | |
774 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
775 | |
776 regex = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
777 sizeof(ngx_http_rewrite_regex_code_t)); | |
778 if (regex == NULL) { | |
779 return NGX_CONF_ERROR; | |
780 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
781 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
782 value = cf->args->elts; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
783 |
485 | 784 err.len = NGX_MAX_CONF_ERRSTR; |
785 err.data = errstr; | |
786 | |
787 /* TODO: NGX_REGEX_CASELESS */ | |
788 | |
789 regex->regex = ngx_regex_compile(&value[1], 0, cf->pool, &err); | |
790 | |
791 if (regex->regex == NULL) { | |
792 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | |
793 return NGX_CONF_ERROR; | |
794 } | |
795 | |
796 regex->code = ngx_http_rewrite_regex_start_code; | |
797 regex->size = 0; | |
798 regex->ncaptures = 0; | |
799 regex->status = 0; | |
800 regex->uri = 1; | |
801 regex->args = 1; | |
802 regex->redirect = 0; | |
803 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
|
804 |
485 | 805 last = 0; |
806 | |
807 if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0) { | |
808 regex->status = NGX_HTTP_MOVED_TEMPORARILY; | |
809 regex->redirect = 1; | |
810 last = 1; | |
811 } | |
812 | |
813 if (cf->args->nelts == 4) { | |
814 if (ngx_strcmp(value[3].data, "last") == 0) { | |
815 last = 1; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
816 |
487 | 817 } else if (ngx_strcmp(value[3].data, "break") == 0) { |
818 regex->break_cycle = 1; | |
819 last = 1; | |
820 | |
485 | 821 } else if (ngx_strcmp(value[3].data, "redirect") == 0) { |
822 regex->status = NGX_HTTP_MOVED_TEMPORARILY; | |
823 regex->redirect = 1; | |
824 last = 1; | |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
825 |
485 | 826 } else if (ngx_strcmp(value[3].data, "permanent") == 0) { |
827 regex->status = NGX_HTTP_MOVED_PERMANENTLY; | |
828 regex->redirect = 1; | |
829 last = 1; | |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
830 |
485 | 831 } else { |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
832 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
461 | 833 "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
|
834 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
|
835 } |
485 | 836 } |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
837 |
485 | 838 i = 0; |
839 | |
840 while (i < value[2].len) { | |
841 | |
842 data = &value[2].data[i]; | |
483 | 843 |
485 | 844 if (value[2].data[i] == '$' && i < value[2].len |
845 && value[2].data[i + 1] >= '1' && value[2].data[i + 1] <= '9') | |
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 /* the "$1" - "$9" captures */ |
849 | |
850 copy_capture = ngx_http_rewrite_add_code(lcf->codes, | |
851 sizeof(ngx_http_rewrite_copy_capture_code_t), | |
487 | 852 ®ex); |
485 | 853 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
|
854 return NGX_CONF_ERROR; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
855 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
856 |
485 | 857 i++; |
858 | |
859 copy_capture->code = ngx_http_rewrite_copy_capture_code; | |
860 copy_capture->n = value[2].data[i] - '0'; | |
861 | |
862 if (regex->ncaptures < copy_capture->n) { | |
863 regex->ncaptures = copy_capture->n; | |
864 } | |
865 | |
866 copy_capture->n *= 2; | |
867 | |
868 i++; | |
869 | |
870 continue; | |
871 } | |
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 (value[2].data[i] == '?') { |
874 | |
875 /* the arguments */ | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
876 |
485 | 877 if (i == value[2].len - 1) { |
878 /* the last "?" drops the original arguments */ | |
879 regex->args = 0; | |
880 break; | |
881 } | |
882 | |
883 if (!regex->redirect) { | |
884 code = ngx_http_rewrite_add_code(lcf->codes, sizeof(uintptr_t), | |
487 | 885 ®ex); |
485 | 886 if (code == NULL) { |
887 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
|
888 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
889 |
485 | 890 *code = ngx_http_rewrite_start_args_code; |
891 | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
892 i++; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
893 |
483 | 894 continue; |
895 } | |
485 | 896 } |
897 | |
898 i++; | |
899 | |
900 /* the substituion strings */ | |
901 | |
902 while (i < value[2].len && value[2].data[i] != '$') { | |
483 | 903 |
904 if (value[2].data[i] == '?') { | |
905 | |
485 | 906 if (i == value[2].len - 1) { |
907 /* | |
908 * the last "?" drops the original arguments, | |
909 * and it should not be copied to a substituion | |
910 */ | |
911 regex->args = 0; | |
912 break; | |
913 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
914 |
485 | 915 if (!regex->redirect) { |
916 break; | |
917 } | |
483 | 918 } |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
919 |
483 | 920 i++; |
485 | 921 } |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
922 |
485 | 923 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
|
924 |
485 | 925 if (len == 0) { |
926 continue; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
927 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
928 |
485 | 929 regex->size += len; |
930 | |
931 size = (len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1); | |
481 | 932 |
485 | 933 copy = ngx_http_rewrite_add_code(lcf->codes, |
934 sizeof(ngx_http_rewrite_copy_code_t) + size, | |
487 | 935 ®ex); |
485 | 936 if (copy == NULL) { |
481 | 937 return NGX_CONF_ERROR; |
938 } | |
939 | |
485 | 940 copy->code = ngx_http_rewrite_copy_code; |
941 copy->len = len; | |
942 | |
943 ngx_memcpy((u_char *) copy + sizeof(ngx_http_rewrite_copy_code_t), | |
944 data, len); | |
945 } | |
946 | |
947 n = ngx_regex_capture_count(regex->regex); | |
948 | |
949 if (regex->ncaptures > n) { | |
950 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
951 "pattern \"%V\" has less captures " | |
952 "than referrenced in substitution \"%V\"", | |
953 &value[1], &value[2]); | |
954 return NGX_CONF_ERROR; | |
955 } | |
956 | |
957 if (regex->ncaptures < n) { | |
958 regex->ncaptures = n; | |
959 } | |
481 | 960 |
485 | 961 if (regex->ncaptures) { |
962 regex->ncaptures = (regex->ncaptures + 1) * 3; | |
963 } | |
964 | |
965 regex_end = ngx_http_rewrite_add_code(lcf->codes, | |
966 sizeof(ngx_http_rewrite_regex_end_code_t), | |
487 | 967 ®ex); |
485 | 968 if (regex_end == NULL) { |
969 return NGX_CONF_ERROR; | |
970 } | |
971 | |
972 regex_end->code = ngx_http_rewrite_regex_end_code; | |
973 regex_end->uri = regex->uri; | |
974 regex_end->args = regex->args; | |
975 regex_end->redirect = regex->redirect; | |
976 | |
977 if (last) { | |
978 code = ngx_http_rewrite_add_code(lcf->codes, sizeof(uintptr_t), | |
487 | 979 ®ex); |
485 | 980 if (code == NULL) { |
981 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
|
982 } |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
983 |
485 | 984 *code = (uintptr_t) NULL; |
985 } | |
986 | |
987 regex->next = (u_char *) lcf->codes->elts + lcf->codes->nelts | |
988 - (u_char *) regex; | |
989 | |
990 return NGX_CONF_OK; | |
991 } | |
992 | |
993 | |
487 | 994 static char * |
995 ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
485 | 996 { |
997 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
|
998 |
485 | 999 ngx_str_t *value; |
1000 ngx_http_rewrite_return_code_t *ret; | |
1001 | |
1002 ret = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
1003 sizeof(ngx_http_rewrite_return_code_t)); | |
1004 if (ret == NULL) { | |
1005 return NGX_CONF_ERROR; | |
1006 } | |
1007 | |
1008 value = cf->args->elts; | |
1009 | |
1010 ret->code = ngx_http_rewrite_return_code; | |
1011 ret->null = (uintptr_t) NULL; | |
1012 | |
1013 ret->status = ngx_atoi(value[1].data, value[1].len); | |
1014 | |
1015 if (ret->status == (uintptr_t) NGX_ERROR) { | |
1016 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
|
1017 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1018 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1019 return NGX_CONF_OK; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1020 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1021 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1022 |
487 | 1023 static char * |
1024 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
|
1025 { |
485 | 1026 ngx_http_rewrite_loc_conf_t *lcf = conf; |
1027 | |
1028 void *mconf; | |
1029 char *rv; | |
1030 u_char *elts; | |
1031 ngx_str_t *value; | |
499 | 1032 ngx_int_t index; |
485 | 1033 ngx_uint_t i; |
1034 ngx_conf_t save; | |
1035 ngx_http_rewrite_code_pt *code; | |
1036 ngx_http_module_t *module; | |
1037 ngx_http_conf_ctx_t *ctx, *pctx; | |
1038 ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp; | |
1039 ngx_http_core_main_conf_t *cmcf; | |
1040 ngx_http_rewrite_if_code_t *if_code; | |
1041 ngx_http_rewrite_var_code_t *var_code; | |
1042 ngx_http_rewrite_loc_conf_t *nlcf; | |
1043 | |
1044 if (!(ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)))) { | |
1045 return NGX_CONF_ERROR; | |
1046 } | |
1047 | |
1048 pctx = cf->ctx; | |
1049 ctx->main_conf = pctx->main_conf; | |
1050 ctx->srv_conf = pctx->srv_conf; | |
1051 | |
1052 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); | |
1053 if (ctx->loc_conf == NULL) { | |
1054 return NGX_CONF_ERROR; | |
1055 } | |
1056 | |
1057 for (i = 0; ngx_modules[i]; i++) { | |
1058 if (ngx_modules[i]->type != NGX_HTTP_MODULE) { | |
1059 continue; | |
1060 } | |
1061 | |
1062 module = ngx_modules[i]->ctx; | |
1063 | |
1064 if (module->create_loc_conf) { | |
1065 | |
1066 if (!(mconf = module->create_loc_conf(cf))) { | |
1067 return NGX_CONF_ERROR; | |
1068 } | |
1069 | |
1070 ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf; | |
1071 } | |
1072 } | |
1073 | |
1074 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index]; | |
1075 | |
1076 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; | |
1077 clcf->loc_conf = ctx->loc_conf; | |
1078 clcf->name = pclcf->name; | |
1079 clcf->noname = 1; | |
1080 | |
1081 if (pclcf->locations.elts == NULL) { | |
1082 if (ngx_array_init(&pclcf->locations, cf->pool, 4, sizeof(void *)) | |
1083 == NGX_ERROR) | |
1084 { | |
1085 return NGX_CONF_ERROR; | |
1086 } | |
1087 } | |
1088 | |
1089 if (!(clcfp = ngx_push_array(&pclcf->locations))) { | |
1090 return NGX_CONF_ERROR; | |
1091 } | |
1092 | |
1093 *clcfp = clcf; | |
1094 | |
1095 | |
1096 /* STUB: "if ($var)" */ | |
1097 | |
1098 value = cf->args->elts; | |
1099 | |
1100 if (value[1].len < 2 | |
1101 || value[1].data[0] != '(' | |
1102 || value[1].data[1] != '$' | |
1103 || value[1].data[value[1].len - 1] != ')') | |
1104 { | |
1105 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1106 "invalid condition \"%V\"", &value[1]); | |
1107 return NGX_CONF_ERROR; | |
1108 } | |
1109 | |
1110 value[1].len -= 3; | |
1111 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
|
1112 |
485 | 1113 if (value[1].len == sizeof("invalid_referer") - 1 |
1114 && ngx_strncmp(value[1].data, "invalid_referer", | |
1115 sizeof("invalid_referer") - 1) == 0) | |
1116 { | |
1117 code = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
1118 sizeof(ngx_http_rewrite_code_pt)); | |
1119 if (code == NULL) { | |
1120 return NGX_CONF_ERROR; | |
1121 } | |
1122 | |
1123 *code = ngx_http_rewrite_invalid_referer_code; | |
1124 | |
1125 } else { | |
1126 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | |
1127 | |
499 | 1128 index = ngx_http_get_variable_index(cmcf, &value[1]); |
485 | 1129 |
499 | 1130 if (index == -1) { |
485 | 1131 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
1132 "unknown variable name \"%V\"", &value[1]); | |
1133 return NGX_CONF_ERROR; | |
1134 } | |
1135 | |
1136 var_code = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
1137 sizeof(ngx_http_rewrite_var_code_t)); | |
1138 if (var_code == NULL) { | |
1139 return NGX_CONF_ERROR; | |
1140 } | |
1141 | |
1142 var_code->code = ngx_http_rewrite_var_code; | |
499 | 1143 var_code->index = index; |
485 | 1144 } |
1145 | |
1146 if_code = ngx_array_push_n(lcf->codes, sizeof(ngx_http_rewrite_if_code_t)); | |
1147 if (if_code == NULL) { | |
1148 return NULL; | |
1149 } | |
1150 | |
1151 if_code->code = ngx_http_rewrite_if_code; | |
1152 | |
1153 elts = lcf->codes->elts; | |
1154 | |
1155 | |
1156 /* the inside directives must compile to the same code array */ | |
1157 | |
1158 nlcf = ctx->loc_conf[ngx_http_rewrite_module.ctx_index]; | |
1159 nlcf->codes = lcf->codes; | |
1160 | |
1161 | |
1162 save = *cf; | |
1163 cf->ctx = ctx; | |
1164 | |
1165 if (pclcf->name.len == 0) { | |
1166 if_code->loc_conf = NULL; | |
1167 cf->cmd_type = NGX_HTTP_SIF_CONF; | |
1168 | |
1169 } else { | |
1170 if_code->loc_conf = ctx->loc_conf; | |
1171 cf->cmd_type = NGX_HTTP_LIF_CONF; | |
1172 } | |
1173 | |
1174 rv = ngx_conf_parse(cf, NULL); | |
1175 | |
1176 *cf = save; | |
1177 | |
1178 if (rv != NGX_CONF_OK) { | |
1179 return rv; | |
1180 } | |
1181 | |
1182 | |
1183 if (elts != lcf->codes->elts) { | |
1184 if_code = (ngx_http_rewrite_if_code_t *) | |
1185 ((u_char *) if_code + ((u_char *) lcf->codes->elts - elts)); | |
1186 } | |
1187 | |
1188 if_code->next = (u_char *) lcf->codes->elts + lcf->codes->nelts | |
1189 - (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
|
1190 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
1191 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
|
1192 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
1193 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
1194 |
487 | 1195 static char * |
1196 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
|
1197 { |
485 | 1198 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
|
1199 |
485 | 1200 ngx_uint_t i, server_names; |
1201 ngx_str_t *value; | |
1202 ngx_http_server_name_t *sn; | |
1203 ngx_http_core_srv_conf_t *cscf; | |
1204 ngx_http_rewrite_referer_t *ref; | |
1205 | |
1206 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
|
1207 |
485 | 1208 if (lcf->referers == NULL) { |
1209 lcf->referers = ngx_array_create(cf->pool, | |
1210 cf->args->nelts + cscf->server_names.nelts, | |
1211 sizeof(ngx_http_rewrite_referer_t)); | |
1212 if (lcf->referers == NULL) { | |
1213 return NGX_CONF_ERROR; | |
1214 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1215 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1216 |
485 | 1217 value = cf->args->elts; |
1218 server_names = 0; | |
1219 | |
1220 for (i = 1; i < cf->args->nelts; i++) { | |
1221 if (value[i].len == 0) { | |
1222 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1223 "invalid referer \"%V\"", &value[i]); | |
1224 return NGX_CONF_ERROR; | |
1225 } | |
1226 | |
1227 if (ngx_strcmp(value[i].data, "none") == 0) { | |
1228 lcf->no_referer = 1; | |
1229 continue; | |
1230 } | |
1231 | |
1232 if (ngx_strcmp(value[i].data, "server_names") == 0) { | |
1233 server_names = 1; | |
1234 continue; | |
1235 } | |
1236 | |
1237 if (!(ref = ngx_array_push(lcf->referers))) { | |
1238 return NGX_CONF_ERROR; | |
1239 } | |
1240 | |
1241 if (value[i].data[0] != '*') { | |
1242 ref->name = value[i]; | |
1243 ref->wildcard = 0; | |
1244 continue; | |
1245 } | |
1246 | |
1247 if (value[i].data[1] != '.') { | |
1248 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1249 "invalid wildcard referer \"%V\"", &value[i]); | |
1250 return NGX_CONF_ERROR; | |
1251 } | |
1252 | |
1253 ref->name.len = value[i].len - 1; | |
1254 ref->name.data = value[i].data + 1; | |
1255 ref->wildcard = 1; | |
1256 } | |
1257 | |
1258 if (!server_names) { | |
1259 return NGX_CONF_OK; | |
1260 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1261 |
485 | 1262 sn = cscf->server_names.elts; |
1263 for (i = 0; i < cscf->server_names.nelts; i++) { | |
1264 if (!(ref = ngx_array_push(lcf->referers))) { | |
1265 return NGX_CONF_ERROR; | |
1266 } | |
1267 | |
1268 ref->name.len = sn[i].name.len + 1; | |
1269 if (!(ref->name.data = ngx_palloc(cf->pool, ref->name.len))) { | |
1270 return NGX_CONF_ERROR; | |
1271 } | |
1272 | |
1273 ngx_memcpy(ref->name.data, sn[i].name.data, sn[i].name.len); | |
1274 ref->name.data[sn[i].name.len] = '/'; | |
1275 ref->wildcard = sn[i].wildcard; | |
1276 } | |
1277 | |
1278 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
|
1279 } |
485 | 1280 |
1281 | |
487 | 1282 static void * |
1283 ngx_http_rewrite_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size) | |
485 | 1284 { |
1285 if (*codes == NULL) { | |
1286 if (!(*codes = ngx_array_create(pool, 256, 1))) { | |
1287 return NULL; | |
1288 } | |
1289 } | |
1290 | |
1291 return ngx_array_push_n(*codes, size); | |
1292 } | |
1293 | |
1294 | |
487 | 1295 static void * |
1296 ngx_http_rewrite_add_code(ngx_array_t *codes, size_t size, void *code) | |
485 | 1297 { |
487 | 1298 u_char *elts, **p; |
485 | 1299 void *new; |
1300 | |
1301 elts = codes->elts; | |
1302 | |
1303 if (!(new = ngx_array_push_n(codes, size))) { | |
1304 return NGX_CONF_ERROR; | |
1305 } | |
1306 | |
1307 if (elts != codes->elts) { | |
487 | 1308 p = code; |
1309 *p += (u_char *) codes->elts - elts; | |
485 | 1310 } |
1311 | |
1312 return new; | |
1313 } |