|
|
|
@ -3231,10 +3231,9 @@ webdav_propfind_resource (const webdav_propfind_bufs * const restrict pb)
|
|
|
|
|
buffer * const restrict b_200 = pb->b_200;
|
|
|
|
|
buffer * const restrict b_404 = pb->b_404;
|
|
|
|
|
if (b->size - b->used < b_200->used + b_404->used + 1024) {
|
|
|
|
|
size_t sz = b->used + BUFFER_MAX_REUSE_SIZE
|
|
|
|
|
+ b_200->used + b_404->used + 1024;
|
|
|
|
|
size_t sz = b->used + 8192-1 + b_200->used + b_404->used + 1024 - 1;
|
|
|
|
|
/*(optimization; buffer is extended as needed)*/
|
|
|
|
|
buffer_string_prepare_append(b, sz & (BUFFER_MAX_REUSE_SIZE-1));
|
|
|
|
|
buffer_string_prepare_append(b, sz & (8192-1));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buffer_append_string_len(b, CONST_STR_LEN(
|
|
|
|
@ -3566,7 +3565,7 @@ webdav_has_lock (connection * const con,
|
|
|
|
|
* Revisit to properly support shared locks. */
|
|
|
|
|
|
|
|
|
|
struct webdav_lock_token_submitted_st cbdata;
|
|
|
|
|
cbdata.b = buffer_init();
|
|
|
|
|
cbdata.b = chunk_buffer_acquire();
|
|
|
|
|
cbdata.tokens = NULL;
|
|
|
|
|
cbdata.used = 0;
|
|
|
|
|
cbdata.size = 0;
|
|
|
|
@ -3631,6 +3630,7 @@ webdav_has_lock (connection * const con,
|
|
|
|
|
struct stat st;
|
|
|
|
|
if (0 != lstat(con->physical.path->ptr, &st)) {
|
|
|
|
|
http_status_set_error(con,412);/* Precondition Failed */
|
|
|
|
|
chunk_buffer_release(cbdata.b);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (S_ISDIR(st.st_mode)) continue;/*we ignore etag if dir*/
|
|
|
|
@ -3642,6 +3642,7 @@ webdav_has_lock (connection * const con,
|
|
|
|
|
*p = ']';
|
|
|
|
|
if (!ematch) {
|
|
|
|
|
http_status_set_error(con,412);/* Precondition Failed */
|
|
|
|
|
chunk_buffer_release(cbdata.b);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
@ -3652,6 +3653,7 @@ webdav_has_lock (connection * const con,
|
|
|
|
|
sizeof("<DAV:no-lock>")-1)) {
|
|
|
|
|
if (0 == notflag) {
|
|
|
|
|
http_status_set_error(con,412);/* Precondition Failed */
|
|
|
|
|
chunk_buffer_release(cbdata.b);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
p += sizeof("<DAV:no-lock>")-2; /* point p to '>' */
|
|
|
|
@ -3666,6 +3668,7 @@ webdav_has_lock (connection * const con,
|
|
|
|
|
if (cbdata.size == cbdata.used) {
|
|
|
|
|
if (cbdata.size == 16) { /* arbitrary limit */
|
|
|
|
|
http_status_set_error(con, 400); /* Bad Request */
|
|
|
|
|
chunk_buffer_release(cbdata.b);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
cbdata.tokens =
|
|
|
|
@ -3719,7 +3722,7 @@ webdav_has_lock (connection * const con,
|
|
|
|
|
if (!has_lock)
|
|
|
|
|
webdav_xml_doc_error_lock_token_submitted(con, cbdata.b);
|
|
|
|
|
|
|
|
|
|
buffer_free(cbdata.b);
|
|
|
|
|
chunk_buffer_release(cbdata.b);
|
|
|
|
|
|
|
|
|
|
return (has_lock > 0);
|
|
|
|
|
}
|
|
|
|
@ -3921,12 +3924,9 @@ mod_webdav_propfind (connection * const con, const plugin_config * const pconf)
|
|
|
|
|
pb.pconf = pconf;
|
|
|
|
|
pb.dst = &con->physical;
|
|
|
|
|
pb.b = /*(optimization; buf extended as needed)*/
|
|
|
|
|
chunkqueue_append_buffer_open_sz(con->write_queue, BUFFER_MAX_REUSE_SIZE);
|
|
|
|
|
pb.b_200 = buffer_init();
|
|
|
|
|
pb.b_404 = buffer_init();
|
|
|
|
|
|
|
|
|
|
buffer_string_prepare_copy(pb.b_200, BUFFER_MAX_REUSE_SIZE-1);
|
|
|
|
|
buffer_string_prepare_copy(pb.b_404, BUFFER_MAX_REUSE_SIZE-1);
|
|
|
|
|
chunkqueue_append_buffer_open_sz(con->write_queue, 8192);
|
|
|
|
|
pb.b_200 = chunk_buffer_acquire();
|
|
|
|
|
pb.b_404 = chunk_buffer_acquire();
|
|
|
|
|
|
|
|
|
|
webdav_xml_doctype(pb.b, con);
|
|
|
|
|
buffer_append_string_len(pb.b, CONST_STR_LEN(
|
|
|
|
@ -3946,8 +3946,8 @@ mod_webdav_propfind (connection * const con, const plugin_config * const pconf)
|
|
|
|
|
|
|
|
|
|
http_status_set_fin(con, 207); /* Multi-status */
|
|
|
|
|
|
|
|
|
|
buffer_free(pb.b_404);
|
|
|
|
|
buffer_free(pb.b_200);
|
|
|
|
|
chunk_buffer_release(pb.b_404);
|
|
|
|
|
chunk_buffer_release(pb.b_200);
|
|
|
|
|
#ifdef USE_PROPPATCH
|
|
|
|
|
if (pb.proplist.ptr)
|
|
|
|
|
free(pb.proplist.ptr);
|
|
|
|
@ -4025,7 +4025,7 @@ mod_webdav_delete (connection * const con, const plugin_config * const pconf)
|
|
|
|
|
return HANDLER_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buffer * const ms = buffer_init(); /* multi-status */
|
|
|
|
|
buffer * const ms = chunk_buffer_acquire(); /* multi-status */
|
|
|
|
|
|
|
|
|
|
const int flags = (con->conf.force_lowercase_filenames)
|
|
|
|
|
? WEBDAV_FLAG_LC_NAMES
|
|
|
|
@ -4042,7 +4042,7 @@ mod_webdav_delete (connection * const con, const plugin_config * const pconf)
|
|
|
|
|
webdav_xml_doc_multistatus(con, pconf, ms); /* 207 Multi-status */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buffer_free(ms);
|
|
|
|
|
chunk_buffer_release(ms);
|
|
|
|
|
/* invalidate stat cache of src if DELETE, whether or not successful */
|
|
|
|
|
stat_cache_delete_dir(CONST_BUF_LEN(con->physical.path));
|
|
|
|
|
}
|
|
|
|
@ -4809,7 +4809,7 @@ mod_webdav_copymove_b (connection * const con, const plugin_config * const pconf
|
|
|
|
|
buffer_append_slash(dst_path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buffer * const ms = buffer_init(); /* multi-status */
|
|
|
|
|
buffer * const ms = chunk_buffer_acquire(); /* multi-status */
|
|
|
|
|
if (0 == webdav_copymove_dir(pconf, &con->physical, &dst, ms, flags)) {
|
|
|
|
|
if (con->request.http_method == HTTP_METHOD_MOVE)
|
|
|
|
|
webdav_lock_delete_uri_col(pconf, con->physical.rel_path);
|
|
|
|
@ -4825,7 +4825,7 @@ mod_webdav_copymove_b (connection * const con, const plugin_config * const pconf
|
|
|
|
|
* locks on internal elements that are successfully moved */
|
|
|
|
|
webdav_xml_doc_multistatus(con, pconf, ms); /* 207 Multi-status */
|
|
|
|
|
}
|
|
|
|
|
buffer_free(ms);
|
|
|
|
|
chunk_buffer_release(ms);
|
|
|
|
|
/* invalidate stat cache of src if MOVE, whether or not successful */
|
|
|
|
|
if (con->request.http_method == HTTP_METHOD_MOVE)
|
|
|
|
|
stat_cache_delete_dir(CONST_BUF_LEN(con->physical.path));
|
|
|
|
@ -4929,11 +4929,11 @@ mod_webdav_copymove_b (connection * const con, const plugin_config * const pconf
|
|
|
|
|
static handler_t
|
|
|
|
|
mod_webdav_copymove (connection * const con, const plugin_config * const pconf)
|
|
|
|
|
{
|
|
|
|
|
buffer *dst_path = buffer_init();
|
|
|
|
|
buffer *dst_rel_path = buffer_init();
|
|
|
|
|
buffer *dst_path = chunk_buffer_acquire();
|
|
|
|
|
buffer *dst_rel_path = chunk_buffer_acquire();
|
|
|
|
|
handler_t rc = mod_webdav_copymove_b(con, pconf, dst_path, dst_rel_path);
|
|
|
|
|
buffer_free(dst_rel_path);
|
|
|
|
|
buffer_free(dst_path);
|
|
|
|
|
chunk_buffer_release(dst_rel_path);
|
|
|
|
|
chunk_buffer_release(dst_path);
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -5049,7 +5049,7 @@ mod_webdav_proppatch (connection * const con, const plugin_config * const pconf)
|
|
|
|
|
/* error: missing namespace for property */
|
|
|
|
|
log_error(con->conf.errh, __FILE__, __LINE__,
|
|
|
|
|
"no namespace for: %s", prop->name);
|
|
|
|
|
if (!ms) ms = buffer_init(); /* Unprocessable Entity */
|
|
|
|
|
if (!ms) ms = chunk_buffer_acquire(); /* Unprocessable Entity */
|
|
|
|
|
webdav_xml_propstat_status(ms, "", (char *)prop->name, 422);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
@ -5066,7 +5066,7 @@ mod_webdav_proppatch (connection * const con, const plugin_config * const pconf)
|
|
|
|
|
++list;
|
|
|
|
|
if (NULL != list->prop) {
|
|
|
|
|
/* error <DAV:cannot-modify-protected-property/> */
|
|
|
|
|
if (!ms) ms = buffer_init();
|
|
|
|
|
if (!ms) ms = chunk_buffer_acquire();
|
|
|
|
|
webdav_xml_propstat_protected(ms, (char *)prop->name,
|
|
|
|
|
namelen, 403); /* Forbidden */
|
|
|
|
|
continue;
|
|
|
|
@ -5103,7 +5103,7 @@ mod_webdav_proppatch (connection * const con, const plugin_config * const pconf)
|
|
|
|
|
/* workaround Microsoft-WebDAV-MiniRedir bug; 204 not handled */
|
|
|
|
|
/* 200 without response body or 204 both incorrectly interpreted
|
|
|
|
|
* as 507 Insufficient Storage by Microsoft-WebDAV-MiniRedir. */
|
|
|
|
|
ms = buffer_init(); /* 207 Multi-status */
|
|
|
|
|
ms = chunk_buffer_acquire(); /* 207 Multi-status */
|
|
|
|
|
webdav_xml_response_status(ms, con->physical.path, 200);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -5116,7 +5116,7 @@ mod_webdav_proppatch (connection * const con, const plugin_config * const pconf)
|
|
|
|
|
http_status_set_error(con, 500); /* Internal Server Error */
|
|
|
|
|
|
|
|
|
|
if (NULL != ms)
|
|
|
|
|
buffer_free(ms);
|
|
|
|
|
chunk_buffer_release(ms);
|
|
|
|
|
|
|
|
|
|
xmlFreeDoc(xml);
|
|
|
|
|
return HANDLER_FINISHED;
|
|
|
|
@ -5309,17 +5309,17 @@ mod_webdav_lock (connection * const con, const plugin_config * const pconf)
|
|
|
|
|
* and prior to using entropy to create uuid */
|
|
|
|
|
struct webdav_conflicting_lock_st cbdata;
|
|
|
|
|
cbdata.lockdata = &lockdata;
|
|
|
|
|
cbdata.b = buffer_init();
|
|
|
|
|
cbdata.b = chunk_buffer_acquire();
|
|
|
|
|
webdav_lock_activelocks(pconf, &lockdata.lockroot,
|
|
|
|
|
(0 == lockdata.depth ? 1 : -1),
|
|
|
|
|
webdav_conflicting_lock_cb, &cbdata);
|
|
|
|
|
if (0 != cbdata.b->used) {
|
|
|
|
|
/* 423 Locked */
|
|
|
|
|
webdav_xml_doc_error_no_conflicting_lock(con, cbdata.b);
|
|
|
|
|
buffer_free(cbdata.b);
|
|
|
|
|
chunk_buffer_release(cbdata.b);
|
|
|
|
|
break; /* clean up resources and return HANDLER_FINISHED */
|
|
|
|
|
}
|
|
|
|
|
buffer_free(cbdata.b);
|
|
|
|
|
chunk_buffer_release(cbdata.b);
|
|
|
|
|
|
|
|
|
|
int created = 0;
|
|
|
|
|
struct stat st;
|
|
|
|
|