Mercurial > hg > nginx
annotate src/http/modules/ngx_http_rewrite_module.c @ 505:ee66921ecd47 release-0.1.27
nginx-0.1.27-RELEASE import
*) Feature: the "blocked" parameter of the "valid_referers" directive.
*) Change: the errors while handling the request header now logged at
"info" level. The server name and the "Host" and "Referer" header
lines also logged.
*) Change: the "Host" header line is also logged in error log.
*) Feature: the proxy_pass_unparsed_uri directive. The special handling
of the "://" symbols in URI, appeared in 0.1.11 version, now is
canceled.
*) Bugfix: nginx could not be built on FreeBSD and Linux, if the
--without-ngx_http_auth_basic_module configuration parameter was
used.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 28 Mar 2005 14:43:02 +0000 |
parents | d4ea69372b94 |
children | cd3117ad9aab |
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 { | |
501 | 24 ngx_str_t *name; |
25 ngx_http_variable_value_t *value; | |
26 } ngx_http_rewrite_variable_t; | |
27 | |
28 | |
29 typedef struct { | |
485 | 30 ngx_array_t *codes; /* uintptr_t */ |
31 ngx_array_t *referers; /* ngx_http_rewrite_referer_t */ | |
32 | |
33 ngx_uint_t max_captures; | |
34 ngx_uint_t stack_size; | |
35 | |
36 ngx_flag_t log; | |
37 | |
38 ngx_flag_t no_referer; | |
505 | 39 ngx_flag_t blocked_referer; |
485 | 40 } 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
|
41 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
42 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
43 typedef struct { |
485 | 44 ngx_http_rewrite_code_pt code; |
45 ngx_regex_t *regex; | |
46 uintptr_t size; | |
47 uintptr_t ncaptures; | |
48 uintptr_t status; | |
49 uintptr_t next; | |
50 | |
501 | 51 uintptr_t test:1; |
485 | 52 uintptr_t uri:1; |
53 | |
54 /* add the r->args to the new arguments */ | |
55 uintptr_t args:1; | |
56 | |
57 uintptr_t redirect:1; | |
487 | 58 uintptr_t break_cycle:1; |
485 | 59 |
60 ngx_str_t name; | |
61 } ngx_http_rewrite_regex_code_t; | |
62 | |
63 | |
64 typedef struct { | |
65 ngx_http_rewrite_code_pt code; | |
66 | |
67 uintptr_t uri:1; | |
68 | |
69 /* add the r->args to the new arguments */ | |
70 uintptr_t args:1; | |
71 | |
72 uintptr_t redirect:1; | |
73 } ngx_http_rewrite_regex_end_code_t; | |
74 | |
75 typedef struct { | |
76 ngx_http_rewrite_code_pt code; | |
77 uintptr_t n; | |
78 } 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
|
79 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
80 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
81 typedef struct { |
485 | 82 ngx_http_rewrite_code_pt code; |
83 uintptr_t len; | |
84 } 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
|
85 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
86 |
485 | 87 typedef struct { |
88 ngx_http_rewrite_code_pt code; | |
89 uintptr_t status; | |
90 uintptr_t null; | |
91 } 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
|
92 |
485 | 93 |
94 typedef struct { | |
95 ngx_http_rewrite_code_pt code; | |
96 uintptr_t next; | |
97 void **loc_conf; | |
98 } 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
|
99 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
100 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
101 typedef struct { |
485 | 102 ngx_http_rewrite_code_pt code; |
501 | 103 uintptr_t value; |
104 uintptr_t text_len; | |
105 uintptr_t text_data; | |
106 } ngx_http_rewrite_value_code_t; | |
107 | |
108 | |
109 typedef struct { | |
110 ngx_http_rewrite_code_pt code; | |
485 | 111 uintptr_t index; |
112 } 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
|
113 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
114 |
485 | 115 struct ngx_http_rewrite_engine_s { |
116 u_char *ip; | |
501 | 117 ngx_http_variable_value_t *sp; |
485 | 118 |
119 ngx_str_t buf; | |
120 ngx_str_t *line; | |
121 | |
122 u_char *pos; | |
123 | |
124 /* the start of the rewritten arguments */ | |
125 u_char *args; | |
126 | |
127 unsigned quote:1; | |
128 | |
129 ngx_int_t status; | |
130 | |
131 int *captures; | |
132 | |
133 ngx_http_request_t *request; | |
134 ngx_http_rewrite_loc_conf_t *conf; | |
135 }; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
136 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
137 |
485 | 138 static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle); |
139 static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf); | |
140 static char *ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, | |
487 | 141 void *parent, void *child); |
485 | 142 static char *ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
143 static char *ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, | |
487 | 144 void *conf); |
485 | 145 static char *ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, |
487 | 146 void *conf); |
501 | 147 static char * ngx_http_rewrite_if_condition(ngx_conf_t *cf, |
148 ngx_http_rewrite_loc_conf_t *lcf); | |
149 static char *ngx_http_rewrite_variable(ngx_conf_t *cf, | |
150 ngx_http_rewrite_loc_conf_t *lcf, ngx_str_t *value); | |
487 | 151 static char *ngx_http_rewrite_valid_referers(ngx_conf_t *cf, |
152 ngx_command_t *cmd, void *conf); | |
501 | 153 static char * ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, |
154 void *conf); | |
485 | 155 static void *ngx_http_rewrite_start_code(ngx_pool_t *pool, |
487 | 156 ngx_array_t **codes, size_t size); |
485 | 157 static void *ngx_http_rewrite_add_code(ngx_array_t *codes, size_t size, |
487 | 158 void *code); |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
159 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
160 |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
161 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
|
162 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
163 { ngx_string("rewrite"), |
485 | 164 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |
165 |NGX_CONF_TAKE23, | |
166 ngx_http_rewrite, | |
167 NGX_HTTP_LOC_CONF_OFFSET, | |
168 0, | |
169 NULL }, | |
170 | |
171 { ngx_string("return"), | |
172 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF | |
173 |NGX_CONF_TAKE1, | |
174 ngx_http_rewrite_return, | |
175 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
|
176 0, |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
177 NULL }, |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
178 |
485 | 179 { ngx_string("if"), |
180 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE, | |
181 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
|
182 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
|
183 0, |
485 | 184 NULL }, |
185 | |
186 { ngx_string("valid_referers"), | |
187 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | |
188 ngx_http_rewrite_valid_referers, | |
189 NGX_HTTP_LOC_CONF_OFFSET, | |
190 0, | |
191 NULL }, | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
192 |
501 | 193 { ngx_string("set"), |
194 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF | |
195 |NGX_CONF_TAKE2, | |
196 ngx_http_rewrite_set, | |
197 NGX_HTTP_LOC_CONF_OFFSET, | |
198 0, | |
199 NULL }, | |
200 | |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
201 { ngx_string("rewrite_log"), |
485 | 202 NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |
203 |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
|
204 ngx_conf_set_flag_slot, |
485 | 205 NGX_HTTP_LOC_CONF_OFFSET, |
206 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
|
207 NULL }, |
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
208 |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
209 ngx_null_command |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
210 }; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
211 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
212 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
213 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
|
214 NULL, /* pre conf */ |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
215 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
216 NULL, /* create main configuration */ |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
217 NULL, /* init main configuration */ |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
218 |
485 | 219 NULL, /* create server configuration */ |
220 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
|
221 |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
222 ngx_http_rewrite_create_loc_conf, /* create location configration */ |
485 | 223 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
|
224 }; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
225 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
226 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
227 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
|
228 NGX_MODULE, |
485 | 229 &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
|
230 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
|
231 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
|
232 ngx_http_rewrite_init, /* init module */ |
485 | 233 NULL /* init process */ |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
234 }; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
235 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
236 |
485 | 237 #define ngx_http_rewrite_exit (u_char *) &ngx_http_rewrite_exit_code |
238 | |
239 uintptr_t ngx_http_rewrite_exit_code = (uintptr_t) NULL; | |
240 | |
501 | 241 static ngx_http_variable_value_t ngx_http_rewrite_null_value = |
242 { 0, ngx_string("") }; | |
243 | |
485 | 244 |
487 | 245 static ngx_int_t |
246 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
|
247 { |
485 | 248 ngx_http_rewrite_code_pt code; |
249 ngx_http_rewrite_engine_t *e; | |
250 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
|
251 |
485 | 252 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
|
253 |
485 | 254 if (cf->codes == NULL) { |
255 return NGX_DECLINED; | |
256 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
257 |
501 | 258 e = ngx_palloc(r->pool, sizeof(ngx_http_rewrite_engine_t)); |
259 if (e == NULL) { | |
485 | 260 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
261 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
262 |
501 | 263 e->sp = ngx_palloc(r->pool, |
264 cf->stack_size * sizeof(ngx_http_variable_value_t)); | |
485 | 265 if (e->sp == NULL) { |
266 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
267 } | |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
268 |
485 | 269 if (cf->max_captures) { |
270 e->captures = ngx_palloc(r->pool, cf->max_captures * sizeof(int)); | |
271 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
|
272 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
|
273 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
274 |
485 | 275 } else { |
276 e->captures = NULL; | |
277 } | |
278 | |
279 e->ip = cf->codes->elts; | |
280 e->buf.len = 0; | |
281 e->buf.data = NULL; | |
282 e->line = NULL; | |
283 e->pos = NULL; | |
284 e->args = NULL; | |
285 e->quote = 1; | |
286 e->status = NGX_DECLINED; | |
287 e->request = r; | |
288 e->conf = cf; | |
289 | |
290 while (*(uintptr_t *) e->ip) { | |
291 code = *(ngx_http_rewrite_code_pt *) e->ip; | |
292 code(e); | |
293 } | |
294 | |
295 return e->status; | |
296 } | |
297 | |
298 | |
487 | 299 static void |
300 ngx_http_rewrite_regex_start_code(ngx_http_rewrite_engine_t *e) | |
485 | 301 { |
302 ngx_int_t rc; | |
303 ngx_uint_t n; | |
304 ngx_http_request_t *r; | |
305 ngx_http_rewrite_regex_code_t *code; | |
306 | |
307 code = (ngx_http_rewrite_regex_code_t *) e->ip; | |
308 | |
309 r = e->request; | |
310 | |
311 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
501 | 312 "http rewrite regex: \"%V\"", &code->name); |
485 | 313 |
314 if (code->uri) { | |
315 e->line = &r->uri; | |
316 } else { | |
501 | 317 e->sp--; |
318 e->line = &e->sp->text; | |
485 | 319 } |
320 | |
321 rc = ngx_regex_exec(code->regex, e->line, e->captures, code->ncaptures); | |
322 | |
323 if (rc == NGX_REGEX_NO_MATCHED) { | |
324 if (e->conf->log) { | |
325 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, | |
326 "\"%V\" does not match \"%V\"", &code->name, e->line); | |
327 } | |
328 | |
501 | 329 if (code->test) { |
330 e->sp->value = 0; | |
331 e->sp->text.len = 0; | |
332 e->sp->text.data = (u_char *) ""; | |
333 e->sp++; | |
334 | |
335 e->ip += sizeof(ngx_http_rewrite_regex_code_t); | |
336 return; | |
337 } | |
338 | |
485 | 339 e->ip += code->next; |
340 return; | |
341 } | |
342 | |
343 if (rc < 0) { | |
344 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | |
345 ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"", | |
346 rc, e->line, &code->name); | |
347 | |
348 e->ip = ngx_http_rewrite_exit; | |
349 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
350 return; | |
351 } | |
352 | |
353 if (e->conf->log) { | |
354 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, | |
355 "\"%V\" matches \"%V\"", &code->name, e->line); | |
356 } | |
357 | |
501 | 358 if (code->test) { |
359 e->sp->value = 1; | |
360 e->sp->text.len = 1; | |
361 e->sp->text.data = (u_char *) "1"; | |
362 e->sp++; | |
363 | |
364 e->ip += sizeof(ngx_http_rewrite_regex_code_t); | |
365 return; | |
366 } | |
367 | |
485 | 368 if (code->status) { |
369 e->status = code->status; | |
370 | |
371 if (!code->redirect) { | |
372 e->ip = ngx_http_rewrite_exit; | |
373 return; | |
374 } | |
375 } | |
376 | |
377 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
|
378 |
485 | 379 if (code->uri) { |
487 | 380 if (!code->break_cycle) { |
381 r->uri_changed = 1; | |
505 | 382 r->valid_unparsed_uri = 1; |
487 | 383 } |
485 | 384 |
385 if (rc && (r->quoted_uri || r->plus_in_uri)) { | |
386 e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len, | |
387 NGX_ESCAPE_ARGS); | |
388 } | |
389 } | |
390 | |
391 for (n = 1; n < (ngx_uint_t) rc; n++) { | |
392 e->buf.len += e->captures[2 * n + 1] - e->captures[2 * n]; | |
393 } | |
394 | |
395 if (code->args && r->args.len) { | |
396 e->buf.len += r->args.len + 1; | |
397 } | |
398 | |
501 | 399 e->buf.data = ngx_palloc(r->pool, e->buf.len); |
400 if (e->buf.data == NULL) { | |
485 | 401 e->ip = ngx_http_rewrite_exit; |
402 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
403 return; | |
404 } | |
405 | |
406 e->quote = code->redirect; | |
407 | |
408 e->pos = e->buf.data; | |
409 | |
410 e->ip += sizeof(ngx_http_rewrite_regex_code_t); | |
411 } | |
412 | |
413 | |
487 | 414 static void |
415 ngx_http_rewrite_regex_end_code(ngx_http_rewrite_engine_t *e) | |
485 | 416 { |
417 ngx_http_request_t *r; | |
418 ngx_http_rewrite_regex_end_code_t *code; | |
419 | |
420 code = (ngx_http_rewrite_regex_end_code_t *) e->ip; | |
421 | |
422 r = e->request; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
423 |
485 | 424 e->quote = 0; |
425 | |
426 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
501 | 427 "http rewrite regex end"); |
485 | 428 |
429 if (e->args) { | |
430 e->buf.len = e->args - e->buf.data; | |
431 | |
432 if (code->args && r->args.len) { | |
433 *e->pos++ = '&'; | |
434 e->pos = ngx_cpymem(e->pos, r->args.data, r->args.len); | |
435 } | |
436 | |
437 r->args.len = e->pos - e->args; | |
438 r->args.data = e->args; | |
439 | |
440 e->args = NULL; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
441 |
485 | 442 } else { |
443 if (code->args && r->args.len) { | |
487 | 444 *e->pos++ = '?'; |
485 | 445 e->pos = ngx_cpymem(e->pos, r->args.data, r->args.len); |
446 } | |
447 | |
448 e->buf.len = e->pos - e->buf.data; | |
449 } | |
483 | 450 |
485 | 451 if (!code->redirect) { |
452 if (e->conf->log) { | |
453 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, | |
454 "rewritten data: \"%V\", args: \"%V\"", | |
455 &e->buf, &r->args); | |
456 } | |
457 | |
458 if (code->uri) { | |
459 r->uri = e->buf; | |
460 | |
461 if (ngx_http_set_exten(r) != NGX_OK) { | |
462 e->ip = ngx_http_rewrite_exit; | |
463 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
464 return; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
465 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
466 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
467 |
485 | 468 e->ip += sizeof(ngx_http_rewrite_regex_end_code_t); |
469 return; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
470 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
471 |
485 | 472 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, |
473 "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
|
474 |
501 | 475 r->headers_out.location = ngx_list_push(&r->headers_out.headers); |
476 if (r->headers_out.location == NULL) { | |
485 | 477 e->ip = ngx_http_rewrite_exit; |
478 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
479 return; | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
480 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
481 |
485 | 482 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
|
483 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
|
484 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
|
485 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
486 |
485 | 487 r->headers_out.location->value = e->buf; |
488 | |
489 e->ip += sizeof(ngx_http_rewrite_regex_end_code_t); | |
490 } | |
491 | |
492 | |
487 | 493 static void |
494 ngx_http_rewrite_copy_capture_code(ngx_http_rewrite_engine_t *e) | |
485 | 495 { |
496 ngx_http_rewrite_copy_capture_code_t *code; | |
497 | |
498 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
|
499 |
485 | 500 e->ip += sizeof(ngx_http_rewrite_copy_capture_code_t); |
501 | |
502 if ((e->args || e->quote) | |
503 && (e->request->quoted_uri || e->request->plus_in_uri)) | |
504 { | |
505 e->pos = (u_char *) ngx_escape_uri(e->pos, | |
506 &e->line->data[e->captures[code->n]], | |
507 e->captures[code->n + 1] - e->captures[code->n], | |
508 NGX_ESCAPE_ARGS); | |
509 } else { | |
510 e->pos = ngx_cpymem(e->pos, &e->line->data[e->captures[code->n]], | |
511 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
|
512 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
513 |
485 | 514 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, |
515 "http rewrite capture: \"%V\"", &e->buf); | |
516 } | |
517 | |
518 | |
487 | 519 static void |
520 ngx_http_rewrite_copy_code(ngx_http_rewrite_engine_t *e) | |
485 | 521 { |
522 ngx_http_rewrite_copy_code_t *code; | |
523 | |
524 code = (ngx_http_rewrite_copy_code_t *) e->ip; | |
525 | |
526 e->pos = ngx_cpymem(e->pos, e->ip + sizeof(ngx_http_rewrite_copy_code_t), | |
527 code->len); | |
528 | |
529 e->ip += sizeof(ngx_http_rewrite_copy_code_t) | |
501 | 530 + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1)); |
485 | 531 |
532 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
533 "http rewrite copy: \"%V\"", &e->buf); | |
534 } | |
535 | |
536 | |
487 | 537 static void |
538 ngx_http_rewrite_start_args_code(ngx_http_rewrite_engine_t *e) | |
485 | 539 { |
540 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
541 "http rewrite args"); | |
542 | |
543 e->args = e->pos; | |
544 e->ip += sizeof(uintptr_t); | |
545 } | |
546 | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
547 |
487 | 548 static void |
549 ngx_http_rewrite_return_code(ngx_http_rewrite_engine_t *e) | |
485 | 550 { |
551 ngx_http_rewrite_return_code_t *code; | |
552 | |
553 code = (ngx_http_rewrite_return_code_t *) e->ip; | |
554 | |
555 e->status = code->status; | |
556 | |
557 e->ip += sizeof(ngx_http_rewrite_return_code_t) - sizeof(uintptr_t); | |
558 } | |
559 | |
560 | |
487 | 561 static void |
562 ngx_http_rewrite_if_code(ngx_http_rewrite_engine_t *e) | |
485 | 563 { |
564 ngx_http_rewrite_if_code_t *code; | |
565 | |
566 code = (ngx_http_rewrite_if_code_t *) e->ip; | |
567 | |
568 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
569 "http rewrite if"); | |
570 | |
501 | 571 e->sp--; |
572 | |
573 if (e->sp->value) { | |
485 | 574 if (code->loc_conf) { |
575 e->request->loc_conf = code->loc_conf; | |
576 } | |
577 | |
578 e->ip += sizeof(ngx_http_rewrite_if_code_t); | |
579 return; | |
580 } | |
581 | |
582 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
583 "http rewrite if false"); | |
584 | |
585 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
|
586 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
587 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
588 |
487 | 589 static void |
501 | 590 ngx_http_rewrite_value_code(ngx_http_rewrite_engine_t *e) |
591 { | |
592 ngx_http_rewrite_value_code_t *code; | |
593 | |
594 code = (ngx_http_rewrite_value_code_t *) e->ip; | |
595 | |
596 e->ip += sizeof(ngx_http_rewrite_value_code_t); | |
597 | |
598 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
599 "http rewrite value"); | |
600 | |
601 e->sp->value = (ngx_uint_t) code->value; | |
602 e->sp->text.len = (size_t) code->text_len; | |
603 e->sp->text.data = (u_char *) code->text_data; | |
604 e->sp++; | |
605 } | |
606 | |
607 | |
608 static void | |
609 ngx_http_rewrite_set_var_code(ngx_http_rewrite_engine_t *e) | |
610 { | |
611 ngx_http_request_t *r; | |
612 ngx_http_variable_value_t *value; | |
613 ngx_http_core_main_conf_t *cmcf; | |
614 ngx_http_rewrite_var_code_t *code; | |
615 | |
616 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
617 "http rewrite set var"); | |
618 | |
619 code = (ngx_http_rewrite_var_code_t *) e->ip; | |
620 | |
621 e->ip += sizeof(ngx_http_rewrite_var_code_t); | |
622 | |
623 r = e->request; | |
624 | |
625 if (r->variables == NULL) { | |
626 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
627 | |
628 r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts | |
629 * sizeof(ngx_http_variable_value_t *)); | |
630 if (r->variables == NULL) { | |
631 e->ip = ngx_http_rewrite_exit; | |
632 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
633 return; | |
634 } | |
635 } | |
636 | |
637 value = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t)); | |
638 if (value == NULL) { | |
639 e->ip = ngx_http_rewrite_exit; | |
640 e->status = NGX_HTTP_INTERNAL_SERVER_ERROR; | |
641 return; | |
642 } | |
643 | |
644 e->sp--; | |
645 | |
646 *value = *e->sp; | |
647 | |
648 r->variables[code->index] = value; | |
649 } | |
650 | |
651 | |
652 static void | |
487 | 653 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
|
654 { |
485 | 655 ngx_http_variable_value_t *value; |
656 ngx_http_rewrite_var_code_t *code; | |
657 | |
658 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, | |
659 "http rewrite var"); | |
660 | |
661 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
|
662 |
485 | 663 e->ip += sizeof(ngx_http_rewrite_var_code_t); |
664 | |
501 | 665 value = ngx_http_get_indexed_variable(e->request, code->index); |
666 | |
667 if (value == NULL || value == NGX_HTTP_VARIABLE_NOT_FOUND) { | |
668 e->sp->value = 0; | |
669 e->sp->text.len = 0; | |
670 e->sp->text.data = (u_char *) ""; | |
671 e->sp++; | |
672 | |
485 | 673 return; |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
674 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
675 |
501 | 676 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, |
677 "http rewrite var: %ui, \"%V\"", value->value, &value->text); | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
678 |
501 | 679 *e->sp = *value; |
680 e->sp++; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
681 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
682 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
683 |
487 | 684 static void |
685 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
|
686 { |
485 | 687 u_char *ref; |
688 size_t len; | |
689 ngx_uint_t i, n; | |
690 ngx_http_request_t *r; | |
691 ngx_http_rewrite_referer_t *refs; | |
692 ngx_http_rewrite_loc_conf_t *cf; | |
693 | |
694 r = e->request; | |
695 | |
696 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
697 "http rewrite invalid referer"); | |
698 | |
699 cf = ngx_http_get_module_loc_conf(r, ngx_http_rewrite_module); | |
700 | |
701 e->ip += sizeof(uintptr_t); | |
702 | |
703 if (cf->referers == NULL) { | |
501 | 704 e->sp->value = 0; |
705 e->sp->text.len = 0; | |
706 e->sp->text.data = (u_char *) ""; | |
707 e->sp++; | |
708 | |
485 | 709 return; |
710 } | |
711 | |
712 if (r->headers_in.referer == NULL) { | |
713 if (cf->no_referer) { | |
501 | 714 e->sp->value = 0; |
715 e->sp->text.len = 0; | |
716 e->sp->text.data = (u_char *) ""; | |
717 e->sp++; | |
718 | |
485 | 719 return; |
505 | 720 |
485 | 721 } else { |
501 | 722 e->sp->value = 1; |
723 e->sp->text.len = 1; | |
724 e->sp->text.data = (u_char *) "1"; | |
725 e->sp++; | |
726 | |
485 | 727 return; |
728 } | |
729 } | |
730 | |
731 len = r->headers_in.referer->value.len; | |
732 ref = r->headers_in.referer->value.data; | |
733 | |
734 if (len < sizeof("http://i.ru") - 1 | |
735 || (ngx_strncasecmp(ref, "http://", 7) != 0)) | |
736 { | |
505 | 737 if (cf->blocked_referer) { |
738 e->sp->value = 0; | |
739 e->sp->text.len = 0; | |
740 e->sp->text.data = (u_char *) "0"; | |
741 e->sp++; | |
742 | |
743 return; | |
501 | 744 |
505 | 745 } else { |
746 e->sp->value = 1; | |
747 e->sp->text.len = 1; | |
748 e->sp->text.data = (u_char *) "1"; | |
749 e->sp++; | |
750 | |
751 return; | |
752 } | |
485 | 753 } |
754 | |
755 len -= 7; | |
756 ref += 7; | |
757 | |
758 refs = cf->referers->elts; | |
759 for (i = 0; i < cf->referers->nelts; i++ ){ | |
760 | |
761 if (refs[i].name.len > len) { | |
762 continue; | |
763 } | |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
764 |
485 | 765 if (refs[i].wildcard) { |
766 for (n = 0; n < len; n++) { | |
767 if (ref[n] == '/' || ref[n] == ':') { | |
768 break; | |
769 } | |
770 | |
771 if (ref[n] != '.') { | |
772 continue; | |
773 } | |
774 | |
775 if (ngx_strncmp(&ref[n], refs[i].name.data, | |
776 refs[i].name.len) == 0) | |
777 { | |
501 | 778 e->sp->value = 0; |
779 e->sp->text.len = 0; | |
780 e->sp->text.data = (u_char *) ""; | |
781 e->sp++; | |
782 | |
485 | 783 return; |
784 } | |
785 } | |
786 | |
787 } else { | |
788 if (ngx_strncasecmp(refs[i].name.data, ref, refs[i].name.len) == 0) | |
789 { | |
501 | 790 e->sp->value = 0; |
791 e->sp->text.len = 0; | |
792 e->sp->text.data = (u_char *) ""; | |
793 e->sp++; | |
794 | |
485 | 795 return; |
796 } | |
797 } | |
798 } | |
325
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
799 |
501 | 800 e->sp->value = 1; |
801 e->sp->text.len = 1; | |
802 e->sp->text.data = (u_char *) "1"; | |
803 e->sp++; | |
485 | 804 } |
805 | |
806 | |
487 | 807 static void |
808 ngx_http_rewrite_nop_code(ngx_http_rewrite_engine_t *e) | |
485 | 809 { |
810 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
|
811 } |
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
812 |
7c3323909107
nginx-0.0.3-2004-04-23-20:50:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
813 |
501 | 814 static ngx_http_variable_value_t * |
815 ngx_http_rewrite_var(ngx_http_request_t *r, uintptr_t data) | |
816 { | |
817 ngx_http_variable_t *var; | |
818 ngx_http_core_main_conf_t *cmcf; | |
819 | |
820 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); | |
821 | |
822 var = cmcf->variables.elts; | |
823 | |
824 /* | |
825 * the ngx_http_rewrite_module sets variables directly in r->variables, | |
826 * and they should be handle by ngx_http_get_indexed_variable(), | |
827 * so the handler is called only if the variable is not initialized | |
828 */ | |
829 | |
830 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | |
831 "using uninitialized \"%V\" variable", &var[data].name); | |
832 | |
833 return &ngx_http_rewrite_null_value; | |
834 } | |
835 | |
836 | |
487 | 837 static ngx_int_t |
838 ngx_http_rewrite_init(ngx_cycle_t *cycle) | |
485 | 839 { |
840 ngx_http_handler_pt *h; | |
841 ngx_http_core_main_conf_t *cmcf; | |
842 | |
843 cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); | |
844 | |
501 | 845 h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers); |
485 | 846 if (h == NULL) { |
847 return NGX_ERROR; | |
848 } | |
849 | |
850 *h = ngx_http_rewrite_handler; | |
851 | |
852 return NGX_OK; | |
853 } | |
854 | |
855 | |
487 | 856 static void * |
857 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
|
858 { |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
859 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
|
860 |
501 | 861 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_rewrite_loc_conf_t)); |
862 if (conf == NULL) { | |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
863 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
|
864 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
865 |
485 | 866 conf->stack_size = NGX_CONF_UNSET_UINT; |
867 conf->log = NGX_CONF_UNSET; | |
868 conf->no_referer = NGX_CONF_UNSET; | |
505 | 869 conf->blocked_referer = NGX_CONF_UNSET; |
485 | 870 |
437
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
871 return conf; |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
872 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
873 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
874 |
487 | 875 static char * |
876 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
|
877 { |
485 | 878 ngx_http_rewrite_loc_conf_t *prev = parent; |
879 ngx_http_rewrite_loc_conf_t *conf = child; | |
880 | |
881 uintptr_t *code, *last; | |
882 ngx_http_rewrite_regex_code_t *regex; | |
883 | |
884 ngx_conf_merge_value(conf->log, prev->log, 0); | |
885 ngx_conf_merge_unsigned_value(conf->stack_size, prev->stack_size, 10); | |
886 | |
887 if (conf->referers == NULL) { | |
888 conf->referers = prev->referers; | |
889 ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0); | |
505 | 890 ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0); |
485 | 891 } |
892 | |
499 | 893 if (conf->no_referer == NGX_CONF_UNSET) { |
894 conf->no_referer = 0; | |
895 } | |
896 | |
505 | 897 if (conf->blocked_referer == NGX_CONF_UNSET) { |
898 conf->blocked_referer = 0; | |
899 } | |
900 | |
485 | 901 if (conf->codes == NULL) { |
902 return NGX_CONF_OK; | |
903 } | |
904 | |
905 if (conf->codes == prev->codes) { | |
906 return NGX_CONF_OK; | |
907 } | |
908 | |
909 code = conf->codes->elts; | |
910 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
|
911 |
485 | 912 while (code < last) { |
913 if (*code == (uintptr_t) NULL) { | |
914 return NGX_CONF_OK; | |
915 } | |
916 | |
917 if (*code == (uintptr_t) &ngx_http_rewrite_regex_start_code) { | |
918 regex = (ngx_http_rewrite_regex_code_t *) code; | |
919 if (conf->max_captures < regex->ncaptures) { | |
920 conf->max_captures = regex->ncaptures; | |
921 } | |
922 code = (uintptr_t *) ((u_char *) code + regex->next); | |
501 | 923 continue; |
485 | 924 } |
925 | |
926 if (*code == (uintptr_t) &ngx_http_rewrite_if_code) { | |
927 code += sizeof(ngx_http_rewrite_if_code_t) / sizeof(uintptr_t); | |
501 | 928 continue; |
485 | 929 } |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
930 |
485 | 931 if (*code == (uintptr_t) &ngx_http_rewrite_return_code) { |
932 code += sizeof(ngx_http_rewrite_return_code_t) / sizeof(uintptr_t); | |
501 | 933 continue; |
934 } | |
935 | |
936 if (*code == (uintptr_t) &ngx_http_rewrite_set_var_code) { | |
937 code += sizeof(ngx_http_rewrite_var_code_t) / sizeof(uintptr_t); | |
938 continue; | |
485 | 939 } |
940 | |
941 if (*code == (uintptr_t) &ngx_http_rewrite_var_code) { | |
942 code += sizeof(ngx_http_rewrite_var_code_t) / sizeof(uintptr_t); | |
501 | 943 continue; |
944 } | |
945 | |
946 if (*code == (uintptr_t) &ngx_http_rewrite_value_code) { | |
947 code += sizeof(ngx_http_rewrite_value_code_t) / sizeof(uintptr_t); | |
948 continue; | |
485 | 949 } |
950 | |
951 if (*code == (uintptr_t) &ngx_http_rewrite_invalid_referer_code) { | |
952 code++; | |
501 | 953 continue; |
485 | 954 } |
955 | |
956 if (*code == (uintptr_t) &ngx_http_rewrite_nop_code) { | |
957 code++; | |
501 | 958 continue; |
485 | 959 } |
501 | 960 |
961 #if (NGX_DEBUG) | |
962 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
963 "unknown rewrite code: %p", *code); | |
964 return NGX_CONF_ERROR; | |
965 #endif | |
485 | 966 } |
967 | |
501 | 968 code = ngx_array_push_n(conf->codes, sizeof(uintptr_t)); |
969 if (code == NULL) { | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
970 return NGX_CONF_ERROR; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
971 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
972 |
485 | 973 *code = (uintptr_t) NULL; |
974 | |
975 return NGX_CONF_OK; | |
976 } | |
977 | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
978 |
487 | 979 static char * |
980 ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
485 | 981 { |
982 ngx_http_rewrite_loc_conf_t *lcf = conf; | |
983 | |
984 u_char *data; | |
985 size_t len, size; | |
986 ngx_str_t *value, err; | |
501 | 987 ngx_int_t n; |
988 ngx_uint_t i, last; | |
485 | 989 ngx_http_rewrite_code_pt *code; |
990 ngx_http_rewrite_copy_code_t *copy; | |
991 ngx_http_rewrite_regex_code_t *regex; | |
992 ngx_http_rewrite_regex_end_code_t *regex_end; | |
993 ngx_http_rewrite_copy_capture_code_t *copy_capture; | |
994 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
995 | |
996 regex = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
997 sizeof(ngx_http_rewrite_regex_code_t)); | |
998 if (regex == NULL) { | |
999 return NGX_CONF_ERROR; | |
1000 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1001 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1002 value = cf->args->elts; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1003 |
485 | 1004 err.len = NGX_MAX_CONF_ERRSTR; |
1005 err.data = errstr; | |
1006 | |
1007 /* TODO: NGX_REGEX_CASELESS */ | |
1008 | |
1009 regex->regex = ngx_regex_compile(&value[1], 0, cf->pool, &err); | |
1010 | |
1011 if (regex->regex == NULL) { | |
1012 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | |
1013 return NGX_CONF_ERROR; | |
1014 } | |
1015 | |
1016 regex->code = ngx_http_rewrite_regex_start_code; | |
1017 regex->size = 0; | |
1018 regex->ncaptures = 0; | |
1019 regex->status = 0; | |
501 | 1020 regex->test = 0; |
485 | 1021 regex->uri = 1; |
1022 regex->args = 1; | |
1023 regex->redirect = 0; | |
1024 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
|
1025 |
485 | 1026 last = 0; |
1027 | |
1028 if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0) { | |
1029 regex->status = NGX_HTTP_MOVED_TEMPORARILY; | |
1030 regex->redirect = 1; | |
1031 last = 1; | |
1032 } | |
1033 | |
1034 if (cf->args->nelts == 4) { | |
1035 if (ngx_strcmp(value[3].data, "last") == 0) { | |
1036 last = 1; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1037 |
487 | 1038 } else if (ngx_strcmp(value[3].data, "break") == 0) { |
1039 regex->break_cycle = 1; | |
1040 last = 1; | |
1041 | |
485 | 1042 } else if (ngx_strcmp(value[3].data, "redirect") == 0) { |
1043 regex->status = NGX_HTTP_MOVED_TEMPORARILY; | |
1044 regex->redirect = 1; | |
1045 last = 1; | |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
1046 |
485 | 1047 } else if (ngx_strcmp(value[3].data, "permanent") == 0) { |
1048 regex->status = NGX_HTTP_MOVED_PERMANENTLY; | |
1049 regex->redirect = 1; | |
1050 last = 1; | |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
1051 |
485 | 1052 } else { |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
1053 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
461 | 1054 "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
|
1055 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
|
1056 } |
485 | 1057 } |
326
8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
Igor Sysoev <igor@sysoev.ru>
parents:
325
diff
changeset
|
1058 |
485 | 1059 i = 0; |
1060 | |
1061 while (i < value[2].len) { | |
1062 | |
1063 data = &value[2].data[i]; | |
483 | 1064 |
485 | 1065 if (value[2].data[i] == '$' && i < value[2].len |
1066 && value[2].data[i + 1] >= '1' && value[2].data[i + 1] <= '9') | |
1067 { | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1068 |
485 | 1069 /* the "$1" - "$9" captures */ |
1070 | |
1071 copy_capture = ngx_http_rewrite_add_code(lcf->codes, | |
1072 sizeof(ngx_http_rewrite_copy_capture_code_t), | |
487 | 1073 ®ex); |
485 | 1074 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
|
1075 return NGX_CONF_ERROR; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1076 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1077 |
485 | 1078 i++; |
1079 | |
1080 copy_capture->code = ngx_http_rewrite_copy_capture_code; | |
1081 copy_capture->n = value[2].data[i] - '0'; | |
1082 | |
1083 if (regex->ncaptures < copy_capture->n) { | |
1084 regex->ncaptures = copy_capture->n; | |
1085 } | |
1086 | |
1087 copy_capture->n *= 2; | |
1088 | |
1089 i++; | |
1090 | |
1091 continue; | |
1092 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1093 |
485 | 1094 if (value[2].data[i] == '?') { |
1095 | |
1096 /* the arguments */ | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1097 |
485 | 1098 if (i == value[2].len - 1) { |
1099 /* the last "?" drops the original arguments */ | |
1100 regex->args = 0; | |
1101 break; | |
1102 } | |
1103 | |
1104 if (!regex->redirect) { | |
1105 code = ngx_http_rewrite_add_code(lcf->codes, sizeof(uintptr_t), | |
487 | 1106 ®ex); |
485 | 1107 if (code == NULL) { |
1108 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
|
1109 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1110 |
485 | 1111 *code = ngx_http_rewrite_start_args_code; |
1112 | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1113 i++; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1114 |
483 | 1115 continue; |
1116 } | |
485 | 1117 } |
1118 | |
1119 i++; | |
1120 | |
1121 /* the substituion strings */ | |
1122 | |
1123 while (i < value[2].len && value[2].data[i] != '$') { | |
483 | 1124 |
1125 if (value[2].data[i] == '?') { | |
1126 | |
485 | 1127 if (i == value[2].len - 1) { |
1128 /* | |
1129 * the last "?" drops the original arguments, | |
1130 * and it should not be copied to a substituion | |
1131 */ | |
1132 regex->args = 0; | |
1133 break; | |
1134 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1135 |
485 | 1136 if (!regex->redirect) { |
1137 break; | |
1138 } | |
483 | 1139 } |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1140 |
483 | 1141 i++; |
485 | 1142 } |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1143 |
485 | 1144 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
|
1145 |
485 | 1146 if (len == 0) { |
1147 continue; | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1148 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1149 |
485 | 1150 regex->size += len; |
1151 | |
1152 size = (len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1); | |
481 | 1153 |
485 | 1154 copy = ngx_http_rewrite_add_code(lcf->codes, |
1155 sizeof(ngx_http_rewrite_copy_code_t) + size, | |
487 | 1156 ®ex); |
485 | 1157 if (copy == NULL) { |
481 | 1158 return NGX_CONF_ERROR; |
1159 } | |
1160 | |
485 | 1161 copy->code = ngx_http_rewrite_copy_code; |
1162 copy->len = len; | |
1163 | |
1164 ngx_memcpy((u_char *) copy + sizeof(ngx_http_rewrite_copy_code_t), | |
1165 data, len); | |
1166 } | |
1167 | |
1168 n = ngx_regex_capture_count(regex->regex); | |
1169 | |
501 | 1170 if (n < 0) { |
1171 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1172 ngx_regex_capture_count_n " failed for " | |
1173 "pattern \"%V\"", &value[1]); | |
1174 return NGX_CONF_ERROR; | |
1175 } | |
1176 | |
1177 if (regex->ncaptures > (ngx_uint_t) n) { | |
485 | 1178 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
1179 "pattern \"%V\" has less captures " | |
1180 "than referrenced in substitution \"%V\"", | |
1181 &value[1], &value[2]); | |
1182 return NGX_CONF_ERROR; | |
1183 } | |
1184 | |
501 | 1185 if (regex->ncaptures < (ngx_uint_t) n) { |
1186 regex->ncaptures = (ngx_uint_t) n; | |
485 | 1187 } |
481 | 1188 |
485 | 1189 if (regex->ncaptures) { |
1190 regex->ncaptures = (regex->ncaptures + 1) * 3; | |
1191 } | |
1192 | |
1193 regex_end = ngx_http_rewrite_add_code(lcf->codes, | |
1194 sizeof(ngx_http_rewrite_regex_end_code_t), | |
487 | 1195 ®ex); |
485 | 1196 if (regex_end == NULL) { |
1197 return NGX_CONF_ERROR; | |
1198 } | |
1199 | |
1200 regex_end->code = ngx_http_rewrite_regex_end_code; | |
1201 regex_end->uri = regex->uri; | |
1202 regex_end->args = regex->args; | |
1203 regex_end->redirect = regex->redirect; | |
1204 | |
1205 if (last) { | |
1206 code = ngx_http_rewrite_add_code(lcf->codes, sizeof(uintptr_t), | |
487 | 1207 ®ex); |
485 | 1208 if (code == NULL) { |
1209 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
|
1210 } |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1211 |
485 | 1212 *code = (uintptr_t) NULL; |
1213 } | |
1214 | |
1215 regex->next = (u_char *) lcf->codes->elts + lcf->codes->nelts | |
1216 - (u_char *) regex; | |
1217 | |
1218 return NGX_CONF_OK; | |
1219 } | |
1220 | |
1221 | |
487 | 1222 static char * |
1223 ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
485 | 1224 { |
1225 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
|
1226 |
485 | 1227 ngx_str_t *value; |
1228 ngx_http_rewrite_return_code_t *ret; | |
1229 | |
1230 ret = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
1231 sizeof(ngx_http_rewrite_return_code_t)); | |
1232 if (ret == NULL) { | |
1233 return NGX_CONF_ERROR; | |
1234 } | |
1235 | |
1236 value = cf->args->elts; | |
1237 | |
1238 ret->code = ngx_http_rewrite_return_code; | |
1239 ret->null = (uintptr_t) NULL; | |
1240 | |
1241 ret->status = ngx_atoi(value[1].data, value[1].len); | |
1242 | |
1243 if (ret->status == (uintptr_t) NGX_ERROR) { | |
1244 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
|
1245 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1246 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1247 return NGX_CONF_OK; |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1248 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1249 |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1250 |
487 | 1251 static char * |
1252 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
|
1253 { |
485 | 1254 ngx_http_rewrite_loc_conf_t *lcf = conf; |
1255 | |
1256 void *mconf; | |
1257 char *rv; | |
1258 u_char *elts; | |
1259 ngx_uint_t i; | |
1260 ngx_conf_t save; | |
1261 ngx_http_module_t *module; | |
1262 ngx_http_conf_ctx_t *ctx, *pctx; | |
1263 ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp; | |
1264 ngx_http_rewrite_if_code_t *if_code; | |
1265 ngx_http_rewrite_loc_conf_t *nlcf; | |
1266 | |
501 | 1267 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); |
1268 if (ctx == NULL) { | |
485 | 1269 return NGX_CONF_ERROR; |
1270 } | |
1271 | |
1272 pctx = cf->ctx; | |
1273 ctx->main_conf = pctx->main_conf; | |
1274 ctx->srv_conf = pctx->srv_conf; | |
1275 | |
1276 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); | |
1277 if (ctx->loc_conf == NULL) { | |
1278 return NGX_CONF_ERROR; | |
1279 } | |
1280 | |
1281 for (i = 0; ngx_modules[i]; i++) { | |
1282 if (ngx_modules[i]->type != NGX_HTTP_MODULE) { | |
1283 continue; | |
1284 } | |
1285 | |
1286 module = ngx_modules[i]->ctx; | |
1287 | |
1288 if (module->create_loc_conf) { | |
1289 | |
501 | 1290 mconf = module->create_loc_conf(cf); |
1291 if (mconf == NULL) { | |
485 | 1292 return NGX_CONF_ERROR; |
1293 } | |
1294 | |
1295 ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf; | |
1296 } | |
1297 } | |
1298 | |
1299 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index]; | |
1300 | |
1301 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; | |
1302 clcf->loc_conf = ctx->loc_conf; | |
1303 clcf->name = pclcf->name; | |
1304 clcf->noname = 1; | |
1305 | |
1306 if (pclcf->locations.elts == NULL) { | |
1307 if (ngx_array_init(&pclcf->locations, cf->pool, 4, sizeof(void *)) | |
1308 == NGX_ERROR) | |
1309 { | |
1310 return NGX_CONF_ERROR; | |
1311 } | |
1312 } | |
1313 | |
501 | 1314 clcfp = ngx_array_push(&pclcf->locations); |
1315 if (clcfp == NULL) { | |
485 | 1316 return NGX_CONF_ERROR; |
1317 } | |
1318 | |
1319 *clcfp = clcf; | |
1320 | |
1321 | |
501 | 1322 if (ngx_http_rewrite_if_condition(cf, lcf) != NGX_CONF_OK) { |
485 | 1323 return NGX_CONF_ERROR; |
1324 } | |
1325 | |
1326 if_code = ngx_array_push_n(lcf->codes, sizeof(ngx_http_rewrite_if_code_t)); | |
1327 if (if_code == NULL) { | |
1328 return NULL; | |
1329 } | |
1330 | |
1331 if_code->code = ngx_http_rewrite_if_code; | |
1332 | |
1333 elts = lcf->codes->elts; | |
1334 | |
1335 | |
1336 /* the inside directives must compile to the same code array */ | |
1337 | |
1338 nlcf = ctx->loc_conf[ngx_http_rewrite_module.ctx_index]; | |
1339 nlcf->codes = lcf->codes; | |
1340 | |
1341 | |
1342 save = *cf; | |
1343 cf->ctx = ctx; | |
1344 | |
1345 if (pclcf->name.len == 0) { | |
1346 if_code->loc_conf = NULL; | |
1347 cf->cmd_type = NGX_HTTP_SIF_CONF; | |
1348 | |
1349 } else { | |
1350 if_code->loc_conf = ctx->loc_conf; | |
1351 cf->cmd_type = NGX_HTTP_LIF_CONF; | |
1352 } | |
1353 | |
1354 rv = ngx_conf_parse(cf, NULL); | |
1355 | |
1356 *cf = save; | |
1357 | |
1358 if (rv != NGX_CONF_OK) { | |
1359 return rv; | |
1360 } | |
1361 | |
1362 | |
1363 if (elts != lcf->codes->elts) { | |
1364 if_code = (ngx_http_rewrite_if_code_t *) | |
1365 ((u_char *) if_code + ((u_char *) lcf->codes->elts - elts)); | |
1366 } | |
1367 | |
1368 if_code->next = (u_char *) lcf->codes->elts + lcf->codes->nelts | |
1369 - (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
|
1370 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
1371 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
|
1372 } |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
1373 |
470270fa84d2
nginx-0.0.12-2004-09-23-20:39:34 import
Igor Sysoev <igor@sysoev.ru>
parents:
396
diff
changeset
|
1374 |
487 | 1375 static char * |
501 | 1376 ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf) |
1377 { | |
1378 ngx_str_t *value, err; | |
1379 ngx_uint_t cur, last; | |
1380 ngx_http_rewrite_regex_code_t *regex; | |
1381 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
1382 | |
1383 value = cf->args->elts; | |
1384 last = cf->args->nelts - 1; | |
1385 | |
1386 if (value[1].len < 1 || value[1].data[0] != '(') { | |
1387 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1388 "invalid condition \"%V\"", &value[1]); | |
1389 return NGX_CONF_ERROR; | |
1390 } | |
1391 | |
1392 if (value[1].len == 1) { | |
1393 cur = 2; | |
1394 | |
1395 } else { | |
1396 cur = 1; | |
1397 value[1].len--; | |
1398 value[1].data++; | |
1399 } | |
1400 | |
1401 if (value[last].len < 1 || value[last].data[value[last].len - 1] != ')') { | |
1402 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1403 "invalid condition \"%V\"", &value[last]); | |
1404 return NGX_CONF_ERROR; | |
1405 } | |
1406 | |
1407 if (value[last].len == 1) { | |
1408 last--; | |
1409 | |
1410 } else { | |
1411 value[last].len--; | |
1412 value[last].data[value[last].len] = '\0'; | |
1413 } | |
1414 | |
1415 if (value[cur].len > 1 && value[cur].data[0] == '$') { | |
1416 | |
1417 if (cur != last && cur + 2 != last) { | |
1418 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1419 "invalid condition \"%V\"", &value[cur]); | |
1420 return NGX_CONF_ERROR; | |
1421 } | |
1422 | |
1423 if (ngx_http_rewrite_variable(cf, lcf, &value[cur])!= NGX_CONF_OK) { | |
1424 return NGX_CONF_ERROR; | |
1425 } | |
1426 | |
1427 if (cur == last) { | |
1428 return NGX_CONF_OK; | |
1429 } | |
1430 | |
1431 cur++; | |
1432 | |
1433 if ((value[cur].len == 1 && value[cur].data[0] != '~') | |
1434 || (value[cur].len == 2 | |
1435 && value[cur].data[0] != '~' && value[cur].data[1] != '*')) | |
1436 { | |
1437 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1438 "unexpected \"%V\" in condition", &value[cur]); | |
1439 return NGX_CONF_ERROR; | |
1440 } | |
1441 | |
1442 regex = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
1443 sizeof(ngx_http_rewrite_regex_code_t)); | |
1444 if (regex == NULL) { | |
1445 return NGX_CONF_ERROR; | |
1446 } | |
1447 | |
1448 err.len = NGX_MAX_CONF_ERRSTR; | |
1449 err.data = errstr; | |
1450 | |
1451 regex->regex = ngx_regex_compile(&value[last], | |
1452 (value[cur].len == 2) ? NGX_REGEX_CASELESS : 0, | |
1453 cf->pool, &err); | |
1454 | |
1455 if (regex->regex == NULL) { | |
1456 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data); | |
1457 return NGX_CONF_ERROR; | |
1458 } | |
1459 | |
1460 regex->code = ngx_http_rewrite_regex_start_code; | |
1461 regex->size = 0; | |
1462 regex->ncaptures = 0; | |
1463 regex->status = 0; | |
1464 regex->next = sizeof(ngx_http_rewrite_regex_code_t); | |
1465 regex->test = 1; | |
1466 regex->uri = 0; | |
1467 regex->args = 0; | |
1468 regex->redirect = 0; | |
1469 regex->name = value[last]; | |
1470 | |
1471 return NGX_CONF_OK; | |
1472 } | |
1473 | |
1474 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1475 "invalid condition \"%V\"", &value[cur]); | |
1476 | |
1477 return NGX_CONF_ERROR; | |
1478 } | |
1479 | |
1480 | |
1481 static char * | |
1482 ngx_http_rewrite_variable(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf, | |
1483 ngx_str_t *value) | |
1484 { | |
1485 ngx_http_variable_t *var; | |
1486 ngx_http_rewrite_code_pt *code; | |
1487 ngx_http_rewrite_var_code_t *var_code; | |
1488 | |
1489 value->len--; | |
1490 value->data++; | |
1491 | |
1492 if (value->len == sizeof("invalid_referer") - 1 | |
1493 && ngx_strncmp(value->data, "invalid_referer", | |
1494 sizeof("invalid_referer") - 1) == 0) | |
1495 { | |
1496 code = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
1497 sizeof(ngx_http_rewrite_code_pt)); | |
1498 if (code == NULL) { | |
1499 return NGX_CONF_ERROR; | |
1500 } | |
1501 | |
1502 *code = ngx_http_rewrite_invalid_referer_code; | |
1503 | |
1504 } else { | |
1505 var = ngx_http_add_variable(cf, value, 0); | |
1506 | |
1507 if (var == NULL) { | |
1508 return NGX_CONF_ERROR; | |
1509 } | |
1510 | |
1511 var_code = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
1512 sizeof(ngx_http_rewrite_var_code_t)); | |
1513 if (var_code == NULL) { | |
1514 return NGX_CONF_ERROR; | |
1515 } | |
1516 | |
1517 var_code->code = ngx_http_rewrite_var_code; | |
1518 var_code->index = var->index; | |
1519 } | |
1520 | |
1521 return NGX_CONF_OK; | |
1522 } | |
1523 | |
1524 | |
1525 static char * | |
487 | 1526 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
|
1527 { |
485 | 1528 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
|
1529 |
485 | 1530 ngx_uint_t i, server_names; |
1531 ngx_str_t *value; | |
1532 ngx_http_server_name_t *sn; | |
1533 ngx_http_core_srv_conf_t *cscf; | |
1534 ngx_http_rewrite_referer_t *ref; | |
1535 | |
1536 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
|
1537 |
485 | 1538 if (lcf->referers == NULL) { |
1539 lcf->referers = ngx_array_create(cf->pool, | |
1540 cf->args->nelts + cscf->server_names.nelts, | |
1541 sizeof(ngx_http_rewrite_referer_t)); | |
1542 if (lcf->referers == NULL) { | |
1543 return NGX_CONF_ERROR; | |
1544 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1545 } |
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1546 |
485 | 1547 value = cf->args->elts; |
1548 server_names = 0; | |
1549 | |
1550 for (i = 1; i < cf->args->nelts; i++) { | |
1551 if (value[i].len == 0) { | |
1552 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1553 "invalid referer \"%V\"", &value[i]); | |
1554 return NGX_CONF_ERROR; | |
1555 } | |
1556 | |
1557 if (ngx_strcmp(value[i].data, "none") == 0) { | |
1558 lcf->no_referer = 1; | |
1559 continue; | |
1560 } | |
1561 | |
505 | 1562 if (ngx_strcmp(value[i].data, "blocked") == 0) { |
1563 lcf->blocked_referer = 1; | |
1564 continue; | |
1565 } | |
1566 | |
485 | 1567 if (ngx_strcmp(value[i].data, "server_names") == 0) { |
1568 server_names = 1; | |
1569 continue; | |
1570 } | |
1571 | |
501 | 1572 ref = ngx_array_push(lcf->referers); |
1573 if (ref == NULL) { | |
485 | 1574 return NGX_CONF_ERROR; |
1575 } | |
1576 | |
1577 if (value[i].data[0] != '*') { | |
1578 ref->name = value[i]; | |
1579 ref->wildcard = 0; | |
1580 continue; | |
1581 } | |
1582 | |
1583 if (value[i].data[1] != '.') { | |
1584 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1585 "invalid wildcard referer \"%V\"", &value[i]); | |
1586 return NGX_CONF_ERROR; | |
1587 } | |
1588 | |
1589 ref->name.len = value[i].len - 1; | |
1590 ref->name.data = value[i].data + 1; | |
1591 ref->wildcard = 1; | |
1592 } | |
1593 | |
1594 if (!server_names) { | |
1595 return NGX_CONF_OK; | |
1596 } | |
216
f1d0e5f09c1e
nginx-0.0.1-2003-12-25-23:26:58 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1597 |
485 | 1598 sn = cscf->server_names.elts; |
1599 for (i = 0; i < cscf->server_names.nelts; i++) { | |
501 | 1600 ref = ngx_array_push(lcf->referers); |
1601 if (ref == NULL) { | |
485 | 1602 return NGX_CONF_ERROR; |
1603 } | |
1604 | |
1605 ref->name.len = sn[i].name.len + 1; | |
501 | 1606 ref->name.data = ngx_palloc(cf->pool, ref->name.len); |
1607 if (ref->name.data == NULL) { | |
485 | 1608 return NGX_CONF_ERROR; |
1609 } | |
1610 | |
1611 ngx_memcpy(ref->name.data, sn[i].name.data, sn[i].name.len); | |
1612 ref->name.data[sn[i].name.len] = '/'; | |
1613 ref->wildcard = sn[i].wildcard; | |
1614 } | |
1615 | |
1616 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
|
1617 } |
485 | 1618 |
1619 | |
501 | 1620 static char * |
1621 ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1622 { | |
1623 ngx_http_rewrite_loc_conf_t *lcf = conf; | |
1624 | |
1625 ngx_int_t n; | |
1626 ngx_str_t *value; | |
1627 ngx_http_variable_t *v; | |
1628 ngx_http_rewrite_var_code_t *var; | |
1629 ngx_http_rewrite_value_code_t *val; | |
1630 | |
1631 value = cf->args->elts; | |
1632 | |
1633 if (value[1].data[0] != '$') { | |
1634 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1635 "invalid variable name \"%V\"", &value[1]); | |
1636 return NGX_CONF_ERROR; | |
1637 } | |
1638 | |
1639 value[1].len--; | |
1640 value[1].data++; | |
1641 | |
1642 v = ngx_http_add_variable(cf, &value[1], 1); | |
1643 if (v == NULL) { | |
1644 return NGX_CONF_ERROR; | |
1645 } | |
1646 | |
1647 v->handler = ngx_http_rewrite_var; | |
1648 v->data = v->index; | |
1649 | |
1650 val = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
1651 sizeof(ngx_http_rewrite_value_code_t)); | |
1652 if (val == NULL) { | |
1653 return NGX_CONF_ERROR; | |
1654 } | |
1655 | |
1656 n = ngx_atoi(value[2].data, value[2].len); | |
1657 | |
1658 if (n == NGX_ERROR) { | |
1659 n = 0; | |
1660 } | |
1661 | |
1662 val->code = ngx_http_rewrite_value_code; | |
1663 val->value = (uintptr_t) n; | |
1664 val->text_len = (uintptr_t) value[2].len; | |
1665 val->text_data = (uintptr_t) value[2].data; | |
1666 | |
1667 var = ngx_http_rewrite_start_code(cf->pool, &lcf->codes, | |
1668 sizeof(ngx_http_rewrite_var_code_t)); | |
1669 if (var == NULL) { | |
1670 return NGX_CONF_ERROR; | |
1671 } | |
1672 | |
1673 var->code = ngx_http_rewrite_set_var_code; | |
1674 var->index = (uintptr_t) v->index; | |
1675 | |
1676 return NGX_CONF_OK; | |
1677 } | |
1678 | |
1679 | |
487 | 1680 static void * |
1681 ngx_http_rewrite_start_code(ngx_pool_t *pool, ngx_array_t **codes, size_t size) | |
485 | 1682 { |
1683 if (*codes == NULL) { | |
501 | 1684 *codes = ngx_array_create(pool, 256, 1); |
1685 if (*codes == NULL) { | |
485 | 1686 return NULL; |
1687 } | |
1688 } | |
1689 | |
1690 return ngx_array_push_n(*codes, size); | |
1691 } | |
1692 | |
1693 | |
487 | 1694 static void * |
1695 ngx_http_rewrite_add_code(ngx_array_t *codes, size_t size, void *code) | |
485 | 1696 { |
487 | 1697 u_char *elts, **p; |
485 | 1698 void *new; |
1699 | |
1700 elts = codes->elts; | |
1701 | |
501 | 1702 new = ngx_array_push_n(codes, size); |
1703 if (new == NULL) { | |
485 | 1704 return NGX_CONF_ERROR; |
1705 } | |
1706 | |
1707 if (elts != codes->elts) { | |
487 | 1708 p = code; |
1709 *p += (u_char *) codes->elts - elts; | |
485 | 1710 } |
1711 | |
1712 return new; | |
1713 } |