1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include "nametrans.h"
30
31 #include "../daemon/log.h"
32 #include "../daemon/request.h"
33 #include "../util/pblock.h"
34 #include "../util/util.h"
35 #include "../public/webdav.h"
36
37 #include "../daemon/session.h"
38 #include "../daemon/config.h"
39
40 #include "../public/vfs.h"
41
42 static int initialize_dav_repo(pblock *pb, Session *sn, Request *rq, WebdavRepository *repo) {
43 if(repo->vfs) {
44 VFS *vfs = repo->vfs->create(sn, rq, pb, repo->vfsInitData);
45 if(!vfs) {
46 return REQ_ABORTED;
47 }
48 rq->vfs = vfs;
49 }
50
51 void *backend_first =
NULL;
52 void *backend_last =
NULL;
53 CxIterator i = cxListIterator(repo->davBackends);
54 cx_foreach(WebdavBackendInitData *, davInit, i) {
55 WebdavBackend *backend = davInit->davType->create(sn, rq, pb, davInit->davInitData);
56 if(!backend) {
57 return REQ_ABORTED;
58 }
59 cx_linked_list_add(&backend_first, &backend_last, -
1, offsetof(WebdavBackend, next), backend);
60 }
61 rq->davCollection = backend_first;
62
63 return 0;
64 }
65
66 static int nametrans_set_dav_repository(pblock *pb, Session *sn, Request *rq) {
67 char *dav = pblock_findkeyval(pb_key_dav, pb);
68 if(!dav)
return 0;
69
70 ServerConfiguration *config = session_get_config(sn);
71 WebdavRepository *repo = cxMapGet(config->dav, cx_hash_key_str(dav));
72
73 if(!repo) {
74 log_ereport(
LOG_MISCONFIG,
"nametrans: unknown dav repository ''%s''", dav);
75 return REQ_ABORTED;
76 }
77
78 return initialize_dav_repo(pb, sn, rq, repo);
79 }
80
81 static int nametrans_set_vfs(pblock *pb, Session *sn, Request *rq) {
82 char *vfsclass = pblock_findkeyval(pb_key_vfsclass, pb);
83 if(!vfsclass)
return 0;
84
85 VFS *vfs = vfs_create(sn, rq, vfsclass, pb,
NULL);
86 if(!vfs) {
87 return 1;
88 }
89 rq->vfs = vfs;
90 return 0;
91 }
92
93 static int nametrans_set_dav(pblock *pb, Session *sn, Request *rq) {
94 char *davclass = pblock_findkeyval(pb_key_davclass, pb);
95 if(!davclass)
return 0;
96
97 WebdavBackend *dav = webdav_create(sn, rq, davclass, pb,
NULL);
98
99 rq->davCollection = dav;
100 return 0;
101 }
102
103
104
105
106
107
108
109
110
111
112
113 int assign_name(pblock *pb, Session *sn, Request *rq) {
114
115
116 char *name = pblock_findkeyval(pb_key_name, pb);
117 char *from = pblock_findkeyval(pb_key_from, pb);
118
119 if(!name) {
120 log_ereport(
LOG_MISCONFIG,
"assign-name: missing name parameter");
121 protocol_status(sn, rq,
500,
NULL);
122 return REQ_ABORTED;
123 }
124
125 if(from) {
126 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
127 char c;
128 int i =
0;
129 while((c = from[i]) !=
0) {
130 if(c != uri[i]) {
131 return REQ_NOACTION;
132 }
133 i++;
134 }
135 }
136
137 if(nametrans_set_dav_repository(pb, sn, rq)) {
138 log_ereport(
LOG_FAILURE,
"assign-name: cannot create dav repository: name=%s from=%s", name, from);
139 return REQ_ABORTED;
140 }
141 if(nametrans_set_vfs(pb, sn, rq)) {
142 log_ereport(
LOG_FAILURE,
"assign-name: cannot create VFS: name=%s from=%s", name, from);
143 return REQ_ABORTED;
144 }
145 if(nametrans_set_dav(pb, sn, rq)) {
146 log_ereport(
LOG_FAILURE,
"assign-name: cannot create Webdav Backend: name=%s from=%s", name, from);
147 return REQ_ABORTED;
148 }
149
150
151 pblock_kvinsert(pb_key_name, name, strlen(name), rq->vars);
152
153 return REQ_NOACTION;
154 }
155
156
157
158
159
160
161
162
163
164 int document_root(pblock *pb, Session *sn, Request *rq) {
165 char *root = pblock_findkeyval(pb_key_root, pb);
166 if(!root) {
167 log_ereport(
LOG_MISCONFIG,
"document-root: missing root parameter");
168 protocol_status(sn, rq,
500,
NULL);
169 return REQ_ABORTED;
170 }
171
172 if(nametrans_set_vfs(pb, sn, rq)) {
173 log_ereport(
LOG_FAILURE,
"document-root: cannot create VFS");
174 return REQ_ABORTED;
175 }
176
177 cxstring root_str = cx_str(root);
178 cxstring uri_str = cx_str(pblock_findkeyval(pb_key_uri, rq->reqpb));
179
180 request_set_path(root_str, uri_str, rq->vars);
181
182 return REQ_PROCEED;
183 }
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199 int pfx2dir(pblock *pb, Session *sn, Request *rq) {
200 char *from = pblock_findkeyval(pb_key_from, pb);
201 char *dir = pblock_findkeyval(pb_key_dir, pb);
202 char *name = pblock_findkeyval(pb_key_name, pb);
203
204 if(!from || !dir) {
205 if(!from && dir) {
206 log_ereport(
LOG_MISCONFIG,
"pfx2dir: missing from parameter");
207 }
else if(!dir && from) {
208 log_ereport(
LOG_MISCONFIG,
"pfx2dir: missing dir parameter");
209 }
else {
210 log_ereport(
211 LOG_MISCONFIG,
212 "pfx2dir: missing from and dir parameter");
213 }
214 protocol_status(sn, rq,
500,
NULL);
215 return REQ_ABORTED;
216 }
217
218
219 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
220 char fc;
221 char uc;
222 int i =
0;
223 while((fc = from[i]) !=
0) {
224 uc = uri[i];
225 if(fc != uc) {
226 return REQ_NOACTION;
227 }
228 i++;
229 }
230
231
232
233 uri = uri + i;
234 if(uri[
0] ==
'/') {
235 uri++;
236 }
237
238 if(nametrans_set_dav_repository(pb, sn, rq)) {
239 log_ereport(
LOG_FAILURE,
"pfx2dir: cannot create dav repository: from=%s dir=%s name=%s", from, dir, name);
240 return REQ_ABORTED;
241 }
242 if(nametrans_set_vfs(pb, sn, rq)) {
243 log_ereport(
LOG_FAILURE,
"pfx2dir: cannot create VFS: from=%s dir=%s name=%s", from, dir, name);
244 return REQ_ABORTED;
245 }
246 if(nametrans_set_dav(pb, sn, rq)) {
247 log_ereport(
LOG_FAILURE,
"pfx2dir: cannot create Webdav Backend: from=%s dir=%s name=%s", from, dir, name);
248 return REQ_ABORTED;
249 }
250
251 request_set_path(cx_str(dir), cx_str(uri), rq->vars);
252
253 if(name) {
254
255 pblock_kvinsert(pb_key_name, name, strlen(name), rq->vars);
256 }
257
258 return REQ_PROCEED;
259 }
260
261
262 int redirect(pblock *pb, Session *sn, Request *rq) {
263 char *from = pblock_findval(
"from", pb);
264 char *url = pblock_findval(
"url", pb);
265
266 if(!from || !url) {
267 log_ereport(
LOG_MISCONFIG,
"redirect: missing parameter (from, url)");
268 return REQ_ABORTED;
269 }
270
271 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
272 if(!strcmp(uri, from)) {
273 pblock_nvinsert(
"location", url, rq->srvhdrs);
274
275 protocol_status(sn, rq,
302,
NULL);
276 return REQ_ABORTED;
277 }
278
279 return REQ_NOACTION;
280 }
281
282
283
284
285 int simple_rewrite(pblock *pb, Session *sn, Request *rq) {
286 char *from = pblock_findval(
"from", pb);
287 char *root = pblock_findval(
"root", pb);
288 char *path = pblock_findval(
"path", pb);
289 char *name = pblock_findval(
"name", pb);
290
291 if(!from || !path || !root) {
292 log_ereport(
LOG_MISCONFIG,
"simple-rewrite: missing parameter (from, root, path)");
293 return REQ_ABORTED;
294 }
295
296 if(nametrans_set_vfs(pb, sn, rq)) {
297 log_ereport(
LOG_FAILURE,
"simple-rewrite: cannot create VFS: from=%s root=%s path=%s name=%s", from, root, path, name);
298 return REQ_ABORTED;
299 }
300
301 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
302 cxstring u = cx_str(uri);
303 cxstring f = cx_str(from);
304 if(cx_strprefix(u, f)) {
305 cxstring suf = cx_strsubs(u, f.length);
306 cxmutstr ppath = cx_strcat(
2, cx_str(path), suf);
307
308 request_set_path(cx_str(root), (cxstring){ppath.ptr, ppath.length}, rq->vars);
309 free(ppath.ptr);
310
311 if(name) {
312
313 pblock_kvinsert(pb_key_name, name, strlen(name), rq->vars);
314 }
315 }
316
317 return REQ_NOACTION;
318 }
319