--- a/dav/propfind.c Sat Dec 01 20:34:55 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,229 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2012 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 "utils.h" -#include "propfind.h" - -Propfind* dav_propfind(CURL *handle) { - Propfind *response = malloc(sizeof(Propfind)); - response->resource = NULL; - response->children = NULL; - - curl_easy_setopt(handle, CURLOPT_CUSTOMREQUEST, "PROPFIND"); - - struct curl_slist *headers = NULL; - headers = curl_slist_append(headers, "Content-Type: text/xml"); - headers = curl_slist_append(headers, "Depth: 1"); - curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers); - - UcxBuffer *rqbuf = create_propfind_request_body(); - UcxBuffer *rpbuf = ucx_buffer_new(NULL, 4096, UCX_BUFFER_AUTOEXTEND); - //printf("request\n%s\n", body->space); - - curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0); - - curl_easy_setopt(handle, CURLOPT_UPLOAD, 1); - curl_easy_setopt(handle, CURLOPT_READFUNCTION, ucx_buffer_read); - curl_easy_setopt(handle, CURLOPT_READDATA, rqbuf); - curl_easy_setopt(handle, CURLOPT_INFILESIZE, rqbuf->size); - - curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, ucx_buffer_write); - curl_easy_setopt(handle, CURLOPT_WRITEDATA, rpbuf); - - ucx_buffer_seek(rqbuf, 0, SEEK_SET); - CURLcode res = curl_easy_perform(handle); - if(res == CURLE_OK) { - printf("response\n%s\n", rpbuf->space); - - char *url = NULL; - curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &url); - response->url = util_url_path(url); - - parse_propfind(response, rpbuf); - - response->url = strdup(url); - } - curl_easy_reset(handle); - - return response; -} - -UcxBuffer* create_propfind_request_body() { - UcxBuffer *buf = ucx_buffer_new(NULL, 512, 0); - sstr_t s; - - s = ST("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"); - ucx_buffer_write(s.ptr, 1, s.length, buf); - - s = ST("<D:propfind xmlns:D=\"DAV:\">\n"); - ucx_buffer_write(s.ptr, 1, s.length, buf); - - s = ST("<D:prop>\n"); - ucx_buffer_write(s.ptr, 1, s.length, buf); - - s = ST("<D:creationdate />\n<D:getlastmodified />\n"); - ucx_buffer_write(s.ptr, 1, s.length, buf); - - s = ST("<D:getcontentlength />\n<D:getcontenttype />\n"); - ucx_buffer_write(s.ptr, 1, s.length, buf); - - s = ST("<D:resourcetype />\n"); - ucx_buffer_write(s.ptr, 1, s.length, buf); - - s = ST("</D:prop>\n</D:propfind>\n"); - ucx_buffer_write(s.ptr, 1, s.length, buf); - - return buf; -} - -int parse_propfind(Propfind *propfind, UcxBuffer *response) { - xmlTextReaderPtr reader = xmlReaderForMemory( - response->space, - response->size, - propfind->url, - NULL, - 0); - - int ret = 0; - if(reader != NULL) { - int r; - while((r = xmlTextReaderRead(reader)) == 1) { - int nodetype = xmlTextReaderNodeType(reader); - if(nodetype == XML_READER_TYPE_ELEMENT) { - const xmlChar *name = xmlTextReaderConstLocalName(reader); - if(!xmlStrcmp(name, BAD_CAST "response")) { - r = parse_response(reader, propfind); - if(r != 0) { - ret = -1; - break; - } - } - } - } - xmlFreeTextReader(reader); - } - - return ret; -} - -int parse_response(xmlTextReaderPtr reader, Propfind *propfind) { - DavResource *res = calloc(sizeof(DavResource), 1); - if(res == NULL) { - return -1; - } - - /* - * 0: href - * 1: creationdate - * 2: getlastmodified - * 3: getcontentlength - * 4: getcontenttype - * 5: resourcetype - */ - int valuetype = -1; - - int r; - while((r = xmlTextReaderRead(reader)) == 1) { - int nodetype = xmlTextReaderNodeType(reader); - - if(nodetype == XML_READER_TYPE_END_ELEMENT) { - const xmlChar *name = xmlTextReaderConstLocalName(reader); - if(!xmlStrcmp(name, BAD_CAST "response")) { - break; - } - } - - switch(nodetype) { - case XML_READER_TYPE_ELEMENT: { - const xmlChar *name = xmlTextReaderConstLocalName(reader); - if(!xmlStrcmp(name, BAD_CAST "href")) { - valuetype = 0; - } else if(!xmlStrcmp(name, BAD_CAST "creationdate")) { - valuetype = 1; - } else if(!xmlStrcmp(name, BAD_CAST "getlastmodified")) { - valuetype = 2; - } else if(!xmlStrcmp(name, BAD_CAST "getcontentlength")) { - valuetype = 3; - } else if(!xmlStrcmp(name, BAD_CAST "getcontenttype")) { - valuetype = 4; - } else if(!xmlStrcmp(name, BAD_CAST "resourcetype")) { - valuetype = 5; - } else if(!xmlStrcmp(name, BAD_CAST "collection") - && valuetype == 5) { - res->collection = 1; - } else { - valuetype = -1; - } - break; - } - case XML_READER_TYPE_TEXT: { - const xmlChar *cvalue = xmlTextReaderConstValue(reader); - if(cvalue == NULL) { - break; - } - char *value = strdup((char*)cvalue); - switch(valuetype) { - case 0: { - res->href = value; - res->name = util_resource_name(value); - break; - } - case 1: { - res->creationdate = 0; // TODO - break; - } - case 2: { - res->lastmodified = 0; // TODO - break; - } - case 3: { - res->contentlength = atoi(value); - break; - } - case 4: { - res->contenttype = value; - //break; - } - } - //break; - } - } - } - - if(!strcmp(res->href, propfind->url)) { - propfind->resource = res; - } else { - propfind->children = ucx_dlist_append(propfind->children, res); - } - - return 0; -}