fix race in dynamic handler configs (reentrancy) (fixes #2774)
(thx tobbe303) x-ref: "CGI request not handled" https://redmine.lighttpd.net/issues/2774personal/stbuehler/mod-csrf
parent
df61f19daf
commit
5bf5e1adcc
|
@ -95,6 +95,7 @@ typedef struct {
|
|||
|
||||
buffer *response;
|
||||
buffer *response_header;
|
||||
plugin_config conf;
|
||||
} handler_ctx;
|
||||
|
||||
static handler_ctx * cgi_handler_ctx_init(void) {
|
||||
|
@ -562,10 +563,10 @@ static int cgi_demux_response(server *srv, handler_ctx *hctx) {
|
|||
}
|
||||
}
|
||||
|
||||
if (p->conf.xsendfile_allow) {
|
||||
if (hctx->conf.xsendfile_allow) {
|
||||
data_string *ds;
|
||||
if (NULL != (ds = (data_string *) array_get_element(con->response.headers, "X-Sendfile"))) {
|
||||
http_response_xsendfile(srv, con, ds->value, p->conf.xsendfile_docroot);
|
||||
http_response_xsendfile(srv, con, ds->value, hctx->conf.xsendfile_docroot);
|
||||
return FDEVENT_HANDLED_FINISHED;
|
||||
}
|
||||
}
|
||||
|
@ -1335,6 +1336,7 @@ URIHANDLER_FUNC(cgi_is_handled) {
|
|||
handler_ctx *hctx = cgi_handler_ctx_init();
|
||||
hctx->remote_conn = con;
|
||||
hctx->plugin_data = p;
|
||||
memcpy(&hctx->conf, &p->conf, sizeof(plugin_config));
|
||||
con->plugin_ctx[p->id] = hctx;
|
||||
con->mode = p->id;
|
||||
}
|
||||
|
@ -1442,7 +1444,7 @@ SUBREQUEST_FUNC(mod_cgi_handle_subrequest) {
|
|||
}
|
||||
|
||||
if (-1 == hctx->fd) {
|
||||
buffer *handler = cgi_get_handler(p->conf.cgi, con->physical.path);
|
||||
buffer *handler = cgi_get_handler(hctx->conf.cgi, con->physical.path);
|
||||
if (!handler) return HANDLER_GO_ON; /*(should not happen; checked in cgi_is_handled())*/
|
||||
if (cgi_create_env(srv, con, p, hctx, handler)) {
|
||||
con->http_status = 500;
|
||||
|
|
|
@ -305,8 +305,6 @@ typedef struct {
|
|||
|
||||
buffer *fcgi_env;
|
||||
|
||||
buffer *path;
|
||||
|
||||
buffer *statuskey;
|
||||
|
||||
plugin_config **config_storage;
|
||||
|
@ -701,8 +699,6 @@ INIT_FUNC(mod_fastcgi_init) {
|
|||
|
||||
p->fcgi_env = buffer_init();
|
||||
|
||||
p->path = buffer_init();
|
||||
|
||||
p->statuskey = buffer_init();
|
||||
|
||||
return p;
|
||||
|
@ -715,7 +711,6 @@ FREE_FUNC(mod_fastcgi_free) {
|
|||
UNUSED(srv);
|
||||
|
||||
buffer_free(p->fcgi_env);
|
||||
buffer_free(p->path);
|
||||
buffer_free(p->statuskey);
|
||||
|
||||
if (p->config_storage) {
|
||||
|
|
|
@ -348,7 +348,7 @@ static void proxy_backend_close(server *srv, handler_ctx *hctx) {
|
|||
}
|
||||
}
|
||||
|
||||
static data_proxy * mod_proxy_extension_host_get(server *srv, connection *con, plugin_data *p, data_array *extension) {
|
||||
static data_proxy * mod_proxy_extension_host_get(server *srv, connection *con, data_array *extension, proxy_balance_t balance, int debug) {
|
||||
unsigned long last_max = ULONG_MAX;
|
||||
int max_usage = INT_MAX;
|
||||
int ndx = -1;
|
||||
|
@ -360,11 +360,11 @@ static data_proxy * mod_proxy_extension_host_get(server *srv, connection *con, p
|
|||
} else {
|
||||
ndx = 0;
|
||||
}
|
||||
} else if (extension->value->used != 0) switch(p->conf.balance) {
|
||||
} else if (extension->value->used != 0) switch(balance) {
|
||||
case PROXY_BALANCE_HASH:
|
||||
/* hash balancing */
|
||||
|
||||
if (p->conf.debug) {
|
||||
if (debug) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sd",
|
||||
"proxy - used hash balancing, hosts:", extension->value->used);
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ static data_proxy * mod_proxy_extension_host_get(server *srv, connection *con, p
|
|||
generate_crc32c(CONST_BUF_LEN(host->host)) + /* we can cache this */
|
||||
generate_crc32c(CONST_BUF_LEN(con->uri.authority));
|
||||
|
||||
if (p->conf.debug) {
|
||||
if (debug) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sbbbd",
|
||||
"proxy - election:",
|
||||
con->uri.path,
|
||||
|
@ -399,7 +399,7 @@ static data_proxy * mod_proxy_extension_host_get(server *srv, connection *con, p
|
|||
break;
|
||||
case PROXY_BALANCE_FAIR:
|
||||
/* fair balancing */
|
||||
if (p->conf.debug) {
|
||||
if (debug) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "s",
|
||||
"proxy - used fair balancing");
|
||||
}
|
||||
|
@ -421,7 +421,7 @@ static data_proxy * mod_proxy_extension_host_get(server *srv, connection *con, p
|
|||
data_proxy *host;
|
||||
|
||||
/* round robin */
|
||||
if (p->conf.debug) {
|
||||
if (debug) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "s",
|
||||
"proxy - used round-robin balancing");
|
||||
}
|
||||
|
@ -464,7 +464,7 @@ static data_proxy * mod_proxy_extension_host_get(server *srv, connection *con, p
|
|||
if (ndx != -1) {
|
||||
data_proxy *host = (data_proxy *)extension->value->data[ndx];
|
||||
|
||||
if (p->conf.debug) {
|
||||
if (debug) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "sbd",
|
||||
"proxy - found a host",
|
||||
host->host, host->port);
|
||||
|
@ -505,7 +505,7 @@ static void proxy_connection_close(server *srv, handler_ctx *hctx) {
|
|||
static handler_t proxy_reconnect(server *srv, handler_ctx *hctx) {
|
||||
proxy_backend_close(srv, hctx);
|
||||
|
||||
hctx->host = mod_proxy_extension_host_get(srv, hctx->remote_conn, hctx->plugin_data, hctx->ext);
|
||||
hctx->host = mod_proxy_extension_host_get(srv, hctx->remote_conn, hctx->ext, hctx->conf.balance, (int)hctx->conf.debug);
|
||||
if (NULL == hctx->host) return HANDLER_FINISHED;
|
||||
|
||||
hctx->state = PROXY_STATE_INIT;
|
||||
|
@ -1271,7 +1271,7 @@ static handler_t mod_proxy_check_extension(server *srv, connection *con, void *p
|
|||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
host = mod_proxy_extension_host_get(srv, con, p, extension);
|
||||
host = mod_proxy_extension_host_get(srv, con, extension, p->conf.balance, (int)p->conf.debug);
|
||||
if (NULL == host) {
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
|
@ -1293,6 +1293,7 @@ static handler_t mod_proxy_check_extension(server *srv, connection *con, void *p
|
|||
hctx->host = host;
|
||||
hctx->ext = extension;
|
||||
|
||||
hctx->conf.balance = p->conf.balance;
|
||||
hctx->conf.debug = p->conf.debug;
|
||||
|
||||
con->plugin_ctx[p->id] = hctx;
|
||||
|
|
|
@ -291,7 +291,6 @@ typedef struct {
|
|||
|
||||
buffer *scgi_env;
|
||||
|
||||
buffer *path;
|
||||
buffer *parse_response;
|
||||
|
||||
plugin_config **config_storage;
|
||||
|
@ -545,7 +544,6 @@ INIT_FUNC(mod_scgi_init) {
|
|||
|
||||
p->scgi_env = buffer_init();
|
||||
|
||||
p->path = buffer_init();
|
||||
p->parse_response = buffer_init();
|
||||
|
||||
return p;
|
||||
|
@ -558,7 +556,6 @@ FREE_FUNC(mod_scgi_free) {
|
|||
UNUSED(srv);
|
||||
|
||||
buffer_free(p->scgi_env);
|
||||
buffer_free(p->path);
|
||||
buffer_free(p->parse_response);
|
||||
|
||||
if (p->config_storage) {
|
||||
|
@ -1606,7 +1603,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
|
|||
|
||||
http_cgi_opts opts = { 0, 0, host->docroot, NULL };
|
||||
|
||||
http_cgi_header_append_cb scgi_env_add = p->conf.proto == LI_PROTOCOL_SCGI
|
||||
http_cgi_header_append_cb scgi_env_add = hctx->conf.proto == LI_PROTOCOL_SCGI
|
||||
? scgi_env_add_scgi
|
||||
: scgi_env_add_uwsgi;
|
||||
|
||||
|
@ -1617,7 +1614,7 @@ static int scgi_create_env(server *srv, handler_ctx *hctx) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (p->conf.proto == LI_PROTOCOL_SCGI) {
|
||||
if (hctx->conf.proto == LI_PROTOCOL_SCGI) {
|
||||
scgi_env_add(p->scgi_env, CONST_STR_LEN("SCGI"), CONST_STR_LEN("1"));
|
||||
b = buffer_init();
|
||||
buffer_append_int(b, buffer_string_length(p->scgi_env));
|
||||
|
@ -2759,6 +2756,7 @@ static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, i
|
|||
hctx->ext = extension;
|
||||
|
||||
/*hctx->conf.exts = p->conf.exts;*/
|
||||
hctx->conf.proto = p->conf.proto;
|
||||
hctx->conf.debug = p->conf.debug;
|
||||
|
||||
con->plugin_ctx[p->id] = hctx;
|
||||
|
@ -2816,6 +2814,7 @@ static handler_t scgi_check_extension(server *srv, connection *con, void *p_d, i
|
|||
hctx->ext = extension;
|
||||
|
||||
/*hctx->conf.exts = p->conf.exts;*/
|
||||
hctx->conf.proto = p->conf.proto;
|
||||
hctx->conf.debug = p->conf.debug;
|
||||
|
||||
con->plugin_ctx[p->id] = hctx;
|
||||
|
|
110
src/mod_webdav.c
110
src/mod_webdav.c
|
@ -89,6 +89,10 @@ typedef struct {
|
|||
plugin_config conf;
|
||||
} plugin_data;
|
||||
|
||||
typedef struct {
|
||||
plugin_config conf;
|
||||
} handler_ctx;
|
||||
|
||||
/* init the plugin data */
|
||||
INIT_FUNC(mod_webdav_init) {
|
||||
plugin_data *p;
|
||||
|
@ -533,7 +537,7 @@ static int webdav_gen_response_status_tag(server *srv, connection *con, physical
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int webdav_delete_file(server *srv, connection *con, plugin_data *p, physical *dst, buffer *b) {
|
||||
static int webdav_delete_file(server *srv, connection *con, handler_ctx *hctx, physical *dst, buffer *b) {
|
||||
int status = 0;
|
||||
|
||||
/* try to unlink it */
|
||||
|
@ -551,7 +555,7 @@ static int webdav_delete_file(server *srv, connection *con, plugin_data *p, phys
|
|||
webdav_gen_response_status_tag(srv, con, dst, status, b);
|
||||
} else {
|
||||
#ifdef USE_PROPPATCH
|
||||
sqlite3_stmt *stmt = p->conf.stmt_delete_uri;
|
||||
sqlite3_stmt *stmt = hctx->conf.stmt_delete_uri;
|
||||
|
||||
if (!stmt) {
|
||||
status = 403;
|
||||
|
@ -577,7 +581,7 @@ static int webdav_delete_file(server *srv, connection *con, plugin_data *p, phys
|
|||
return (status != 0);
|
||||
}
|
||||
|
||||
static int webdav_delete_dir(server *srv, connection *con, plugin_data *p, physical *dst, buffer *b) {
|
||||
static int webdav_delete_dir(server *srv, connection *con, handler_ctx *hctx, physical *dst, buffer *b) {
|
||||
DIR *dir;
|
||||
int have_multi_status = 0;
|
||||
physical d;
|
||||
|
@ -609,7 +613,7 @@ static int webdav_delete_dir(server *srv, connection *con, plugin_data *p, physi
|
|||
if (-1 == stat(d.path->ptr, &st)) {
|
||||
/* don't about it yet, rmdir will fail too */
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
have_multi_status = webdav_delete_dir(srv, con, p, &d, b);
|
||||
have_multi_status = webdav_delete_dir(srv, con, hctx, &d, b);
|
||||
|
||||
/* try to unlink it */
|
||||
if (-1 == rmdir(d.path->ptr)) {
|
||||
|
@ -629,7 +633,7 @@ static int webdav_delete_dir(server *srv, connection *con, plugin_data *p, physi
|
|||
webdav_gen_response_status_tag(srv, con, &d, status, b);
|
||||
} else {
|
||||
#ifdef USE_PROPPATCH
|
||||
sqlite3_stmt *stmt = p->conf.stmt_delete_uri;
|
||||
sqlite3_stmt *stmt = hctx->conf.stmt_delete_uri;
|
||||
|
||||
if (stmt) {
|
||||
sqlite3_reset(stmt);
|
||||
|
@ -647,7 +651,7 @@ static int webdav_delete_dir(server *srv, connection *con, plugin_data *p, physi
|
|||
#endif
|
||||
}
|
||||
} else {
|
||||
have_multi_status = webdav_delete_file(srv, con, p, &d, b);
|
||||
have_multi_status = webdav_delete_file(srv, con, hctx, &d, b);
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
|
@ -670,7 +674,7 @@ static int webdav_delete_dir(server *srv, connection *con, plugin_data *p, physi
|
|||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
static int webdav_copy_file(server *srv, connection *con, plugin_data *p, physical *src, physical *dst, int overwrite) {
|
||||
static int webdav_copy_file(server *srv, connection *con, handler_ctx *hctx, physical *src, physical *dst, int overwrite) {
|
||||
char *data;
|
||||
ssize_t rd, wr, offset;
|
||||
int status = 0, ifd, ofd;
|
||||
|
@ -729,7 +733,7 @@ static int webdav_copy_file(server *srv, connection *con, plugin_data *p, physic
|
|||
#ifdef USE_PROPPATCH
|
||||
if (0 == status) {
|
||||
/* copy worked fine, copy connected properties */
|
||||
sqlite3_stmt *stmt = p->conf.stmt_copy_uri;
|
||||
sqlite3_stmt *stmt = hctx->conf.stmt_copy_uri;
|
||||
|
||||
if (stmt) {
|
||||
sqlite3_reset(stmt);
|
||||
|
@ -754,7 +758,7 @@ static int webdav_copy_file(server *srv, connection *con, plugin_data *p, physic
|
|||
return status;
|
||||
}
|
||||
|
||||
static int webdav_copy_dir(server *srv, connection *con, plugin_data *p, physical *src, physical *dst, int overwrite) {
|
||||
static int webdav_copy_dir(server *srv, connection *con, handler_ctx *hctx, physical *src, physical *dst, int overwrite) {
|
||||
DIR *srcdir;
|
||||
int status = 0;
|
||||
|
||||
|
@ -801,9 +805,9 @@ static int webdav_copy_dir(server *srv, connection *con, plugin_data *p, physica
|
|||
/* WTH ? */
|
||||
} else {
|
||||
#ifdef USE_PROPPATCH
|
||||
sqlite3_stmt *stmt = p->conf.stmt_copy_uri;
|
||||
sqlite3_stmt *stmt = hctx->conf.stmt_copy_uri;
|
||||
|
||||
if (0 != (status = webdav_copy_dir(srv, con, p, &s, &d, overwrite))) {
|
||||
if (0 != (status = webdav_copy_dir(srv, con, hctx, &s, &d, overwrite))) {
|
||||
break;
|
||||
}
|
||||
/* directory is copied, copy the properties too */
|
||||
|
@ -828,7 +832,7 @@ static int webdav_copy_dir(server *srv, connection *con, plugin_data *p, physica
|
|||
}
|
||||
} else if (S_ISREG(st.st_mode)) {
|
||||
/* a plain file */
|
||||
if (0 != (status = webdav_copy_file(srv, con, p, &s, &d, overwrite))) {
|
||||
if (0 != (status = webdav_copy_file(srv, con, hctx, &s, &d, overwrite))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -883,9 +887,9 @@ static void webdav_activelock(buffer *b,
|
|||
buffer_append_string_len(b, CONST_STR_LEN("</D:activelock>\n"));
|
||||
}
|
||||
|
||||
static void webdav_get_live_property_lockdiscovery(server *srv, connection *con, plugin_data *p, physical *dst, buffer *b) {
|
||||
static void webdav_get_live_property_lockdiscovery(server *srv, connection *con, handler_ctx *hctx, physical *dst, buffer *b) {
|
||||
|
||||
sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri;
|
||||
sqlite3_stmt *stmt = hctx->conf.stmt_read_lock_by_uri;
|
||||
if (!stmt) { /*(should not happen)*/
|
||||
buffer_append_string_len(b, CONST_STR_LEN("<D:lockdiscovery>\n</D:lockdiscovery>\n"));
|
||||
return;
|
||||
|
@ -923,11 +927,11 @@ static void webdav_get_live_property_lockdiscovery(server *srv, connection *con,
|
|||
}
|
||||
#endif
|
||||
|
||||
static int webdav_get_live_property(server *srv, connection *con, plugin_data *p, physical *dst, char *prop_name, buffer *b) {
|
||||
static int webdav_get_live_property(server *srv, connection *con, handler_ctx *hctx, physical *dst, char *prop_name, buffer *b) {
|
||||
stat_cache_entry *sce = NULL;
|
||||
int found = 0;
|
||||
|
||||
UNUSED(p);
|
||||
UNUSED(hctx);
|
||||
|
||||
if (HANDLER_ERROR != (stat_cache_get_entry(srv, con, dst->path, &sce))) {
|
||||
char ctime_buf[] = "2005-08-18T07:27:16Z";
|
||||
|
@ -992,7 +996,7 @@ static int webdav_get_live_property(server *srv, connection *con, plugin_data *p
|
|||
found = 1;
|
||||
#ifdef USE_LOCKS
|
||||
} else if (0 == strcmp(prop_name, "lockdiscovery")) {
|
||||
webdav_get_live_property_lockdiscovery(srv, con, p, dst, b);
|
||||
webdav_get_live_property_lockdiscovery(srv, con, hctx, dst, b);
|
||||
found = 1;
|
||||
} else if (0 == strcmp(prop_name, "supportedlock")) {
|
||||
buffer_append_string_len(b,CONST_STR_LEN("<D:supportedlock>"));
|
||||
|
@ -1009,14 +1013,14 @@ static int webdav_get_live_property(server *srv, connection *con, plugin_data *p
|
|||
return found ? 0 : -1;
|
||||
}
|
||||
|
||||
static int webdav_get_property(server *srv, connection *con, plugin_data *p, physical *dst, char *prop_name, char *prop_ns, buffer *b) {
|
||||
static int webdav_get_property(server *srv, connection *con, handler_ctx *hctx, physical *dst, char *prop_name, char *prop_ns, buffer *b) {
|
||||
if (0 == strcmp(prop_ns, "DAV:")) {
|
||||
/* a local 'live' property */
|
||||
return webdav_get_live_property(srv, con, p, dst, prop_name, b);
|
||||
return webdav_get_live_property(srv, con, hctx, dst, prop_name, b);
|
||||
} else {
|
||||
int found = 0;
|
||||
#ifdef USE_PROPPATCH
|
||||
sqlite3_stmt *stmt = p->conf.stmt_select_prop;
|
||||
sqlite3_stmt *stmt = hctx->conf.stmt_select_prop;
|
||||
|
||||
if (stmt) {
|
||||
/* perhaps it is in sqlite3 */
|
||||
|
@ -1081,7 +1085,7 @@ typedef struct {
|
|||
size_t size;
|
||||
} webdav_properties;
|
||||
|
||||
static int webdav_get_props(server *srv, connection *con, plugin_data *p, physical *dst, webdav_properties *props, buffer *b_200, buffer *b_404) {
|
||||
static int webdav_get_props(server *srv, connection *con, handler_ctx *hctx, physical *dst, webdav_properties *props, buffer *b_200, buffer *b_404) {
|
||||
size_t i;
|
||||
|
||||
if (props && props->used) {
|
||||
|
@ -1090,7 +1094,7 @@ static int webdav_get_props(server *srv, connection *con, plugin_data *p, physic
|
|||
|
||||
prop = props->ptr[i];
|
||||
|
||||
if (0 != webdav_get_property(srv, con, p,
|
||||
if (0 != webdav_get_property(srv, con, hctx,
|
||||
dst, prop->prop, prop->ns, b_200)) {
|
||||
webdav_gen_prop_tag(srv, con, prop->prop, prop->ns, NULL, b_404);
|
||||
}
|
||||
|
@ -1098,7 +1102,7 @@ static int webdav_get_props(server *srv, connection *con, plugin_data *p, physic
|
|||
} else {
|
||||
for (i = 0; live_properties[i].prop; i++) {
|
||||
/* a local 'live' property */
|
||||
webdav_get_live_property(srv, con, p, dst, live_properties[i].prop, b_200);
|
||||
webdav_get_live_property(srv, con, hctx, dst, live_properties[i].prop, b_200);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1106,7 +1110,7 @@ static int webdav_get_props(server *srv, connection *con, plugin_data *p, physic
|
|||
}
|
||||
|
||||
#ifdef USE_PROPPATCH
|
||||
static int webdav_parse_chunkqueue(server *srv, connection *con, plugin_data *p, chunkqueue *cq, xmlDoc **ret_xml) {
|
||||
static int webdav_parse_chunkqueue(server *srv, connection *con, handler_ctx *hctx, chunkqueue *cq, xmlDoc **ret_xml) {
|
||||
xmlParserCtxtPtr ctxt;
|
||||
xmlDoc *xml;
|
||||
int res;
|
||||
|
@ -1178,7 +1182,7 @@ static int webdav_parse_chunkqueue(server *srv, connection *con, plugin_data *p,
|
|||
|
||||
if (weHave > weWant) weHave = weWant;
|
||||
|
||||
if (p->conf.log_xml) {
|
||||
if (hctx->conf.log_xml) {
|
||||
log_error_write(srv, __FILE__, __LINE__, "ss", "XML-request-body:", c->mem->ptr + c->offset);
|
||||
}
|
||||
|
||||
|
@ -1248,7 +1252,7 @@ static int webdav_lockdiscovery(server *srv, connection *con,
|
|||
*
|
||||
*
|
||||
*/
|
||||
static int webdav_has_lock(server *srv, connection *con, plugin_data *p, buffer *uri) {
|
||||
static int webdav_has_lock(server *srv, connection *con, handler_ctx *hctx, buffer *uri) {
|
||||
int has_lock = 1;
|
||||
|
||||
#ifdef USE_LOCKS
|
||||
|
@ -1279,7 +1283,7 @@ static int webdav_has_lock(server *srv, connection *con, plugin_data *p, buffer
|
|||
/* we didn't provided a lock-token -> */
|
||||
/* if the resource is locked -> 423 */
|
||||
|
||||
sqlite3_stmt *stmt = p->conf.stmt_read_lock_by_uri;
|
||||
sqlite3_stmt *stmt = hctx->conf.stmt_read_lock_by_uri;
|
||||
|
||||
sqlite3_reset(stmt);
|
||||
|
||||
|
@ -1294,7 +1298,7 @@ static int webdav_has_lock(server *srv, connection *con, plugin_data *p, buffer
|
|||
#else
|
||||
UNUSED(srv);
|
||||
UNUSED(con);
|
||||
UNUSED(p);
|
||||
UNUSED(pconf);
|
||||
UNUSED(uri);
|
||||
#endif
|
||||
|
||||
|
@ -1304,6 +1308,7 @@ static int webdav_has_lock(server *srv, connection *con, plugin_data *p, buffer
|
|||
|
||||
SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
||||
plugin_data *p = p_d;
|
||||
handler_ctx *hctx = con->plugin_ctx[p->id];
|
||||
buffer *b;
|
||||
DIR *dir;
|
||||
data_string *ds;
|
||||
|
@ -1316,7 +1321,8 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
|||
|
||||
UNUSED(srv);
|
||||
|
||||
if (!p->conf.enabled) return HANDLER_GO_ON;
|
||||
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;
|
||||
|
||||
|
@ -1362,7 +1368,7 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
|||
if (r != HANDLER_GO_ON) return r;
|
||||
}
|
||||
|
||||
if (1 == webdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
|
||||
if (1 == webdav_parse_chunkqueue(srv, con, hctx, con->request_content_queue, &xml)) {
|
||||
xmlNode *rootnode = xmlDocGetRootElement(xml);
|
||||
|
||||
force_assert(rootnode);
|
||||
|
@ -1462,7 +1468,7 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
|||
|
||||
{
|
||||
/* Depth: 0 or Depth: 1 */
|
||||
webdav_get_props(srv, con, p, &(con->physical), req_props, prop_200, prop_404);
|
||||
webdav_get_props(srv, con, hctx, &(con->physical), req_props, prop_200, prop_404);
|
||||
|
||||
buffer_append_string_len(b,CONST_STR_LEN("<D:response>\n"));
|
||||
buffer_append_string_len(b,CONST_STR_LEN("<D:href>"));
|
||||
|
@ -1528,7 +1534,7 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
|||
buffer_reset(prop_200);
|
||||
buffer_reset(prop_404);
|
||||
|
||||
webdav_get_props(srv, con, p, &d, req_props, prop_200, prop_404);
|
||||
webdav_get_props(srv, con, hctx, &d, req_props, prop_200, prop_404);
|
||||
|
||||
buffer_append_string_len(b,CONST_STR_LEN("<D:response>\n"));
|
||||
buffer_append_string_len(b,CONST_STR_LEN("<D:href>"));
|
||||
|
@ -1644,7 +1650,7 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
|||
}
|
||||
|
||||
/* does the client have a lock for this connection ? */
|
||||
if (!webdav_has_lock(srv, con, p, con->uri.path)) {
|
||||
if (!webdav_has_lock(srv, con, hctx, con->uri.path)) {
|
||||
con->http_status = 423;
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
|
@ -1670,7 +1676,7 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
|||
|
||||
multi_status_resp = buffer_init();
|
||||
|
||||
if (webdav_delete_dir(srv, con, p, &(con->physical), multi_status_resp)) {
|
||||
if (webdav_delete_dir(srv, con, hctx, &(con->physical), multi_status_resp)) {
|
||||
/* we got an error somewhere in between, build a 207 */
|
||||
response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("text/xml; charset=\"utf-8\""));
|
||||
|
||||
|
@ -1743,7 +1749,7 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
|||
|
||||
/* is a exclusive lock set on the source */
|
||||
/* (check for lock once before potentially reading large input) */
|
||||
if (0 == cq->bytes_in && !webdav_has_lock(srv, con, p, con->uri.path)) {
|
||||
if (0 == cq->bytes_in && !webdav_has_lock(srv, con, hctx, con->uri.path)) {
|
||||
con->http_status = 423;
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
|
@ -1933,7 +1939,7 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
|||
|
||||
/* is a exclusive lock set on the source */
|
||||
if (con->request.http_method == HTTP_METHOD_MOVE) {
|
||||
if (!webdav_has_lock(srv, con, p, con->uri.path)) {
|
||||
if (!webdav_has_lock(srv, con, hctx, con->uri.path)) {
|
||||
con->http_status = 423;
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
|
@ -2118,13 +2124,13 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
|||
}
|
||||
|
||||
/* copy the content of src to dest */
|
||||
if (0 != (r = webdav_copy_dir(srv, con, p, &(con->physical), &(p->physical), overwrite))) {
|
||||
if (0 != (r = webdav_copy_dir(srv, con, hctx, &(con->physical), &(p->physical), overwrite))) {
|
||||
con->http_status = r;
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
if (con->request.http_method == HTTP_METHOD_MOVE) {
|
||||
b = buffer_init();
|
||||
webdav_delete_dir(srv, con, p, &(con->physical), b); /* content */
|
||||
webdav_delete_dir(srv, con, hctx, &(con->physical), b); /* content */
|
||||
buffer_free(b);
|
||||
|
||||
rmdir(con->physical.path->ptr);
|
||||
|
@ -2137,7 +2143,7 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
|||
int destdir = 0;
|
||||
|
||||
/* does the client have a lock for this connection ? */
|
||||
if (!webdav_has_lock(srv, con, p, p->uri.path)) {
|
||||
if (!webdav_has_lock(srv, con, hctx, p->uri.path)) {
|
||||
con->http_status = 423;
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
|
@ -2205,7 +2211,7 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
|||
/* rename failed, fall back to COPY + DELETE */
|
||||
}
|
||||
|
||||
if (0 != (r = webdav_copy_file(srv, con, p, &(con->physical), &(p->physical), overwrite))) {
|
||||
if (0 != (r = webdav_copy_file(srv, con, hctx, &(con->physical), &(p->physical), overwrite))) {
|
||||
con->http_status = r;
|
||||
|
||||
return HANDLER_FINISHED;
|
||||
|
@ -2213,7 +2219,7 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
|||
|
||||
if (con->request.http_method == HTTP_METHOD_MOVE) {
|
||||
b = buffer_init();
|
||||
webdav_delete_file(srv, con, p, &(con->physical), b);
|
||||
webdav_delete_file(srv, con, hctx, &(con->physical), b);
|
||||
buffer_free(b);
|
||||
}
|
||||
}
|
||||
|
@ -2226,7 +2232,7 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
|||
return HANDLER_FINISHED;
|
||||
}
|
||||
|
||||
if (!webdav_has_lock(srv, con, p, con->uri.path)) {
|
||||
if (!webdav_has_lock(srv, con, hctx, con->uri.path)) {
|
||||
con->http_status = 423;
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
|
@ -2254,7 +2260,7 @@ SUBREQUEST_FUNC(mod_webdav_subrequest_handler_huge) {
|
|||
if (r != HANDLER_GO_ON) return r;
|
||||
}
|
||||
|
||||
if (1 == webdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
|
||||
if (1 == webdav_parse_chunkqueue(srv, con, hctx, con->request_content_queue, &xml)) {
|
||||
xmlNode *rootnode = xmlDocGetRootElement(xml);
|
||||
|
||||
if (0 == xmlStrcmp(rootnode->name, BAD_CAST "propertyupdate")) {
|
||||
|
@ -2451,7 +2457,7 @@ propmatch_cleanup:
|
|||
}
|
||||
}
|
||||
|
||||
if (1 == webdav_parse_chunkqueue(srv, con, p, con->request_content_queue, &xml)) {
|
||||
if (1 == webdav_parse_chunkqueue(srv, con, hctx, con->request_content_queue, &xml)) {
|
||||
xmlNode *rootnode = xmlDocGetRootElement(xml);
|
||||
|
||||
force_assert(rootnode);
|
||||
|
@ -2735,10 +2741,14 @@ PHYSICALPATH_FUNC(mod_webdav_physical_handler) {
|
|||
case HTTP_METHOD_MKCOL:
|
||||
case HTTP_METHOD_DELETE:
|
||||
case HTTP_METHOD_LOCK:
|
||||
case HTTP_METHOD_UNLOCK:
|
||||
case HTTP_METHOD_UNLOCK: {
|
||||
handler_ctx *hctx = calloc(1, sizeof(*hctx));
|
||||
memcpy(&hctx->conf, &p->conf, sizeof(plugin_config));
|
||||
con->plugin_ctx[p->id] = hctx;
|
||||
con->conf.stream_request_body = 0;
|
||||
con->mode = p->id;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2746,6 +2756,15 @@ PHYSICALPATH_FUNC(mod_webdav_physical_handler) {
|
|||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
static handler_t mod_webdav_connection_reset(server *srv, connection *con, void *p_d) {
|
||||
plugin_data *p = p_d;
|
||||
handler_ctx *hctx = con->plugin_ctx[p->id];
|
||||
if (hctx) free(hctx);
|
||||
|
||||
UNUSED(srv);
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
||||
/* this function is called at dlopen() time and inits the callbacks */
|
||||
|
||||
|
@ -2758,6 +2777,7 @@ int mod_webdav_plugin_init(plugin *p) {
|
|||
p->handle_uri_clean = mod_webdav_uri_handler;
|
||||
p->handle_physical = mod_webdav_physical_handler;
|
||||
p->handle_subrequest = mod_webdav_subrequest_handler;
|
||||
p->connection_reset = mod_webdav_connection_reset;
|
||||
p->set_defaults = mod_webdav_set_defaults;
|
||||
p->cleanup = mod_webdav_free;
|
||||
|
||||
|
|
Loading…
Reference in New Issue