src/server/webdav/webdav.c

Thu, 23 Feb 2012 13:10:04 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 23 Feb 2012 13:10:04 +0100
changeset 24
1a7853a4257e
parent 20
7b235fa88008
child 26
37ff8bf54b89
permissions
-rw-r--r--

removed some NSPR dependencies

13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2011 Olaf Wintermann. All rights reserved.
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 *
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 *
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 *
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
29 #include <stdio.h>
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
30 #include <stdlib.h>
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
31 #include <string.h>
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
32
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
33 #include "webdav.h"
15
cff9c4101dd7 Replaced old utils with ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 14
diff changeset
34 #include "../ucx/string.h"
14
b8bf95b39952 New source folder layout
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 13
diff changeset
35 #include "../util/pool.h"
b8bf95b39952 New source folder layout
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 13
diff changeset
36 #include "../util/pblock.h"
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
37
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
38 #include "davparser.h"
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
39
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
40 int webdav_service(pblock *pb, Session *sn, Request *rq) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
41 /* TODO:
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
42 * Dies ist die Implementierung für PROPFIND. Es sollte für jede webdav-
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
43 * Methode eine eigene Service-Funktion geben. Solange die anderen
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
44 * Methoden nicht implementiert werden, behandelt webdav_service nur
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
45 * PROPFIND.
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
46 */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
47
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
48 /* TODO: clean up if errors occurs */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
49
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
50 /* Get request body which contains the webdav XML request */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
51 char *xml_body;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
52 size_t xml_len = 0;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
53
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
54 char *ctlen = pblock_findkeyval(pb_key_content_length, rq->headers);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
55 if(ctlen) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
56 xml_len = atoi(ctlen);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
57 } else {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
58 /* invalid request */
20
7b235fa88008 Some fixes for mod_jk
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 15
diff changeset
59 printf("invalid request\n");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
60 return REQ_ABORTED;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
61 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
62
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
63 xml_body = pool_malloc(sn->pool, xml_len + 1);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
64 xml_body[xml_len] = 0;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
65 if(!xml_body) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
66 /* server error */
20
7b235fa88008 Some fixes for mod_jk
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 15
diff changeset
67 printf("server error\n");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
68 return REQ_ABORTED;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
69 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
70
24
1a7853a4257e removed some NSPR dependencies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 20
diff changeset
71 /* TODO: bug with multiple reads */
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
72 int r = 0;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
73 char *xb = xml_body;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
74 size_t xl = xml_len;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
75 while((r = netbuf_getbytes(sn->inbuf, xb, xl)) != NETBUF_EOF) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
76 xb += r;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
77 xl -= xml_len;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
80 PropfindRequest *davrq = dav_parse_propfind(sn, rq, xml_body, xml_len);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
81 davrq->sn = sn;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
82 davrq->rq = rq;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
83 davrq->propertyBackend = create_property_backend();
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
84 davrq->notFoundProps = NULL;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85 davrq->forbiddenProps = NULL;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
86 davrq->out = sbuf_new(512);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
87
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
88 /* write header */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
89 sbuf_puts(davrq->out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
90 sbuf_puts(davrq->out, "<D:multistatus xmlns:D=\"DAV:\">\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
91
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
92 /* get stat of file */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
93 char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
94 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96 struct stat st;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
97 if(stat(ppath, &st) != 0) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
98 perror("webdav_service: stat");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99 return REQ_ABORTED;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101 /* TODO: check for more modes */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102 if(S_ISDIR(st.st_mode)) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
103 DIR *dir = opendir(ppath);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104 if(dir == NULL) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
105 protocol_status(sn, rq, 500, NULL);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
106 printf("webdav_service: DIR is null\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
107 return REQ_ABORTED;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
109
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
110 struct dirent *f;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
111 while((f = readdir(dir)) != NULL) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
112 if(strcmp(f->d_name, ".") == 0 || strcmp(f->d_name, "..") == 0) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
113 continue;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
114 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
115
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
116 sstr_t filename = sstr(f->d_name);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
117 sstr_t _path = sstr(ppath);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
118 sstr_t _uri = sstr(uri);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
119
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
120 sstr_t newuri;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
121 newuri.length = filename.length + _uri.length;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
122 newuri.ptr = alloca(newuri.length + 1);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
123 newuri = sstrncat(2, newuri, _uri, filename);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
124
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
125 sstr_t newpath;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
126 newpath.length = _path.length + filename.length;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
127 newpath.ptr = alloca(newpath.length + 1);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
128 newpath = sstrncat(2, newpath, _path, filename);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
129
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
130 davrq->path = newpath.ptr;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
131 davrq->uri = newuri.ptr;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
132 dav_create_response(davrq);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
133 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
134 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
135 davrq->path = ppath;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
136 davrq->uri = uri;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
137 dav_create_response(davrq);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
138
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
139 sbuf_puts(davrq->out, "</D:multistatus>\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
140
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
141 /* send buffer to client */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
142 pblock_removekey(pb_key_content_type, rq->srvhdrs);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
143 pblock_nvinsert("content-type", "text/xml", rq->srvhdrs);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
144 pblock_nninsert("content-length", davrq->out->length, rq->srvhdrs);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
145
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
146 protocol_status(sn, rq, 207, NULL);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
147 http_start_response(sn, rq);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
148
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
149 net_write(sn->csd, davrq->out->ptr, davrq->out->length);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
150
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
151 return REQ_PROCEED;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
152 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
153
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
154 int dav_foreach_reqprop(UcxDlist *list, PropfindRequest *davrq) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
155 DavProperty *prop = list->data;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
156 int error = 0;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
157
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
158 char *str = davrq->propertyBackend->get_property(
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
159 davrq->propertyBackend,
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
160 davrq,
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
161 davrq->path,
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
162 prop->xmlns,
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
163 prop->name,
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
164 &error);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
165 if(str == NULL) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
166 UcxDlist **dl = NULL;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
167 if(error == 404) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
168 dl = &davrq->notFoundProps;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
169 } else {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
170 dl = &davrq->forbiddenProps;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
171 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
172 *dl = ucx_dlist_append(*dl, prop);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
173 } else {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
174 //printf("dav property: {%s|%s::%s\n", prop->xmlns, prop->name, str);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
175 sbuf_puts(davrq->out, "<D:");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
176 sbuf_puts(davrq->out, prop->name);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
177 sbuf_puts(davrq->out, ">");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
178 sbuf_puts(davrq->out, str);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
179 sbuf_puts(davrq->out, "</D:");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
180 sbuf_puts(davrq->out, prop->name);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
181 sbuf_puts(davrq->out, ">\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
182 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 return 0;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
184 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
185
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186 void dav_create_response(PropfindRequest *davrq) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
187 sbuf_puts(davrq->out, "<D:response>\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
188
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
189 sbuf_puts(davrq->out, "<D:href>");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
190 sbuf_puts(davrq->out, davrq->uri);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
191 sbuf_puts(davrq->out, "</D:href>\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
192
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
193 sbuf_puts(davrq->out, "<D:propstat>\n<D:prop>\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
194
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
195 ucx_dlist_foreach(
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
196 davrq->properties,
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
197 (ucx_callback)dav_foreach_reqprop,
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
198 davrq);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
199
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
200 sbuf_puts(davrq->out, "</D:prop>\n<D:status>HTTP/1.1 200 OK</D:status>\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
201 sbuf_puts(davrq->out, "</D:propstat>\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
202
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
203 /* 404 props */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
204 sbuf_puts(davrq->out, "<D:propstat>\n<D:prop>\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
205 UcxDlist *dl = davrq->notFoundProps;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
206 while(dl != NULL) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
207 DavProperty *nfp = dl->data;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
208 sbuf_puts(davrq->out, "<D:");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
209 sbuf_puts(davrq->out, nfp->name);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
210 sbuf_puts(davrq->out, " />\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
211 dl = dl->next;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
212 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
213 sbuf_puts(davrq->out, "</D:prop>\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
214 sbuf_puts(davrq->out, "<D:status>HTTP/1.1 404 Not Found</D:status>\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
215 sbuf_puts(davrq->out, "</D:propstat>\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
216
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
217 /* end */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
218 sbuf_puts(davrq->out, "</D:response>\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
219
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
220 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
221
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
222 char* dav_get_property(
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
223 DAVPropertyBackend *b,
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
224 PropfindRequest *davrq,
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
225 char *path,
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
226 char *xmlns,
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
227 char *name,
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
228 int *error)
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
229 {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
230 DAVDefaultBackend *be = (DAVDefaultBackend*)b;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
231 *error = 200;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
232
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
233 if(strcmp(name, "getcontentlength") == 0) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
234 struct stat s;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
235 if(stat(davrq->path, &s) != 0) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
236 *error = 403; /* really? */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
237 return NULL;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
238 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
239 if(S_ISDIR(s.st_mode)) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
240 *error = 404;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
241 return NULL;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
242 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
243 char *buf = pool_malloc(davrq->sn->pool, 24);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
244 sprintf(buf, "%d", s.st_size);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
245 return buf;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
246 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
247
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
248 *error = 404;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
249 return NULL;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
250 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
251
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
252 DAVPropertyBackend* create_property_backend() {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
253 DAVDefaultBackend *backend = malloc(sizeof(DAVDefaultBackend));
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
254 backend->backend.get_property = dav_get_property;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
255 backend->path = NULL;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
256 backend->s = 0;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
257 return (DAVPropertyBackend*)backend;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
258 }

mercurial