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