src/server/webdav/webdav.c

Wed, 16 May 2012 12:47:28 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 16 May 2012 12:47:28 +0200
changeset 29
e8619defde14
parent 27
05b7576dca2b
child 30
27c7511c0e34
permissions
-rw-r--r--

added event handler

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"
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
37 #include "../util/date.h"
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
38
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
39 #include "davparser.h"
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
40
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
41 int webdav_service(pblock *pb, Session *sn, Request *rq) {
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
42 char *method = pblock_findkeyval(pb_key_method, rq->reqpb);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
43 if(method == NULL) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
44 return REQ_ABORTED;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
45 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
46
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
47 if(!strcmp(method, "PROPFIND")) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
48 return webdav_propfind(pb, sn, rq);
29
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
49 } else if(!strcmp(method, "PROPPATCH")) {
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
50 return webdav_proppatch(pb, sn, rq);
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
51 } else if(!strcmp(method, "PUT")) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
52 return webdav_put(pb, sn, rq);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
53 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
54
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
55 return REQ_NOACTION;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
56 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
57
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
58 int webdav_put(pblock *pb, Session *sn, Request *rq) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
59 int length = 0;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
60
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
61 char *ctlen = pblock_findkeyval(pb_key_content_length, rq->headers);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
62 if(ctlen) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
63 length = atoi(ctlen);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
64 } else {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
65 /* invalid request */
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
66 printf("invalid request\n");
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
67 return REQ_ABORTED;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
68 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
69
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
70 printf("PUT length: %d\n", length);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
71
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
72 int status = 204;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
73 if(length >= 0) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
74 char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
75
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
76 FILE *out = fopen(ppath, "w");
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
77 if(out == NULL) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
78 fprintf(stderr, "fopen(%s, \"w\") failed\n", ppath);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
79 return REQ_ABORTED;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
80 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
81 setvbuf(out, NULL, _IONBF, 0);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
82
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
83 size_t l = (length > 4096) ? (4096) : (length);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
84 char *buffer = malloc(l);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
85
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
86 int r;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
87 int r2 = 0;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
88 while(r2 < length) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
89 r = netbuf_getbytes(sn->inbuf, buffer, l);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
90 if(r == NETBUF_EOF) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
91 break;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
92 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
93 fwrite(buffer, 1, r, out);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
94
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
95 r2 += r;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
96 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
97
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
98 fclose(out);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
99 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
100
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
101 protocol_status(sn, rq, status, NULL);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
102 pblock_removekey(pb_key_content_type, rq->srvhdrs);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
103 pblock_nninsert("content-length", 0, rq->srvhdrs);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
104 http_start_response(sn, rq);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
105
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
106 return REQ_PROCEED;
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
107 }
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
109 int webdav_propfind(pblock *pb, Session *sn, Request *rq) {
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
110 /* TODO: clean up if errors occurs */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
111
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
112 /* Get request body which contains the webdav XML request */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
113 char *xml_body;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
114 size_t xml_len = 0;
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 char *ctlen = pblock_findkeyval(pb_key_content_length, rq->headers);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
117 if(ctlen) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
118 xml_len = atoi(ctlen);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
119 } else {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
120 /* invalid request */
20
7b235fa88008 Some fixes for mod_jk
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 15
diff changeset
121 printf("invalid request\n");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
122 return REQ_ABORTED;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
123 }
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 xml_body = pool_malloc(sn->pool, xml_len + 1);
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
126 if(xml_body == NULL) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
127 return REQ_ABORTED;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
128 }
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
129 xml_body[xml_len] = 0;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
130 if(!xml_body) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
131 /* server error */
20
7b235fa88008 Some fixes for mod_jk
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 15
diff changeset
132 printf("server error\n");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
133 return REQ_ABORTED;
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
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
136 /* get request body */
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
137 int r = 0;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
138 char *xb = xml_body;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
139 size_t xl = xml_len;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
140 while((r = netbuf_getbytes(sn->inbuf, xb, xl)) != NETBUF_EOF) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
141 xb += r;
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
142 xl -= r;
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
143 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
144
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
145 /*
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
146 * get requested properties and initialize some stuff
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
147 */
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
148 PropfindRequest *davrq = dav_parse_propfind(sn, rq, xml_body, xml_len);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
149 davrq->sn = sn;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
150 davrq->rq = rq;
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
151 davrq->out = sbuf_new(512);
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
152 davrq->propertyBackend = create_property_backend();
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
153
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
154 /* write xml response header */
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
155 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
156 sbuf_puts(davrq->out, "<D:multistatus xmlns:D=\"DAV:\">\n");
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
157
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
158 /* begin multistatus response */
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
159 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
160 char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
161
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
162 struct stat st;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
163 if(stat(ppath, &st) != 0) {
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
164 perror("webdav_propfind: stat");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
165 return REQ_ABORTED;
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
166 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
167
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
168 /*
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
169 * if the requested webdav resource(file) is a directory, we create
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
170 * a response for every child
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
171 */
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
172 if(S_ISDIR(st.st_mode)) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
173 DIR *dir = opendir(ppath);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
174 if(dir == NULL) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
175 protocol_status(sn, rq, 500, NULL);
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
176 printf("webdav_propfind: DIR is null\n");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
177 return REQ_ABORTED;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
178 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
179
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
180 struct dirent *f;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
181 while((f = readdir(dir)) != NULL) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
182 if(strcmp(f->d_name, ".") == 0 || strcmp(f->d_name, "..") == 0) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 continue;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
184 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
185
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186 sstr_t filename = sstr(f->d_name);
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
187 sstr_t _path = sstr(ppath);
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
188 sstr_t _uri = sstr(uri);
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
189 sstr_t ps;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
190 sstr_t us;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
191 ps.length = 0;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
192 ps.ptr = NULL;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
193 us.length = 0;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
194 us.ptr = NULL;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
195 if(_path.ptr[_path.length - 1] != '/') {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
196 ps = sstrn("/", 1);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
197 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
198 if(_uri.ptr[_uri.length - 1] != '/') {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
199 us = sstrn("/", 1);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
200 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
201
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
202 sstr_t newuri;
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
203 newuri.length = filename.length + _uri.length + us.length;
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
204 newuri.ptr = alloca(newuri.length + 1);
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
205 if(us.length == 1) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
206 newuri = sstrncat(3, newuri, _uri, us, filename);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
207 } else {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
208 newuri = sstrncat(2, newuri, _uri, filename);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
209 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
210
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
211 sstr_t newpath;
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
212 newpath.length = _path.length + filename.length + ps.length;
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
213 newpath.ptr = alloca(newpath.length + 1);
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
214 if(ps.length == 1) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
215 newpath = sstrncat(3, newpath, _path, ps, filename);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
216 } else {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
217 newpath = sstrncat(2, newpath, _path, filename);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
218 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
219
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
220 /* child response */
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
221 dav_resource_response(davrq, newpath, newuri);
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
222 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
223 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
224
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
225 /* create the response for the requested resource */
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
226 dav_resource_response(davrq, sstr(ppath), sstr(uri));
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
227
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
228 /* end xml */
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
229 sbuf_puts(davrq->out, "</D:multistatus>\n");
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
230
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
231 /* send the xml response to the client */
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
232 protocol_status(sn, rq, 207, "Multi Status");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
233 pblock_removekey(pb_key_content_type, rq->srvhdrs);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
234 pblock_nvinsert("content-type", "text/xml", rq->srvhdrs);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
235 pblock_nninsert("content-length", davrq->out->length, rq->srvhdrs);
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
236
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
237 pblock_nvinsert("connection", "close", rq->srvhdrs);
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
238 http_start_response(sn, rq);
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
239
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
240 net_write(sn->csd, davrq->out->ptr, davrq->out->length);
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
241
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
242
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
243
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
244
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
245 return REQ_PROCEED;
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
29
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
248 int webdav_proppatch(pblock *pb, Session *sn, Request *rq) {
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
249 /* TODO: clean up if errors occurs */
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
250 /* TODO: this is the same code as in propfind */
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
251
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
252 /* Get request body which contains the webdav XML request */
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
253 char *xml_body;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
254 size_t xml_len = 0;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
255
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
256 char *ctlen = pblock_findkeyval(pb_key_content_length, rq->headers);
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
257 if(ctlen) {
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
258 xml_len = atoi(ctlen);
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
259 } else {
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
260 /* invalid request */
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
261 printf("invalid request\n");
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
262 return REQ_ABORTED;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
263 }
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
264
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
265 xml_body = pool_malloc(sn->pool, xml_len + 1);
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
266 if(xml_body == NULL) {
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
267 return REQ_ABORTED;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
268 }
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
269 xml_body[xml_len] = 0;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
270 if(!xml_body) {
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
271 /* server error */
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
272 printf("server error\n");
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
273 return REQ_ABORTED;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
274 }
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
275
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
276 /* get request body */
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
277 int r = 0;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
278 char *xb = xml_body;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
279 size_t xl = xml_len;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
280 while((r = netbuf_getbytes(sn->inbuf, xb, xl)) != NETBUF_EOF) {
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
281 xb += r;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
282 xl -= r;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
283 }
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
284
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
285
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
286
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
287 return REQ_PROCEED;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
288 }
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
289
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
290 void dav_resource_response(PropfindRequest *davrq, sstr_t path, sstr_t uri) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
291 printf("dav_resource_response %s %s\n", sstrdub(path).ptr, sstrdub(uri).ptr);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
292
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
293 sbuf_puts(davrq->out, "<D:response>\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
294 sbuf_puts(davrq->out, "<D:href>");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
295 sbuf_append(davrq->out, uri);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
296 sbuf_puts(davrq->out, "</D:href>\n");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
297
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
298 davrq->propertyBackend->propfind(davrq->propertyBackend, davrq, path.ptr);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
299
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
300 if(davrq->prop) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
301 /*
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
302 * there are some properties written, so we close the
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
303 * prop and propstat tag
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
304 */
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
305 sbuf_puts(davrq->out, "</D:prop>\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
306 sbuf_puts(davrq->out, "<D:status>HTTP/1.1 200 OK</D:status>\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
307 sbuf_puts(davrq->out, "</D:propstat>\n");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
308 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
309
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
310 if(davrq->notFoundProps != NULL) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
311 sbuf_puts(davrq->out, "<D:propstat>\n<D:prop>\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
312 DAV_FOREACH(elm, davrq->notFoundProps) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
313 DavProperty *prop = (DavProperty*)elm->data;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
314 sbuf_puts(davrq->out, "<D:");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
315 sbuf_puts(davrq->out, prop->name);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
316 sbuf_puts(davrq->out, " />\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
317 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
318 sbuf_puts(davrq->out, "</D:prop>\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
319 sbuf_puts(davrq->out, "<D:status>HTTP/1.1 404 Not Found</D:status>\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
320 sbuf_puts(davrq->out, "</D:propstat>\n");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
321 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
322
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
323 sbuf_puts(davrq->out, "</D:response>\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
324
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
325 /* reset */
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
326 davrq->prop = 0;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
327 davrq->notFoundProps = NULL;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
328 davrq->forbiddenProps = NULL;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
329
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
330 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
331
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
332 void dav_propfind_add_str_prop(
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
333 PropfindRequest *davrq,
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
334 DavProperty* prop,
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
335 char *str,
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
336 size_t len)
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
337 {
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
338 if(!davrq->prop) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
339 sbuf_puts(davrq->out, "<D:propstat>\n<D:prop>\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
340 davrq->prop = 1;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
341 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
342
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
343 sbuf_puts(davrq->out, "<D:");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
344 sbuf_puts(davrq->out, prop->name);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
345 sbuf_puts(davrq->out, ">");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
346
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
347 sbuf_append(davrq->out, sstrn(str, len));
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
348
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
349 sbuf_puts(davrq->out, "</D:");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
350 sbuf_puts(davrq->out, prop->name);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
351 sbuf_puts(davrq->out, ">\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
352 }
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
353
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
354 void dav_propfind_add_prop_error(
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
355 PropfindRequest *davrq,
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
356 DavProperty *prop,
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
357 int error)
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
358 {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
359 davrq->notFoundProps = ucx_dlist_append(davrq->notFoundProps, prop);
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
360 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
361
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
362
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
363
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
364
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
365 /* WebDAV Default Backend */
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
366 DAVPropertyBackend* create_property_backend() {
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
367 DAVPropertyBackend *pb = malloc(sizeof(DAVPropertyBackend));
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
368 if(pb == NULL) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
369 //
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
370 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
371 pb->propfind = dav_rq_propfind;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
372 return pb;
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
373 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
374
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
375 void dav_rq_propfind(DAVPropertyBackend *b, PropfindRequest *rq ,char *path) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
376 struct stat st;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
377 if(stat(path, &st) != 0) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
378 perror("dav_be_propfind");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
379 fprintf(stderr, "Cannot get stat of file: %s\n", path);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
380 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
381
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
382 DAV_FOREACH(elm, rq->properties) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
383 DavProperty *prop = (DavProperty*)elm->data;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
384
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
385 char *s = prop->name;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
386 if(!strcmp(s, "resourcetype")) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
387 if(S_ISDIR(st.st_mode)) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
388 dav_propfind_add_str_prop(rq, prop, "<D:collection/>", 15);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
389 } else {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
390 dav_propfind_add_str_prop(rq, prop, NULL, 0);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
391 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
392 } else if(!strcmp(s, "getcontentlength") && !S_ISDIR(st.st_mode)) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
393 char buf[32];
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
394 size_t n = snprintf(buf, 32, "%d", st.st_size);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
395 dav_propfind_add_str_prop(rq, prop, buf, n);
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
396 } else if(!strcmp(s, "getlastmodified")) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
397 sstr_t s = date_format_http(st.st_mtim.tv_sec, rq->sn->pool);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
398 dav_propfind_add_str_prop(rq, prop, s.ptr, s.length);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
399 } else if(!strcmp(s, "creationdate")) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
400 sstr_t s = date_format_iso8601(st.st_ctim.tv_sec, rq->sn->pool);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
401 dav_propfind_add_str_prop(rq, prop, s.ptr, s.length);
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
402 } else {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
403 dav_propfind_add_prop_error(rq, prop, 404);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
404 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
405 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
406 }

mercurial