src/server/webdav/webdav.c

Thu, 24 May 2012 12:51:52 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 24 May 2012 12:51:52 +0200
changeset 30
27c7511c0e34
parent 29
e8619defde14
child 31
280250e45ba6
permissions
-rw-r--r--

new proppatch, mkcol and delete method

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
30
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
39 #include "../daemon/protocol.h"
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
40
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
41 #include "davparser.h"
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
42
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
43 int webdav_service(pblock *pb, Session *sn, Request *rq) {
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
44 char *method = pblock_findkeyval(pb_key_method, rq->reqpb);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
45 if(method == NULL) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
46 return REQ_ABORTED;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
47 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
48
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
49 if(!strcmp(method, "PROPFIND")) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
50 return webdav_propfind(pb, sn, rq);
29
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
51 } else if(!strcmp(method, "PROPPATCH")) {
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
52 return webdav_proppatch(pb, sn, rq);
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
53 } else if(!strcmp(method, "PUT")) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
54 return webdav_put(pb, sn, rq);
30
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
55 } else if(!strcmp(method, "DELETE")) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
56 return webdav_delete(pb, sn, rq);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
57 } else if(!strcmp(method, "MKCOL")) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
58 return webdav_mkcol(pb, sn, rq);
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
59 }
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 return REQ_NOACTION;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
62 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
63
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
64 int webdav_put(pblock *pb, Session *sn, Request *rq) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
65 int length = 0;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
66
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
67 char *ctlen = pblock_findkeyval(pb_key_content_length, rq->headers);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
68 if(ctlen) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
69 length = atoi(ctlen);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
70 } else {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
71 /* invalid request */
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
72 printf("invalid request\n");
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
73 return REQ_ABORTED;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
74 }
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 printf("PUT length: %d\n", length);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
77
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
78 int status = 204;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
79 if(length >= 0) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
80 char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
81
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
82 FILE *out = fopen(ppath, "w");
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
83 if(out == NULL) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
84 fprintf(stderr, "fopen(%s, \"w\") failed\n", ppath);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
85 return REQ_ABORTED;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
86 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
87 setvbuf(out, NULL, _IONBF, 0);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
88
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
89 size_t l = (length > 4096) ? (4096) : (length);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
90 char *buffer = malloc(l);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
91
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
92 int r;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
93 int r2 = 0;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
94 while(r2 < length) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
95 r = netbuf_getbytes(sn->inbuf, buffer, l);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
96 if(r == NETBUF_EOF) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
97 break;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
98 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
99 fwrite(buffer, 1, r, out);
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 r2 += r;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
102 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
103
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
104 fclose(out);
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
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
107 protocol_status(sn, rq, status, NULL);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
108 pblock_removekey(pb_key_content_type, rq->srvhdrs);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
109 pblock_nninsert("content-length", 0, rq->srvhdrs);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
110 http_start_response(sn, rq);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
111
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
112 return REQ_PROCEED;
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
113 }
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
114
30
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
115 int webdav_delete(pblock *pb, Session *sn, Request *rq) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
116 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
117 char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
118
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
119 int status = 204;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
120
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
121 struct stat st;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
122 if(stat(ppath, &st) != 0) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
123 /* ERROR */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
124 status = 403; /* TODO: check errno */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
125 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
126
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
127 if(!strcmp(uri, "/")) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
128 status = 403;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
129 } else if((st.st_mode & S_IFDIR) == S_IFDIR) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
130 if(rmdir(ppath) != 0) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
131 /* ERROR */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
132 status = 403;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
133 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
134 } else {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
135 if(unlink(ppath) != 0) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
136 /* ERROR */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
137 status = 403; /* TODO: check errno */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
138 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
139 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
140
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
141 protocol_status(sn, rq, status, NULL);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
142 pblock_removekey(pb_key_content_type, rq->srvhdrs);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
143 pblock_nninsert("content-length", 0, rq->srvhdrs);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
144 http_start_response(sn, rq);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
145
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
146 return REQ_PROCEED;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
147 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
148
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
149 int webdav_mkcol(pblock *pb, Session *sn, Request *rq) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
150 char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
151
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
152 int status = 201;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
153 if(mkdir(ppath, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
154 status = 403;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
155 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
156
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
157 protocol_status(sn, rq, status, NULL);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
158 pblock_removekey(pb_key_content_type, rq->srvhdrs);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
159 pblock_nninsert("content-length", 0, rq->srvhdrs);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
160 http_start_response(sn, rq);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
161
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
162 return REQ_ABORTED;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
163 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
164
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
165 int webdav_copy(pblock *pb, Session *sn, Request *rq) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
166 return REQ_ABORTED;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
167 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
168
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
169 int webdav_move(pblock *pb, Session *sn, Request *rq) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
170 return REQ_ABORTED;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
171 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
172
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
173 int webdav_propfind(pblock *pb, Session *sn, Request *rq) {
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
174 /* TODO: clean up if errors occurs */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
175
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
176 /* Get request body which contains the webdav XML request */
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
177 char *xml_body;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
178 size_t xml_len = 0;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
179
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
180 char *ctlen = pblock_findkeyval(pb_key_content_length, rq->headers);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
181 if(ctlen) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
182 xml_len = atoi(ctlen);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 } else {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
184 /* invalid request */
20
7b235fa88008 Some fixes for mod_jk
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 15
diff changeset
185 printf("invalid request\n");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186 return REQ_ABORTED;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
187 }
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 xml_body = pool_malloc(sn->pool, xml_len + 1);
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
190 if(xml_body == NULL) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
191 return REQ_ABORTED;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
192 }
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
193 xml_body[xml_len] = 0;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
194 if(!xml_body) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
195 /* server error */
20
7b235fa88008 Some fixes for mod_jk
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 15
diff changeset
196 printf("server error\n");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
197 return REQ_ABORTED;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
198 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
199
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
200 /* get request body */
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
201 int r = 0;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
202 char *xb = xml_body;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
203 size_t xl = xml_len;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
204 while((r = netbuf_getbytes(sn->inbuf, xb, xl)) != NETBUF_EOF) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
205 xb += r;
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
206 xl -= r;
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
207 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
208
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
209 /*
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
210 * get requested properties and initialize some stuff
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
211 */
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
212 PropfindRequest *davrq = dav_parse_propfind(sn, rq, xml_body, xml_len);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
213 davrq->sn = sn;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
214 davrq->rq = rq;
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
215 davrq->out = sbuf_new(512);
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
216 davrq->propertyBackend = create_property_backend();
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
217
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
218 /* write xml response header */
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
219 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
220 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
221
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
222 /* begin multistatus response */
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
223 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
224 char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars);
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
225
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
226 struct stat st;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
227 if(stat(ppath, &st) != 0) {
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
228 perror("webdav_propfind: stat");
30
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
229 fprintf(stderr, " file: %s\n", ppath);
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
230 return REQ_ABORTED;
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
231 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
232
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
233 /*
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
234 * 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
235 * a response for every child
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
236 */
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
237 if(S_ISDIR(st.st_mode)) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
238 DIR *dir = opendir(ppath);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
239 if(dir == NULL) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
240 protocol_status(sn, rq, 500, NULL);
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
241 printf("webdav_propfind: DIR is null\n");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
242 return REQ_ABORTED;
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 struct dirent *f;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
246 while((f = readdir(dir)) != NULL) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
247 if(strcmp(f->d_name, ".") == 0 || strcmp(f->d_name, "..") == 0) {
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
248 continue;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
249 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
250
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
251 sstr_t filename = sstr(f->d_name);
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
252 sstr_t _path = sstr(ppath);
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
253 sstr_t _uri = sstr(uri);
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
254 sstr_t ps;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
255 sstr_t us;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
256 ps.length = 0;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
257 ps.ptr = NULL;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
258 us.length = 0;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
259 us.ptr = NULL;
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
260 if(_path.ptr[_path.length - 1] != '/') {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
261 ps = sstrn("/", 1);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
262 }
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
263 if(_uri.ptr[_uri.length - 1] != '/') {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
264 us = sstrn("/", 1);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
265 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
266
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
267 sstr_t newuri;
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
268 newuri.length = filename.length + _uri.length + us.length;
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
269 newuri.ptr = alloca(newuri.length + 1);
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
270 if(us.length == 1) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
271 newuri = sstrncat(3, newuri, _uri, us, filename);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
272 } else {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
273 newuri = sstrncat(2, newuri, _uri, filename);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
274 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
275
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
276 sstr_t newpath;
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
277 newpath.length = _path.length + filename.length + ps.length;
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
278 newpath.ptr = alloca(newpath.length + 1);
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
279 if(ps.length == 1) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
280 newpath = sstrncat(3, newpath, _path, ps, filename);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
281 } else {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
282 newpath = sstrncat(2, newpath, _path, filename);
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
283 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
284
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
285 /* child response */
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
286 dav_resource_response(davrq, newpath, newuri);
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
287 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
288 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
289
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
290 /* create the response for the requested resource */
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
291 dav_resource_response(davrq, sstr(ppath), sstr(uri));
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 /* end xml */
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
294 sbuf_puts(davrq->out, "</D:multistatus>\n");
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
295
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
296 /* send the xml response to the client */
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
297 protocol_status(sn, rq, 207, "Multi Status");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
298 pblock_removekey(pb_key_content_type, rq->srvhdrs);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
299 pblock_nvinsert("content-type", "text/xml", rq->srvhdrs);
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
300 pblock_nninsert("content-length", davrq->out->length, rq->srvhdrs);
26
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 pblock_nvinsert("connection", "close", rq->srvhdrs);
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
303 http_start_response(sn, rq);
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
304
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
305 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
306
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
307
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
308
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
309
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
310 return REQ_PROCEED;
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
311 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
312
29
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
313 int webdav_proppatch(pblock *pb, Session *sn, Request *rq) {
30
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
314 printf("webdav-proppatch\n");
29
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
315 /* TODO: clean up if errors occurs */
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
316 /* TODO: this is the same code as in propfind */
30
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
317 char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
318 if(uri == NULL) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
319 /* TODO: error */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
320 return REQ_ABORTED;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
321 }
29
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
322
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
323 /* Get request body which contains the webdav XML request */
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
324 char *xml_body;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
325 size_t xml_len = 0;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
326
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
327 char *ctlen = pblock_findkeyval(pb_key_content_length, rq->headers);
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
328 if(ctlen) {
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
329 xml_len = atoi(ctlen);
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
330 } else {
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
331 /* invalid request */
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
332 printf("invalid request\n");
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
333 return REQ_ABORTED;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
334 }
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
335
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
336 xml_body = pool_malloc(sn->pool, xml_len + 1);
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
337 if(xml_body == NULL) {
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
338 return REQ_ABORTED;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
339 }
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
340 xml_body[xml_len] = 0;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
341 if(!xml_body) {
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
342 /* server error */
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
343 printf("server error\n");
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
344 return REQ_ABORTED;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
345 }
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
346
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
347 /* get request body */
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
348 int r = 0;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
349 char *xb = xml_body;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
350 size_t xl = xml_len;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
351 while((r = netbuf_getbytes(sn->inbuf, xb, xl)) != NETBUF_EOF) {
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
352 xb += r;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
353 xl -= r;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
354 }
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
355
30
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
356 /*
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
357 * parse the xml request and create the proppatch object
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
358 */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
359 ProppatchRequest *davrq = dav_parse_proppatch(sn, rq, xml_body, xml_len);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
360 davrq->sn = sn;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
361 davrq->rq = rq;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
362 davrq->out = sbuf_new(512);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
363 davrq->backend = create_property_backend();
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
364 davrq->propstat = propstat_create(sn->pool);
29
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
365
30
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
366 /* TODO: create prefixes for every namespace */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
367 XmlNs *ns = xmlnsmap_get(davrq->nsmap, "DAV:");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
368 ns->prefix = "D";
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
369 ns->prelen = 1;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
370
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
371 /*
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
372 * begin multistatus response
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
373 *
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
374 * The webdav backend does the most work. The backend->proppatch function
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
375 * modifies the properties and adds status informations to the propstat
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
376 * member of the ProppatchRequest. All we have to do here is to create
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
377 * the xml response and send it to the client
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
378 */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
379
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
380 /* write xml response header */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
381 /* TODO: add possible xml namespaces */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
382 sbuf_puts(davrq->out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
383 sbuf_puts(davrq->out, "<D:multistatus xmlns:D=\"DAV:\">\n");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
384
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
385 sbuf_puts(davrq->out, "<D:response>\n<D:href>");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
386 sbuf_puts(davrq->out, uri);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
387 sbuf_puts(davrq->out, "</D:href>\n");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
388
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
389 /* do proppatch operation */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
390 davrq->backend->proppatch(davrq->backend, davrq);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
391
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
392 propstat_write(davrq->propstat, davrq->out, 0);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
393
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
394 sbuf_puts(davrq->out, "</D:response>\n");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
395 sbuf_puts(davrq->out, "</D:multistatus>\n");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
396
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
397
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
398 /* send the xml response to the client */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
399 protocol_status(sn, rq, 207, "Multi Status");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
400 pblock_removekey(pb_key_content_type, rq->srvhdrs);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
401 pblock_nvinsert("content-type", "text/xml", rq->srvhdrs);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
402 pblock_nninsert("content-length", davrq->out->length, rq->srvhdrs);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
403
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
404 pblock_nvinsert("connection", "close", rq->srvhdrs);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
405 http_start_response(sn, rq);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
406
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
407 net_write(sn->csd, davrq->out->ptr, davrq->out->length);
29
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
408
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
409 return REQ_PROCEED;
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
410 }
e8619defde14 added event handler
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 27
diff changeset
411
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
412 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
413 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
414
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
415 sbuf_puts(davrq->out, "<D:response>\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
416 sbuf_puts(davrq->out, "<D:href>");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
417 sbuf_append(davrq->out, uri);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
418 sbuf_puts(davrq->out, "</D:href>\n");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
419
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
420 davrq->propertyBackend->propfind(davrq->propertyBackend, davrq, path.ptr);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
421
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
422 if(davrq->prop) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
423 /*
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
424 * there are some properties written, so we close the
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
425 * prop and propstat tag
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
426 */
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
427 sbuf_puts(davrq->out, "</D:prop>\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
428 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
429 sbuf_puts(davrq->out, "</D:propstat>\n");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
430 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
431
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
432 if(davrq->notFoundProps != NULL) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
433 sbuf_puts(davrq->out, "<D:propstat>\n<D:prop>\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
434 DAV_FOREACH(elm, davrq->notFoundProps) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
435 DavProperty *prop = (DavProperty*)elm->data;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
436 sbuf_puts(davrq->out, "<D:");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
437 sbuf_puts(davrq->out, prop->name);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
438 sbuf_puts(davrq->out, " />\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
439 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
440 sbuf_puts(davrq->out, "</D:prop>\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
441 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
442 sbuf_puts(davrq->out, "</D:propstat>\n");
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
443 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
444
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
445 sbuf_puts(davrq->out, "</D:response>\n");
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
446
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
447 /* reset */
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
448 davrq->prop = 0;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
449 davrq->notFoundProps = NULL;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
450 davrq->forbiddenProps = NULL;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
451
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
452 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
453
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
454 void dav_propfind_add_str_prop(
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
455 PropfindRequest *davrq,
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
456 DavProperty* prop,
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
457 char *str,
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
458 size_t len)
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
459 {
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
460 if(!davrq->prop) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
461 sbuf_puts(davrq->out, "<D:propstat>\n<D:prop>\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
462 davrq->prop = 1;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
463 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
464
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
465 sbuf_puts(davrq->out, "<D:");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
466 sbuf_puts(davrq->out, prop->name);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
467 sbuf_puts(davrq->out, ">");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
468
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
469 sbuf_append(davrq->out, sstrn(str, len));
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
470
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
471 sbuf_puts(davrq->out, "</D:");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
472 sbuf_puts(davrq->out, prop->name);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
473 sbuf_puts(davrq->out, ">\n");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
474 }
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
475
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
476 void dav_propfind_add_prop_error(
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
477 PropfindRequest *davrq,
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
478 DavProperty *prop,
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
479 int error)
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
480 {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
481 davrq->notFoundProps = ucx_dlist_append(davrq->notFoundProps, prop);
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
482 }
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
483
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
484
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
485
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
486
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
487 /* WebDAV Default Backend */
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
488 DAVPropertyBackend* create_property_backend() {
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
489 DAVPropertyBackend *pb = malloc(sizeof(DAVPropertyBackend));
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
490 if(pb == NULL) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
491 //
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
492 }
30
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
493 pb->propfind = dav_rq_propfind;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
494 pb->proppatch = dav_rq_proppatch;
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
495 return pb;
13
1fdbf4170ef4 Added webdav code
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
496 }
26
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
497
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
498 void dav_rq_propfind(DAVPropertyBackend *b, PropfindRequest *rq ,char *path) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
499 struct stat st;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
500 if(stat(path, &st) != 0) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
501 perror("dav_be_propfind");
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
502 fprintf(stderr, "Cannot get stat of file: %s\n", path);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
503 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
504
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
505 DAV_FOREACH(elm, rq->properties) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
506 DavProperty *prop = (DavProperty*)elm->data;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
507
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
508 char *s = prop->name;
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
509 if(!strcmp(s, "resourcetype")) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
510 if(S_ISDIR(st.st_mode)) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
511 dav_propfind_add_str_prop(rq, prop, "<D:collection/>", 15);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
512 } else {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
513 dav_propfind_add_str_prop(rq, prop, NULL, 0);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
514 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
515 } else if(!strcmp(s, "getcontentlength") && !S_ISDIR(st.st_mode)) {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
516 char buf[32];
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
517 size_t n = snprintf(buf, 32, "%d", st.st_size);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
518 dav_propfind_add_str_prop(rq, prop, buf, n);
27
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
519 } else if(!strcmp(s, "getlastmodified")) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
520 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
521 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
522 } else if(!strcmp(s, "creationdate")) {
05b7576dca2b added put method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 26
diff changeset
523 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
524 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
525 } else {
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
526 dav_propfind_add_prop_error(rq, prop, 404);
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
527 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
528 }
37ff8bf54b89 Minimal webdav support
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
529 }
30
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
530
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
531 void dav_rq_proppatch(DAVPropertyBackend *b, ProppatchRequest *rq) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
532 DAV_FOREACH(p, rq->setProps) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
533 XmlElement *prop = (XmlElement*)p->data;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
534 propstat_add(rq->propstat, 403, prop);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
535 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
536
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
537 DAV_FOREACH(p, rq->removeProps) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
538 XmlElement *prop = (XmlElement*)p->data;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
539 propstat_add(rq->propstat, 403, prop);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
540 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
541 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
542
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
543
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
544
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
545 /*---------------------------------- utils ----------------------------------*/
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
546
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
547 /* XmlNsMap */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
548
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
549 XmlNsMap* xmlnsmap_create() {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
550 XmlNsMap *map = malloc(sizeof(XmlNsMap));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
551 UcxMap *uxm = ucx_map_new(16);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
552 if(map == NULL || uxm == NULL) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
553 return NULL;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
554 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
555 map->map = uxm;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
556 return map;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
557 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
558
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
559 void xmlnsmap_free(XmlNsMap *map) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
560 /* TODO: implement */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
561 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
562
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
563 XmlNs* xmlnsmap_put(XmlNsMap *map, char *ns) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
564 XmlNs *xmlns = xmlnsmap_get(map, ns);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
565 if(xmlns != NULL) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
566 return xmlns;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
567 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
568
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
569 xmlns = malloc(sizeof(XmlNs));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
570 if(xmlns == NULL) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
571 return NULL;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
572 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
573
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
574 xmlns->xmlns = ns;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
575 xmlns->nslen = strlen(ns);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
576
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
577 xmlns->prefix = NULL;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
578 xmlns->prelen = 0;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
579
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
580 ucx_map_cstr_put(map->map, ns, xmlns); /* TODO: check return value */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
581 return xmlns;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
582 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
583
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
584 XmlNs* xmlnsmap_get(XmlNsMap *map, char *ns) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
585 return ucx_map_cstr_get(map->map, ns);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
586 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
587
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
588
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
589 /* XmlElement */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
590
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
591 void xmlelm_add_child(XmlElement *parent, XmlElement *child) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
592 if(parent->ctlen == 0) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
593 parent->content = ucx_dlist_append(parent->content, child);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
594 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
595 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
596
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
597 void xmlelm_write(XmlElement *elm, sbuf_t *out, int wv) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
598 sbuf_append(out, sstrn("<", 1));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
599 sbuf_append(out, sstrn(elm->xmlns->prefix, elm->xmlns->prelen));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
600 sbuf_append(out, sstrn(":", 1));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
601 sbuf_append(out, elm->name);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
602
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
603 if(wv) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
604 if(elm->ctlen == 0) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
605 if(elm->content == NULL) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
606 sbuf_append(out, sstrn(" />", 3));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
607 } else {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
608 sbuf_append(out, sstrn(">", 1));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
609 DAV_FOREACH(pr, (UcxDlist*)elm->content) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
610 xmlelm_write((XmlElement*)pr->data, out, 1);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
611 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
612 sbuf_append(out, sstrn("</", 2));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
613 sbuf_append(out, sstrn(elm->xmlns->prefix, elm->xmlns->prelen));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
614 sbuf_append(out, sstrn(":", 1));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
615 sbuf_append(out, elm->name);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
616 sbuf_append(out, sstrn(">", 1));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
617 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
618 } else {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
619 sbuf_append(out, sstrn(" />", 3));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
620 sbuf_append(out, sstrn((char*)elm->content, elm->ctlen));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
621 sbuf_append(out, sstrn("</", 2));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
622 sbuf_append(out, sstrn(elm->xmlns->prefix, elm->xmlns->prelen));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
623 sbuf_append(out, sstrn(":", 1));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
624 sbuf_append(out, elm->name);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
625 sbuf_append(out, sstrn(">", 1));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
626 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
627 } else {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
628 sbuf_append(out, sstrn(" />", 3));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
629 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
630 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
631
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
632
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
633 /* PropstatMap */
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
634
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
635 Propstat* propstat_create(pool_handle_t *pool) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
636 Propstat *propstat = (Propstat*)pool_malloc(pool, sizeof(Propstat));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
637 propstat->map = ucx_map_new(8);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
638 propstat->okprop = NULL;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
639 propstat->pool = pool;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
640 return propstat;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
641 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
642
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
643 void propstat_add(Propstat *propstat, int status, XmlElement *prop) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
644 if(status == 200) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
645 propstat->okprop = ucx_dlist_append(propstat->okprop, prop);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
646 } else {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
647 UcxKey key;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
648 key.data = &status;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
649 key.len = sizeof(int);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
650
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
651 UcxDlist *list = ucx_map_get(propstat->map, key);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
652 list = ucx_dlist_append(list, prop);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
653
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
654 ucx_map_put(propstat->map, key, list);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
655 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
656 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
657
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
658 void propstat_write(Propstat *propstat, sbuf_t *out, int wv) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
659 if(propstat->okprop) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
660 sbuf_puts(out, "<D:propstat>\n<D:prop>\n");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
661
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
662 DAV_FOREACH(prop, propstat->okprop) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
663 xmlelm_write((XmlElement*)prop->data, out, wv);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
664 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
665
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
666 sbuf_puts(out, "\n</D:prop>\n<D:status>HTTP/1.1 200 OK</D:status>\n");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
667 sbuf_puts(out, "</D:propstat>\n");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
668 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
669
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
670 for(int i=0;i<propstat->map->size;i++) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
671 UcxMapElement *elm = &propstat->map->map[i];
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
672 while(elm) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
673 UcxDlist *proplist = (UcxDlist*)elm->data;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
674
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
675 if(proplist) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
676 sbuf_puts(out, "<D:propstat>\n<D:prop>\n");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
677
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
678 DAV_FOREACH(prop, proplist) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
679 xmlelm_write((XmlElement*)prop->data, out, wv);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
680 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
681
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
682 sbuf_puts(out, "\n</D:prop>\n<D:status>");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
683
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
684 int status = *(int*)elm->key.data;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
685 if(status < 1000 && status > 0) {
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
686 char buf[5];
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
687 buf[4] = 0;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
688 sprintf(buf, "%d ", status);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
689 sbuf_puts(out, "HTTP/1.1 ");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
690 sbuf_puts(out, buf);
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
691 sbuf_puts(out, (char*)protocol_status_message(status));
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
692 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
693
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
694 sbuf_puts(out, "</D:status>\n</D:propstat>\n");
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
695 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
696
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
697 elm = elm->next;
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
698 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
699 }
27c7511c0e34 new proppatch, mkcol and delete method
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 29
diff changeset
700 }

mercurial