src/server/daemon/location.c

changeset 651
ed74879c7041
parent 650
3e4f9cdd70b8
child 652
dd90c858eb74
equal deleted inserted replaced
650:3e4f9cdd70b8 651:ed74879c7041
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 }

mercurial