Sat, 17 Oct 2015 23:05:23 +0200
added date header to response
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2013 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <ucx/string.h> #include <ucx/list.h> #include "../util/pool.h" #include "saxhandler.h" using namespace std; void xstack_push(UcxList **stack, XmlElement *elm) { *stack = ucx_list_prepend(*stack, elm); } XmlElement* xstack_pop(UcxList **stack) { if(*stack == NULL) { return NULL; } XmlElement* ret = (XmlElement*)(*stack)->data; UcxList *newstack = ucx_list_remove(*stack, *stack); *stack = newstack; return ret; } PropfindHandler::PropfindHandler(PropfindRequest *rq, pool_handle_t *p) { davrq = rq; pool = p; davPropTag = false; property = NULL; } PropfindHandler::~PropfindHandler() { } void PropfindHandler::startElement( const XMLCh *const uri, const XMLCh* const localname, const XMLCh* const qname, const Attributes& attrs) { char *ns = XMLString::transcode(uri); char *name = XMLString::transcode(localname); if(!strcmp(ns, "DAV:") && !strcmp(name, "allprop")) { davrq->allprop = 1; } else if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) { davPropTag = true; } else if(davPropTag && property == NULL && !davrq->allprop) { property = (DavProperty*)pool_malloc(pool, sizeof(DavProperty)); size_t nslen = strlen(ns); size_t namelen = strlen(name); if(nslen > 0) { //property->xmlns = (char*)pool_malloc(pool, nslen + 1); //property->xmlns[nslen] = 0; property->xmlns = xmlnsmap_put(davrq->nsmap, ns); //memcpy(property->xmlns, ns, nslen); } else { property->xmlns = NULL; } if(namelen > 0) { property->name = (char*)pool_malloc(pool, namelen + 1); property->name[namelen] = 0; memcpy(property->name, name, namelen); } else { property->name = NULL; } } XMLString::release(&ns); XMLString::release(&name); } void PropfindHandler::endElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname) { char *ns = XMLString::transcode(uri); char *name = XMLString::transcode(localname); if(property != NULL) { const char *xmlns = (property->xmlns) ? property->xmlns->xmlns : ""; if(!strcmp(ns, xmlns) && !strcmp(name, property->name)) { // add property to DavRequest UcxList *elm = (UcxList*)pool_malloc(pool, sizeof(UcxList)); elm->prev = NULL; elm->next = NULL; elm->data = property; //printf("saxhandler: add property: {%s}\n", property->name); davrq->properties = ucx_list_concat(davrq->properties, elm); property = NULL; } } XMLString::release(&ns); XMLString::release(&name); } void PropfindHandler::startDocument() { } void PropfindHandler::endDocument() { } /************* PropPatch Handler **************/ ProppatchHandler::ProppatchHandler(ProppatchRequest *rq, pool_handle_t *p) { davrq = rq; pool = p; davPropTag = false; rootElement = NULL; xmlStack = NULL; newElement = NULL; updateMode = -1; } ProppatchHandler::~ProppatchHandler() { ucx_list_free(xmlStack); } void ProppatchHandler::startElement( const XMLCh *const uri, const XMLCh* const localname, const XMLCh* const qname, const Attributes& attrs) { char *ns = XMLString::transcode(uri); char *name = XMLString::transcode(localname); if(!strcmp(ns, "DAV:") && !strcmp(name, "set")) { updateMode = 0; } else if(!strcmp(ns, "DAV:") && !strcmp(name, "remove")) { updateMode = 1; } else if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) { davPropTag = true; } else if(davPropTag) { newElement = (XmlElement*)pool_calloc(pool, 1, sizeof(XmlElement)); newElement->name = pool_strdup(pool, name); newElement->xmlns = xmlnsmap_put(davrq->nsmap, ns); /* * the xml stack manages the xml hierarchy * new elements will be added to the top element on the stack */ XmlElement *currentElm = XSTACK_CUR(); if(currentElm) { xmlelm_add_child(currentElm, newElement); } /* newElement is now the parent for future elements */ XSTACK_PUSH(newElement); /* if the root element isn't set, the first new element is the root */ if(!rootElement) { rootElement = newElement; } } XMLString::release(&ns); XMLString::release(&name); } void ProppatchHandler::endElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname) { char *ns = XMLString::transcode(uri); char *name = XMLString::transcode(localname); if(!strcmp(ns, "DAV:") && !strcmp(name, "set")) { updateMode = -1; } else if(!strcmp(ns, "DAV:") && !strcmp(name, "remove")) { updateMode = -1; } else if(!strcmp(ns, "DAV:") && !strcmp(name, "prop")) { davPropTag = false; } else if(davPropTag) { XmlElement *elm = XSTACK_POP(); if(xmlStack == NULL) { /* property complete */ /* XmlElement *r = rootElement; printf("<%s>\n", sstrdup(r->name).ptr); printf("%s\n", r->content); printf("</%s>\n", sstrdup(r->name).ptr); */ /* add the property to the proppatch request */ switch(updateMode) { case 0: { davrq->setProps = ucx_list_append( davrq->setProps, rootElement); break; } case 1: { davrq->removeProps = ucx_list_append( davrq->removeProps, rootElement); break; } } rootElement = NULL; } } XMLString::release(&ns); XMLString::release(&name); } void ProppatchHandler::characters( const XMLCh *const chars, const XMLSize_t length) { XMLString::trim((XMLCh *const)chars); if(chars[0] == 0) { return; } XmlElement *currentElm = XSTACK_CUR(); if(currentElm) { xmlch_t *str = (xmlch_t*)pool_calloc(pool, sizeof(xmlch_t), length + 1); for(int i=0;i<length;i++) { str[i] = chars[i]; } str[length] = 0; currentElm->content = str; currentElm->ctlen = length; } } void ProppatchHandler::startDocument() { } void ProppatchHandler::endDocument() { }