src/server/webdav/saxhandler.cpp

changeset 107
7e81699d1f77
parent 106
b122f34ddc80
child 108
2a394ccdd778
equal deleted inserted replaced
106:b122f34ddc80 107:7e81699d1f77
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2013 Olaf Wintermann. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <iostream>
33
34 #include <ucx/string.h>
35 #include <ucx/list.h>
36
37 #include "../util/pool.h"
38
39 #include "saxhandler.h"
40
41 using namespace std;
42
43 void xstack_push(UcxList **stack, XmlElement *elm) {
44 *stack = ucx_list_prepend(*stack, elm);
45 }
46
47 XmlElement* xstack_pop(UcxList **stack) {
48 if(*stack == NULL) {
49 return NULL;
50 }
51 XmlElement* ret = (XmlElement*)(*stack)->data;
52 UcxList *newstack = ucx_list_remove(*stack, *stack);
53 *stack = newstack;
54 return ret;
55 }
56
57
58
59 PropfindHandler::PropfindHandler(PropfindRequest *rq, pool_handle_t *p) {
60 davrq = rq;
61 pool = p;
62
63 davPropTag = false;
64 property = NULL;
65 }
66
67 PropfindHandler::~PropfindHandler() {
68
69 }
70
71 void PropfindHandler::startElement(
72 const XMLCh *const uri,
73 const XMLCh* const localname,
74 const XMLCh* const qname,
75 const Attributes& attrs)
76 {
77 char *ns = XMLString::transcode(uri);
78 char *name = XMLString::transcode(localname);
79
80 if(!strcmp(ns, "DAV:") && !strcmp(name, "allprop")) {
81 davrq->allprop = 1;
82 } else if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) {
83 davPropTag = true;
84 } else if(davPropTag && property == NULL && !davrq->allprop) {
85 property = (DavProperty*)pool_malloc(pool, sizeof(DavProperty));
86
87 size_t nslen = strlen(ns);
88 size_t namelen = strlen(name);
89 if(nslen > 0) {
90 //property->xmlns = (char*)pool_malloc(pool, nslen + 1);
91 //property->xmlns[nslen] = 0;
92 property->xmlns = xmlnsmap_put(davrq->nsmap, ns);
93 //memcpy(property->xmlns, ns, nslen);
94 } else {
95 property->xmlns = NULL;
96 }
97
98 if(namelen > 0) {
99 property->name = (char*)pool_malloc(pool, namelen + 1);
100 property->name[namelen] = 0;
101 memcpy(property->name, name, namelen);
102 } else {
103 property->name = NULL;
104 }
105 }
106
107 XMLString::release(&ns);
108 XMLString::release(&name);
109 }
110
111
112 void PropfindHandler::endElement(
113 const XMLCh* const uri,
114 const XMLCh* const localname,
115 const XMLCh* const qname)
116 {
117 char *ns = XMLString::transcode(uri);
118 char *name = XMLString::transcode(localname);
119
120 if(property != NULL) {
121 const char *xmlns = (property->xmlns) ? property->xmlns->xmlns : "";
122
123 if(!strcmp(ns, xmlns) && !strcmp(name, property->name)) {
124 // add property to DavRequest
125 UcxList *elm = (UcxList*)pool_malloc(pool, sizeof(UcxList));
126 elm->prev = NULL;
127 elm->next = NULL;
128 elm->data = property;
129 //printf("saxhandler: add property: {%s}\n", property->name);
130 davrq->properties = ucx_list_concat(davrq->properties, elm);
131
132 property = NULL;
133 }
134 }
135
136 XMLString::release(&ns);
137 XMLString::release(&name);
138 }
139
140 void PropfindHandler::startDocument() {
141
142 }
143
144 void PropfindHandler::endDocument() {
145
146 }
147
148
149 /************* PropPatch Handler **************/
150
151 ProppatchHandler::ProppatchHandler(ProppatchRequest *rq, pool_handle_t *p) {
152 davrq = rq;
153 pool = p;
154
155 davPropTag = false;
156 rootElement = NULL;
157 xmlStack = NULL;
158 newElement = NULL;
159
160 updateMode = -1;
161 }
162
163 ProppatchHandler::~ProppatchHandler() {
164 ucx_list_free(xmlStack);
165 }
166
167 void ProppatchHandler::startElement(
168 const XMLCh *const uri,
169 const XMLCh* const localname,
170 const XMLCh* const qname,
171 const Attributes& attrs)
172 {
173 char *ns = XMLString::transcode(uri);
174 char *name = XMLString::transcode(localname);
175
176 if(!strcmp(ns, "DAV:") && !strcmp(name, "set")) {
177 updateMode = 0;
178 } else if(!strcmp(ns, "DAV:") && !strcmp(name, "remove")) {
179 updateMode = 1;
180 } else if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) {
181 davPropTag = true;
182 } else if(davPropTag) {
183 newElement = (XmlElement*)pool_calloc(pool, 1, sizeof(XmlElement));
184 newElement->name = pool_strdup(pool, name);
185 newElement->xmlns = xmlnsmap_put(davrq->nsmap, ns);
186
187 /*
188 * the xml stack manages the xml hierarchy
189 * new elements will be added to the top element on the stack
190 */
191
192 XmlElement *currentElm = XSTACK_CUR();
193 if(currentElm) {
194 xmlelm_add_child(currentElm, newElement);
195 }
196
197 /* newElement is now the parent for future elements */
198 XSTACK_PUSH(newElement);
199
200 /* if the root element isn't set, the first new element is the root */
201 if(!rootElement) {
202 rootElement = newElement;
203 }
204 }
205
206 XMLString::release(&ns);
207 XMLString::release(&name);
208 }
209
210
211 void ProppatchHandler::endElement(
212 const XMLCh* const uri,
213 const XMLCh* const localname,
214 const XMLCh* const qname)
215 {
216 char *ns = XMLString::transcode(uri);
217 char *name = XMLString::transcode(localname);
218
219 if(!strcmp(ns, "DAV:") && !strcmp(name, "set")) {
220 updateMode = -1;
221 } else if(!strcmp(ns, "DAV:") && !strcmp(name, "remove")) {
222 updateMode = -1;
223 } else if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) {
224 davPropTag = false;
225 } else if(davPropTag) {
226 XmlElement *elm = XSTACK_POP();
227 if(xmlStack == NULL) {
228 /* property complete */
229
230 /*
231 XmlElement *r = rootElement;
232 printf("<%s>\n", sstrdup(r->name).ptr);
233 printf("%s\n", r->content);
234 printf("</%s>\n", sstrdup(r->name).ptr);
235 */
236
237 /* add the property to the proppatch request */
238 switch(updateMode) {
239 case 0: {
240 davrq->setProps = ucx_list_append(
241 davrq->setProps,
242 rootElement);
243 break;
244 }
245 case 1: {
246 davrq->removeProps = ucx_list_append(
247 davrq->removeProps,
248 rootElement);
249 break;
250 }
251 }
252
253 rootElement = NULL;
254
255 }
256 }
257
258
259 XMLString::release(&ns);
260 XMLString::release(&name);
261 }
262
263 void ProppatchHandler::characters(
264 const XMLCh *const chars,
265 const XMLSize_t length)
266 {
267
268 XMLString::trim((XMLCh *const)chars);
269 if(chars[0] == 0) {
270 return;
271 }
272
273 XmlElement *currentElm = XSTACK_CUR();
274 if(currentElm) {
275 xmlch_t *str = (xmlch_t*)pool_calloc(pool, sizeof(xmlch_t), length + 1);
276 for(int i=0;i<length;i++) {
277 str[i] = chars[i];
278 }
279 str[length] = 0;
280
281 currentElm->content = str;
282 currentElm->ctlen = length;
283 }
284 }
285
286 void ProppatchHandler::startDocument() {
287
288 }
289
290 void ProppatchHandler::endDocument() {
291
292 }
293

mercurial