diff --git a/src/mod_webdav.c b/src/mod_webdav.c index a19f5db1..e7d33d26 100644 --- a/src/mod_webdav.c +++ b/src/mod_webdav.c @@ -1292,37 +1292,26 @@ static int webdav_has_lock(server *srv, connection *con, handler_ctx *hctx, buff return has_lock; } +static int mod_webdav_depth(connection *con) { + buffer *b = + http_header_request_get(con, HTTP_HEADER_OTHER, CONST_STR_LEN("Depth")); + if (NULL != b && 1 == buffer_string_length(b)) { + if (b->ptr[0] == '0') return 0; + if (b->ptr[0] == '1') return 1; + } + return -1; /* (Depth: infinity) */ +} -SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) { - plugin_data *p = p_d; - handler_ctx *hctx = con->plugin_ctx[p->id]; +static handler_t mod_webdav_propfind(server *srv, connection *con, plugin_data *p, handler_ctx *hctx) { buffer *b; DIR *dir; - int depth = -1; /* (Depth: infinity) */ + int depth = mod_webdav_depth(con); struct stat st; buffer *prop_200; buffer *prop_404; webdav_properties *req_props; stat_cache_entry *sce = NULL; - UNUSED(srv); - - if (NULL == hctx) return HANDLER_GO_ON; - if (!hctx->conf.enabled) return HANDLER_GO_ON; - /* physical path is setup */ - if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON; - - /* PROPFIND need them */ - if (NULL != (b = http_header_request_get(con, HTTP_HEADER_OTHER, CONST_STR_LEN("Depth"))) && 1 == buffer_string_length(b)) { - if ('0' == *b->ptr) { - depth = 0; - } else if ('1' == *b->ptr) { - depth = 1; - } - } /* else treat as Depth: infinity */ - - switch (con->request.http_method) { - case HTTP_METHOD_PROPFIND: /* they want to know the properties of the directory */ req_props = NULL; @@ -1601,7 +1590,9 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) { con->file_finished = 1; return HANDLER_FINISHED; - case HTTP_METHOD_MKCOL: +} + +static handler_t mod_webdav_mkcol(connection *con, plugin_data *p) { if (p->conf.is_readonly) { con->http_status = 403; return HANDLER_FINISHED; @@ -1636,7 +1627,11 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) { } return HANDLER_FINISHED; - case HTTP_METHOD_DELETE: +} + +static handler_t mod_webdav_delete(server *srv, connection *con, plugin_data *p, handler_ctx *hctx) { + struct stat st; + if (p->conf.is_readonly) { con->http_status = 403; return HANDLER_FINISHED; @@ -1671,6 +1666,7 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) { if (webdav_delete_dir(srv, con, hctx, &(con->physical), multi_status_resp)) { /* we got an error somewhere in between, build a 207 */ + buffer *b; http_header_response_set(con, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\"")); b = chunkqueue_append_buffer_open(con->write_queue); @@ -1728,7 +1724,10 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) { con->http_status = 204; } return HANDLER_FINISHED; - case HTTP_METHOD_PUT: { +} + +static handler_t mod_webdav_put(server *srv, connection *con, plugin_data *p, handler_ctx *hctx) { + buffer *b; int fd; chunkqueue *cq = con->request_content_queue; chunk *c; @@ -1916,9 +1915,11 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) { } return HANDLER_FINISHED; - } - case HTTP_METHOD_MOVE: - case HTTP_METHOD_COPY: { +} + +static handler_t mod_webdav_copymove(server *srv, connection *con, plugin_data *p, handler_ctx *hctx) { + buffer *b; + struct stat st; buffer *destination = NULL; char *sep, *sep2, *start; int overwrite = 1; @@ -2212,8 +2213,10 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) { } return HANDLER_FINISHED; - } - case HTTP_METHOD_PROPPATCH: +} + +static handler_t mod_webdav_proppatch(server *srv, connection *con, plugin_data *p, handler_ctx *hctx) { + struct stat st; if (p->conf.is_readonly) { con->http_status = 403; return HANDLER_FINISHED; @@ -2380,7 +2383,9 @@ propmatch_cleanup: #endif con->http_status = 501; return HANDLER_FINISHED; - case HTTP_METHOD_LOCK: +} + +static handler_t mod_webdav_lock(server *srv, connection *con, plugin_data *p, handler_ctx *hctx) { /** * a mac wants to write * @@ -2404,6 +2409,7 @@ propmatch_cleanup: * \n */ + int depth = mod_webdav_depth(con); if (depth != 0 && depth != -1) { con->http_status = 400; @@ -2415,6 +2421,7 @@ propmatch_cleanup: xmlDocPtr xml; buffer *hdr_if = NULL; int created = 0; + struct stat st; if (con->state == CON_STATE_READ_POST) { handler_t r = connection_handle_read_post_state(srv, con); @@ -2603,7 +2610,7 @@ propmatch_cleanup: return HANDLER_FINISHED; } } else { - + buffer *b; if (NULL != (b = http_header_request_get(con, HTTP_HEADER_OTHER, CONST_STR_LEN("If")))) { buffer *locktoken = b; sqlite3_stmt *stmt = p->conf.stmt_refresh_lock; @@ -2640,13 +2647,15 @@ propmatch_cleanup: return HANDLER_FINISHED; } } - break; #else con->http_status = 501; return HANDLER_FINISHED; #endif - case HTTP_METHOD_UNLOCK: +} + +static handler_t mod_webdav_unlock(server *srv, connection *con, plugin_data *p) { #ifdef USE_LOCKS + buffer *b; if (NULL != (b = http_header_request_get(con, HTTP_HEADER_OTHER, CONST_STR_LEN("Lock-Token")))) { buffer *locktoken = b; sqlite3_stmt *stmt = p->conf.stmt_remove_lock; @@ -2693,17 +2702,42 @@ propmatch_cleanup: return HANDLER_FINISHED; } - break; #else con->http_status = 501; return HANDLER_FINISHED; #endif +} + +SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) { + plugin_data *p = p_d; + handler_ctx *hctx = con->plugin_ctx[p->id]; + + if (NULL == hctx) return HANDLER_GO_ON; + if (!hctx->conf.enabled) return HANDLER_GO_ON; + /* physical path is setup */ + if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON; + + switch (con->request.http_method) { + case HTTP_METHOD_PROPFIND: + return mod_webdav_propfind(srv, con, p, hctx); + case HTTP_METHOD_MKCOL: + return mod_webdav_mkcol(con, p); + case HTTP_METHOD_DELETE: + return mod_webdav_delete(srv, con, p, hctx); + case HTTP_METHOD_PUT: + return mod_webdav_put(srv, con, p, hctx); + case HTTP_METHOD_MOVE: + case HTTP_METHOD_COPY: + return mod_webdav_copymove(srv, con, p, hctx); + case HTTP_METHOD_PROPPATCH: + return mod_webdav_proppatch(srv, con, p, hctx); + case HTTP_METHOD_LOCK: + return mod_webdav_lock(srv, con, p, hctx); + case HTTP_METHOD_UNLOCK: + return mod_webdav_unlock(srv, con, p); default: - break; + return HANDLER_GO_ON; /* not found */ } - - /* not found */ - return HANDLER_GO_ON; }