src/server/daemon/location.c

changeset 636
40f069ddda37
parent 635
b85d45fd3b01
child 637
85721a583f39
equal deleted inserted replaced
635:b85d45fd3b01 636:40f069ddda37
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
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 "../util/util.h" 32 #include "../util/util.h"
33 #include "../util/pblock.h"
34 #include "vserver.h"
32 #include <cx/linked_list.h> 35 #include <cx/linked_list.h>
33 36
34 #define DIR_CHECK_ARGC(n) if(argc != n) { \ 37 #define DIR_CHECK_ARGC(n) if(argc != n) { \
35 log_ereport(LOG_FAILURE, "%s directive argc != %d", name.ptr, n); \ 38 log_ereport(LOG_FAILURE, "%s directive argc != %d", name.ptr, n); \
36 return 1; \ 39 return 1; \
40 void **begin = (void**)&location->children_begin; 43 void **begin = (void**)&location->children_begin;
41 void **end = (void**)&location->children_end; 44 void **end = (void**)&location->children_end;
42 cx_linked_list_add(begin, end, offsetof(WSLocation, prev), offsetof(WSLocation, next), sub); 45 cx_linked_list_add(begin, end, offsetof(WSLocation, prev), offsetof(WSLocation, next), sub);
43 } 46 }
44 47
45 static int add_location_config(const CxAllocator *a, WSLocation *location, ConfigNode *dir) { 48 static int add_location_config(ServerConfiguration *cfg, WSLocation *location, ConfigNode *dir) {
49 const CxAllocator *a = cfg->a;
50
46 cxmutstr name = dir->name; 51 cxmutstr name = dir->name;
47 int argc = serverconfig_directive_count_args(dir); 52 int argc = serverconfig_directive_count_args(dir);
48 if(!cx_strcasecmp(name, "DirectoryIndex")) { 53 if(!cx_strcasecmp(name, "DirectoryIndex")) {
49 DIR_CHECK_ARGC(1); 54 DIR_CHECK_ARGC(1);
50 location->config.set_dirindex = TRUE; 55 location->config.set_dirindex = TRUE;
51 location->config.dirindex = util_getboolean_s(cx_strcast(dir->args->value), FALSE); 56 location->config.dirindex = util_getboolean_s(cx_strcast(dir->args->value), FALSE);
52 } else if(!cx_strcasecmp(name, "DocumentRoot")) { 57 } else if(!cx_strcasecmp(name, "DocumentRoot")) {
53 DIR_CHECK_ARGC(1); 58 DIR_CHECK_ARGC(1);
54 location->config.docroot = cx_strdup_a(a, dir->args->value); 59 location->config.docroot = cx_strdup_a(a, dir->args->value);
55 } else if(!cx_strcasecmp(name, "Location")) { 60 } else if(!cx_strcasecmp(name, "Location")) {
56 WSLocation *sub_location = cfg_location_get(a, dir); 61 WSLocation *sub_location = cfg_location_get(cfg, dir);
57 if(!sub_location) { 62 if(!sub_location) {
58 return 1; 63 return 1;
59 } 64 }
60 location_list_add(location, sub_location); 65 location_list_add(location, sub_location);
61 } 66 }
62 67
63 return 0; 68 return 0;
64 } 69 }
65 70
66 71
67 WSLocation* cfg_location_get(const CxAllocator *a, ConfigNode *obj) { 72 WSLocation* cfg_location_get(ServerConfiguration *cfg, ConfigNode *obj) {
73 const CxAllocator *a = cfg->a;
74
68 WSLocationMatch match = WS_LOCATION_MATCH_EXACT; 75 WSLocationMatch match = WS_LOCATION_MATCH_EXACT;
69 cxmutstr match_str; 76 cxmutstr match_str;
70 77
71 int regex_flags = REG_EXTENDED; 78 int regex_flags = REG_EXTENDED | REG_NOSUB;
72 int argc = serverconfig_directive_count_args(obj); 79 int argc = serverconfig_directive_count_args(obj);
73 if(argc == 2) { 80 if(argc == 2) {
74 // arg0: match type 81 // arg0: match type
75 cxmutstr type_str = obj->args->value; 82 cxmutstr type_str = obj->args->value;
76 if(!cx_strcmp(type_str, "=")) { 83 if(!cx_strcmp(type_str, "=")) {
108 } 115 }
109 116
110 ConfigNode *dir = obj->children_begin; 117 ConfigNode *dir = obj->children_begin;
111 while(dir) { 118 while(dir) {
112 if(dir->type == CONFIG_NODE_OBJECT || dir->type == CONFIG_NODE_DIRECTIVE) { 119 if(dir->type == CONFIG_NODE_OBJECT || dir->type == CONFIG_NODE_DIRECTIVE) {
113 if(add_location_config(a, location, dir)) { 120 if(add_location_config(cfg, location, dir)) {
114 log_ereport(LOG_FAILURE, "Location %s: abort", match_str.ptr); 121 log_ereport(LOG_FAILURE, "Location %s: abort", match_str.ptr);
115 return NULL; 122 return NULL;
116 } 123 }
117 } 124 }
118 dir = dir->next; 125 dir = dir->next;
120 127
121 128
122 129
123 return location; 130 return location;
124 } 131 }
132
133 int location_apply_config(WSLocationConfig *target, WSLocation *loc) {
134 WSLocationConfig *src = &loc->config;
135 if(src->set_dirindex) {
136 target->set_dirindex = TRUE;
137 target->dirindex = src->dirindex;
138 }
139 if(src->set_forcetls) {
140 target->set_forcetls = TRUE;
141 target->forcetls = src->forcetls;
142 }
143 if(src->docroot.ptr) {
144 target->docroot = src->docroot;
145 }
146 if(src->name.ptr) {
147 target->name = src->name;
148 }
149 if(src->dav) {
150 target->dav = src->dav;
151 }
152 // TODO: ...
153
154 return 0;
155 }
156
157 int location_match(WSLocation *loc, cxstring uri) {
158 if(loc->match == WS_LOCATION_MATCH_EXACT) {
159 return !cx_strcmp(loc->match_string, uri);
160 } else if(loc->match == WS_LOCATION_MATCH_PREFIX) {
161 return cx_strprefix(uri, loc->match_string);
162 } else {
163 return regexec(&loc->regex, uri.ptr, 0, NULL, 0) == 0;
164 }
165 return 0;
166 }
167
168 WSLocationConfig* location_match_and_get_config(pool_handle_t *pool, cxstring uri, WSLocation *loc) {
169 WSLocationConfig *config = pool_malloc(pool, sizeof(WSLocationConfig));
170 if(!config) {
171 return NULL;
172 }
173 ZERO(config, sizeof(WSLocationConfig));
174
175 while(loc) {
176 if(location_match(loc, uri)) {
177 if(location_apply_config(config, loc)) {
178 return NULL;
179 }
180 }
181 loc = loc->next;
182 }
183
184
185 return config;
186 }
187
188 WSLocationConfig* cfg_location_match(Session *sn, Request *rq) {
189 NSAPIRequest *req = (NSAPIRequest*)rq;
190 WSLocation *loc = req->vs->locations_begin;
191 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
192 return location_match_and_get_config(sn->pool, cx_str(uri), loc);
193 }

mercurial