| 27 */ |
27 */ |
| 28 |
28 |
| 29 #include "location.h" |
29 #include "location.h" |
| 30 #include "config.h" |
30 #include "config.h" |
| 31 #include "request.h" |
31 #include "request.h" |
| |
32 #include "rewrite.h" |
| 32 #include "../util/util.h" |
33 #include "../util/util.h" |
| 33 #include "../util/pblock.h" |
34 #include "../util/pblock.h" |
| |
35 #include "../util/pool.h" |
| 34 #include "vserver.h" |
36 #include "vserver.h" |
| 35 #include <cx/linked_list.h> |
37 #include <cx/linked_list.h> |
| 36 #include <cx/array_list.h> |
38 #include <cx/array_list.h> |
| 37 |
39 |
| 38 #define DIR_CHECK_ARGC(n) if(argc != n) { \ |
40 #define DIR_CHECK_ARGC(n) if(argc != n) { \ |
| 82 WSLocation *sub_location = cfg_location_get(cfg, dir); |
84 WSLocation *sub_location = cfg_location_get(cfg, dir); |
| 83 if(!sub_location) { |
85 if(!sub_location) { |
| 84 return 1; |
86 return 1; |
| 85 } |
87 } |
| 86 location_list_add(location, sub_location); |
88 location_list_add(location, sub_location); |
| |
89 } else if(!cx_strcasecmp(name, "Rewrite")) { |
| |
90 cxmutstr regex = (cxmutstr){NULL, 0}; |
| |
91 cxmutstr url = (cxmutstr){NULL, 0}; |
| |
92 if(argc == 1) { |
| |
93 // no custom rewrite regex |
| |
94 url = dir->args->value; |
| |
95 } else if(argc == 2) { |
| |
96 // regex, url |
| |
97 regex = dir->args->value; |
| |
98 url = dir->args->next->value; |
| |
99 } else { |
| |
100 log_ereport(LOG_FAILURE, "rewrite [regex] <url>: illegal argc %d", argc); |
| |
101 return 1; |
| |
102 } |
| |
103 |
| |
104 RewriteRule *rule = rewrite_rule_create(cfg, regex, url); |
| |
105 if(!rule) { |
| |
106 return 1; |
| |
107 } |
| |
108 |
| |
109 if(!location->rewrite) { |
| |
110 location->rewrite = cxLinkedListCreate(a, NULL, CX_STORE_POINTERS); |
| |
111 if(!location->rewrite) { |
| |
112 return 1; |
| |
113 } |
| |
114 } |
| |
115 |
| |
116 if(cxListAdd(location->rewrite, rule)) { |
| |
117 return 1; |
| |
118 } |
| 87 } |
119 } |
| 88 |
120 |
| 89 return 0; |
121 return 0; |
| 90 } |
122 } |
| 91 |
123 |
| 195 return regexec(&loc->regex, uri.ptr, 0, match, WS_LOCATION_NMATCH) == 0; |
227 return regexec(&loc->regex, uri.ptr, 0, match, WS_LOCATION_NMATCH) == 0; |
| 196 } |
228 } |
| 197 return 0; |
229 return 0; |
| 198 } |
230 } |
| 199 |
231 |
| 200 WSLocationConfig* location_match_and_get_config(pool_handle_t *pool, cxstring uri, WSLocation *loc) { |
232 WSLocationConfig* location_match_and_get_config(pool_handle_t *pool, Request *rq, cxstring uri, WSLocation *loc) { |
| 201 WSLocationConfig *config = pool_malloc(pool, sizeof(WSLocationConfig)); |
233 WSLocationConfig *config = pool_malloc(pool, sizeof(WSLocationConfig)); |
| 202 if(!config) { |
234 if(!config) { |
| 203 return NULL; |
235 return NULL; |
| 204 } |
236 } |
| 205 ZERO(config, sizeof(WSLocationConfig)); |
237 ZERO(config, sizeof(WSLocationConfig)); |
| 206 for(int i=0;i<WS_LOCATION_NMATCH;i++) { |
238 for(int i=0;i<WS_LOCATION_NMATCH;i++) { |
| 207 config->match[i].rm_so = -1; |
239 config->match[i].rm_so = -1; |
| 208 config->match[i].rm_eo = -1; |
240 config->match[i].rm_eo = -1; |
| 209 } |
241 } |
| 210 |
242 |
| |
243 const CxAllocator *a = pool_allocator(pool); |
| |
244 |
| 211 while(loc) { |
245 while(loc) { |
| 212 if(location_match(loc, uri, config->match)) { |
246 if(location_match(loc, uri, config->match)) { |
| |
247 // apply rewrite rules |
| |
248 CxIterator iter = cxListIterator(loc->rewrite); |
| |
249 cx_foreach(RewriteRule *, rule, iter) { |
| |
250 char *new_url = NULL; |
| |
251 if(!rewrite_url(rule, config->match, WS_LOCATION_NMATCH, a, uri.ptr, &new_url)) { |
| |
252 pblock_removekey(pb_key_uri, rq->reqpb); |
| |
253 if(pblock_kvinsert(pb_key_uri, new_url, strlen(new_url), rq->reqpb) == NULL) { |
| |
254 return NULL; |
| |
255 } |
| |
256 } |
| |
257 } |
| |
258 |
| 213 if(location_apply_config(config, loc)) { |
259 if(location_apply_config(config, loc)) { |
| 214 return NULL; |
260 return NULL; |
| 215 } |
261 } |
| 216 } |
262 } |
| 217 loc = loc->next; |
263 loc = loc->next; |
| 223 |
269 |
| 224 WSLocationConfig* cfg_location_match(Session *sn, Request *rq) { |
270 WSLocationConfig* cfg_location_match(Session *sn, Request *rq) { |
| 225 NSAPIRequest *req = (NSAPIRequest*)rq; |
271 NSAPIRequest *req = (NSAPIRequest*)rq; |
| 226 WSLocation *loc = req->vs->locations_begin; |
272 WSLocation *loc = req->vs->locations_begin; |
| 227 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb); |
273 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb); |
| 228 return location_match_and_get_config(sn->pool, cx_str(uri), loc); |
274 return location_match_and_get_config(sn->pool, rq, cx_str(uri), loc); |
| 229 } |
275 } |