ASF Bugzilla – Attachment 22295 Details for
Bug 45449
[PATCH] Add support to WebDav to MOVE/COPY to remote servers
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Support for remote MOVE on resources (not collections)
mod_dav_remote-copymove-0.3.diff (text/plain), 21.31 KB, created by
Rafał Malinowski
on 2008-07-21 21:02:29 UTC
(
hide
)
Description:
Support for remote MOVE on resources (not collections)
Filename:
MIME Type:
Creator:
Rafał Malinowski
Created:
2008-07-21 21:02:29 UTC
Size:
21.31 KB
patch
obsolete
>diff -urbB httpd-2.2.9-orig/modules/dav/fs/repos.c httpd-2.2.9/modules/dav/fs/repos.c >--- httpd-2.2.9-orig/modules/dav/fs/repos.c 2008-01-02 10:41:46.000000000 +0100 >+++ httpd-2.2.9/modules/dav/fs/repos.c 2008-07-22 05:24:07.000000000 +0200 >@@ -37,7 +37,7 @@ > > > /* to assist in debugging mod_dav's GET handling */ >-#define DEBUG_GET_HANDLER 0 >+#define DEBUG_GET_HANDLER 1 > > #define DAV_FS_COPY_BLOCKSIZE 16384 /* copy 16k at a time */ > >diff -urbB httpd-2.2.9-orig/modules/dav/main/mod_dav.c httpd-2.2.9/modules/dav/main/mod_dav.c >--- httpd-2.2.9-orig/modules/dav/main/mod_dav.c 2008-05-27 17:57:23.000000000 +0200 >+++ httpd-2.2.9/modules/dav/main/mod_dav.c 2008-07-22 05:32:44.000000000 +0200 >@@ -55,6 +55,7 @@ > #include "http_main.h" > #include "http_protocol.h" > #include "http_request.h" >+#include "util_ebcdic.h" > #include "util_script.h" > > #include "mod_dav.h" >@@ -2550,6 +2551,547 @@ > return dav_created(r, NULL, "Collection", 0); > } > >+DAV_DECLARE(dav_error *) dav_remote_copymove_create_socket(apr_pool_t *p, apr_sockaddr_t *addr, apr_socket_t **newsock) >+{ >+ apr_status_t rv; >+ >+ while (addr) { >+ if ((rv = apr_socket_create(newsock, addr->family, >+ SOCK_STREAM, 0, p)) != APR_SUCCESS) { >+ /* >+ * this could be an IPv6 address from the DNS but the >+ * local machine won't give us an IPv6 socket; hopefully the >+ * DNS returned an additional address to try >+ */ >+ addr = addr->next; >+ continue; >+ } >+ >+ rv = apr_socket_connect(*newsock, addr); >+ >+ /* if an error occurred, loop round and try again */ >+ if (rv != APR_SUCCESS) { >+ apr_socket_close(*newsock); >+ addr = addr->next; >+ continue; >+ } >+ >+ return 0; >+ } >+ >+ // TODO: good error code? >+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, "Socket creating failed"); >+} >+ >+DAV_DECLARE(dav_error *) dav_remote_create_connection(apr_pool_t *p, apr_uri_t *uri, server_rec *s, conn_rec **conn) >+{ >+ apr_status_t rv; >+ apr_sockaddr_t *src_addr; >+ apr_socket_t *socket; >+ dav_error *err; >+ >+ rv = apr_sockaddr_info_get(&src_addr, uri->hostname, APR_UNSPEC, uri->port, 0, p); >+ if (APR_SUCCESS != rv) { >+ return dav_new_error(p, HTTP_BAD_REQUEST, 0, apr_pstrcat(p, "DNS lookup failure for: ", uri->hostname, NULL)); >+ } >+ >+ if (NULL != (err = dav_remote_copymove_create_socket(p, src_addr, &socket))) { >+ return err; >+ } >+ >+ *conn = (conn_rec *)ap_run_create_connection(p, s, socket, 0, NULL, apr_bucket_alloc_create(p)); >+ >+ if (!*conn) { >+ // will it have memory to create error message? i guess not, let the caller check! >+ return 0; >+ } >+ >+ /* set up the connection filters */ >+ rv = ap_run_pre_connection(*conn, socket); >+ if (rv != OK && rv != DONE) { >+ (*conn)->aborted = 1; >+ return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, "pre_connection setup failed"); >+ } >+ >+ return 0; >+} >+ >+DAV_DECLARE(dav_error *) dav_remote_close_connection(request_rec *r) >+{ >+ // TODO: find a better way to do it >+ r->connection = 0; >+} >+ >+DAV_DECLARE(request_rec *) dav_remote_make_fake_request(request_rec *r) >+{ >+ request_rec *rp = apr_pcalloc(r->pool, sizeof(*r)); >+ >+ rp->pool = r->pool; >+ rp->status = HTTP_OK; >+ >+ rp->headers_in = apr_table_make(r->pool, 12); >+ rp->subprocess_env = apr_table_make(r->pool, 12); >+ rp->headers_out = apr_table_make(r->pool, 12); >+ rp->err_headers_out = apr_table_make(r->pool, 5); >+ rp->notes = apr_table_make(r->pool, 5); >+ >+ rp->server = r->server; >+ rp->proxyreq = r->proxyreq; >+ rp->request_time = r->request_time; >+ >+ rp->connection = 0; >+ >+ rp->request_config = ap_create_request_config(r->pool); >+ rp->per_dir_config = r->per_dir_config; // hope it will not crash >+} >+ >+DAV_DECLARE(dav_error *) dav_remote_set_connection(request_rec *r, apr_uri_t *resource_uri) >+{ >+ dav_error *err; >+ conn_rec *conn; >+ >+ if (r->connection) { >+ return 0; >+ } >+ if (NULL != (err = dav_remote_create_connection(r->pool, resource_uri, r->server, &conn))) { >+ return err; >+ } >+ >+ r->connection = conn; >+ r->output_filters = conn->output_filters; >+ r->input_filters = conn->input_filters; >+ r->proto_output_filters = conn->output_filters; >+ r->proto_input_filters = conn->input_filters; >+ >+ return 0; >+} >+ >+DAV_DECLARE(dav_error *) dav_remote_send_resource_content(request_rec *r, dav_resource *resource) >+{ >+ dav_error *err; >+ apr_bucket_brigade *request_brigade; >+ apr_bucket *e; >+ apr_status_t rv; >+ >+ /* okay... time to deliver the content */ >+ if ((err = (*resource->hooks->deliver)(resource, >+ r->output_filters)) != NULL) { >+ return dav_push_error(r->pool, err->status, 0, >+ "Unable to deliver content.", >+ err); >+ } >+ >+ request_brigade = apr_brigade_create(r->pool, r->connection->bucket_alloc); >+ >+ e = apr_bucket_flush_create(r->connection->bucket_alloc); >+ APR_BRIGADE_INSERT_TAIL(request_brigade, e); >+ >+ rv = ap_pass_brigade(r->output_filters, request_brigade); >+ >+ return NULL; >+} >+ >+struct dav_remote_send_headers_wrapper { >+ apr_bucket_alloc_t *bucket_alloc; >+ apr_bucket_brigade *request_brigade; >+ apr_pool_t *p; >+}; >+ >+int dav_remote_send_headers(void *rec, const char *key, const char *value) >+{ >+ struct dav_remote_send_headers_wrapper *wrapper = (struct dav_remote_send_headers_wrapper *)rec; >+ >+ apr_bucket_brigade *request_brigade = wrapper->request_brigade; >+ apr_bucket *e; >+ char *buf; >+ >+ buf = apr_pstrcat(wrapper->p, key, ": ", value, CRLF, NULL); >+ e = apr_bucket_pool_create(buf, strlen(buf), wrapper->p, wrapper->bucket_alloc); >+ ap_xlate_proto_to_ascii(buf, strlen(buf)); >+ APR_BRIGADE_INSERT_TAIL(request_brigade, e); >+} >+ >+DAV_DECLARE(dav_error *) dav_remote_read_status_line(request_rec *r) >+{ >+ apr_bucket_brigade *response_brigade; >+ >+ char buff[HUGE_STRING_LEN]; >+ char *buff_p = buff; >+ char keepchar; >+ apr_size_t len; >+ >+ response_brigade = apr_brigade_create(r->pool, r->connection->bucket_alloc); >+ ap_rgetline(&buff_p, sizeof(buff), &len, r, 0, response_brigade); >+ >+ if (!apr_date_checkmask(buff, "HTTP/#.# ###*")) { >+ return dav_new_error(r->pool, HTTP_BAD_GATEWAY, 0, "Invalid response status line"); >+ } >+ >+ int major, minor; >+ >+ if (2 != sscanf(buff, "HTTP/%u.%u", &major, &minor)) { >+ major = 1; >+ minor = 1; >+ } >+ else if ((buff[5] != '1') || (len >= sizeof(buff) - 1)) { >+ return dav_new_error(r->pool, HTTP_BAD_GATEWAY, 0, "Invalid response status line"); >+ } >+ >+ keepchar = buff[12]; >+ buff[12] = '\0'; >+ r->status = atoi(&buff[9]); >+ >+ if (keepchar != '\0') { >+ buff[12] = keepchar; >+ } else { >+ /* 2616 requires the space in Status-Line; the origin >+ * server may have sent one but ap_rgetline_core will >+ * have stripped it. */ >+ buff[12] = ' '; >+ buff[13] = '\0'; >+ } >+ r->status_line = apr_pstrdup(r->pool, &buff[9]); >+ >+ return 0; >+} >+ >+DAV_DECLARE(dav_error *) dav_remote_read_response_headers(request_rec *r) >+{ >+ dav_error *err; >+ apr_bucket_brigade *response_brigade; >+ apr_size_t len; >+ apr_status_t rv; >+ char buff[HUGE_STRING_LEN]; >+ char *buff_p = buff; >+ char *value, *end; >+ >+ apr_table_clear(r->headers_in); >+ >+ response_brigade = apr_brigade_create(r->pool, r->connection->bucket_alloc); >+ if (APR_SUCCESS != (rv = ap_rgetline(&buff_p, sizeof(buff), &len, r, 0, response_brigade))) { >+ return dav_new_error(r->pool, HTTP_BAD_GATEWAY, 0, "Error reading response header"); >+ } >+ >+ while (0 < len) { >+ if (!(value = strchr(buff, ':'))) { >+ if (APR_SUCCESS != (rv = ap_rgetline(&buff_p, sizeof(buff), &len, r, 0, response_brigade))) { >+ return dav_new_error(r->pool, HTTP_BAD_GATEWAY, 0, "Error reading response header"); >+ } >+ } >+ >+ *value = '\0'; >+ ++value; >+ /* XXX: RFC2068 defines only SP and HT as whitespace, this test is >+ * wrong... and so are many others probably. >+ */ >+ while (apr_isspace(*value)) >+ ++value; /* Skip to start of value */ >+ >+ /* should strip trailing whitespace as well */ >+ for (end = &value[strlen(value)-1]; end > value && apr_isspace(*end); --end) >+ *end = '\0'; >+ >+ apr_table_add(r->headers_in, buff, value); >+ >+ if (APR_SUCCESS != (rv = ap_rgetline(&buff_p, sizeof(buff), &len, r, 0, response_brigade))) { >+ return dav_new_error(r->pool, HTTP_BAD_GATEWAY, 0, "Error reading response header"); >+ } >+ } >+ >+ return 0; >+} >+ >+typedef dav_error * (* write_request_content_callback) (request_rec *, void *data); >+typedef dav_error * (* read_reponse_content_callback) (request_rec *, void *data); >+ >+DAV_DECLARE(dav_error *) dav_remote_skip_response_content(request_rec *r, void *unused) >+{ >+ apr_size_t content_length; >+ apr_size_t to_read; >+ apr_bucket_brigade *response_brigade; >+ apr_bucket *e; >+ int seen_eos; >+ const char *content_length_str; >+ apr_bucket_alloc_t *bucket_alloc = r->connection->bucket_alloc; >+ char buff[HUGE_STRING_LEN]; >+ char *buff_p = buff; >+ >+ if (NULL == apr_table_get(r->headers_in, "Keep-Alive")) { // we can close the connection now >+ dav_remote_close_connection(r); >+ return 0; >+ } >+ >+ content_length_str = apr_table_get(r->headers_in, "Content-Length"); >+ if (!content_length_str) { >+ return 0; // no content >+ } >+ >+ content_length = atoi(content_length_str); >+ if (!content_length) { >+ return 0; // no content >+ } >+ >+ if (content_length < 0) { >+ dav_remote_close_connection(r); >+ return dav_new_error(r->pool, HTTP_BAD_GATEWAY, 0, "Invalid Content-Length of response"); >+ } >+ >+ while (0 < content_length) { >+ response_brigade = apr_brigade_create(r->pool, bucket_alloc); >+ >+ do { >+ apr_status_t rc; >+ >+ rc = ap_get_brigade(r->input_filters, response_brigade, AP_MODE_READBYTES, >+ APR_BLOCK_READ, DAV_READ_BLOCKSIZE); >+ >+ if (rc != APR_SUCCESS) { >+ return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, >+ "Could not get next bucket brigade"); >+ } >+ >+ for (e = APR_BRIGADE_FIRST(response_brigade); >+ e != APR_BRIGADE_SENTINEL(response_brigade); >+ e = APR_BUCKET_NEXT(e)) >+ { >+ const char *data; >+ apr_size_t len; >+ >+ if (APR_BUCKET_IS_EOS(e)) { >+ seen_eos = 1; >+ break; >+ } >+ >+ if (APR_BUCKET_IS_METADATA(e)) { >+ continue; >+ } >+ >+ rc = apr_bucket_read(e, &data, &len, APR_BLOCK_READ); >+ content_length -= len; >+ >+ if (rc != APR_SUCCESS) { >+ return dav_new_error(r->pool, HTTP_BAD_REQUEST, 0, >+ "An error occurred while reading " >+ "the request body."); >+ } >+ } >+ >+ apr_brigade_cleanup(response_brigade); >+ } while (!seen_eos); >+ >+ >+ >+ } >+ >+ return 0; >+} >+ >+DAV_DECLARE(dav_error *) dav_remote_method_request(request_rec *r, const char *method, apr_uri_t *resource_uri, >+ const char *resource_path, dav_resource *resource, >+ write_request_content_callback write_request_content, void *write_request_content_data, >+ read_reponse_content_callback read_response_content, void *read_response_content_data) >+{ >+ apr_status_t rv; >+ dav_error *err; >+ apr_bucket_alloc_t *bucket_alloc = r->connection->bucket_alloc; >+ apr_bucket_brigade *request_brigade; >+ apr_bucket *e; >+ char *buf; >+ >+ // as I see nobody in httpd check for NULL results of malloc/apr_palloc, so why I should? >+ request_brigade = apr_brigade_create(r->pool, bucket_alloc); >+ >+ buf = apr_pstrcat(r->pool, method, " ", resource_uri->path, " HTTP/1.1", CRLF, NULL); >+ e = apr_bucket_pool_create(buf, strlen(buf), r->pool, bucket_alloc); >+ ap_xlate_proto_to_ascii(buf, strlen(buf)); >+ APR_BRIGADE_INSERT_TAIL(request_brigade, e); >+ >+ struct dav_remote_send_headers_wrapper wrapper; >+ wrapper.bucket_alloc = bucket_alloc; >+ wrapper.request_brigade = request_brigade; >+ wrapper.p = r->pool; >+ >+ apr_table_do(dav_remote_send_headers, &wrapper, r->headers_out, 0); >+ >+ buf = apr_pstrcat(r->pool, CRLF, NULL); >+ e = apr_bucket_pool_create(buf, strlen(buf), r->pool, bucket_alloc); >+ ap_xlate_proto_to_ascii(buf, strlen(buf)); >+ APR_BRIGADE_INSERT_TAIL(request_brigade, e); >+ >+ e = apr_bucket_flush_create(bucket_alloc); >+ APR_BRIGADE_INSERT_TAIL(request_brigade, e); >+ >+ rv = ap_pass_brigade(r->output_filters, request_brigade); >+ >+ if (NULL != write_request_content) { >+ write_request_content(r, write_request_content_data); >+ } >+ >+ if (rv != APR_SUCCESS) { >+ return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, "Sending request failed"); >+ } >+ >+ if (NULL != (err = dav_remote_read_status_line(r))) { >+ return dav_push_error(r->pool, err->status, 0, "read_status in dav_remote_method_request failed.", err); >+ } >+ >+ if (NULL != (err = dav_remote_read_response_headers(r))) { >+ return dav_push_error(r->pool, err->status, 0, "read_response_headers in dav_remote_method_request failed.", err); >+ } >+ >+ if (NULL == read_response_content) { >+ read_response_content = dav_remote_skip_response_content; >+ } >+ >+ if (NULL != (err = read_response_content(r, read_response_content_data))) { >+ return dav_push_error(r->pool, err->status, 0, "read_reponse_content_callback in dav_remote_method_request failed.", err); >+ } >+ >+ // MOVED PERMANENTLY - check with '/' at the end >+ if ((r->status == HTTP_MOVED_PERMANENTLY) && (resource_uri->path[strlen(resource_uri->path) - 1] != '/')) { >+ resource_path = apr_pstrcat(r->pool, resource_path, "/", NULL); >+ if (strcmp(resource_path, apr_table_get(r->headers_in, "Location")) != 0) { >+ return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, "No idea what to do..."); >+ } >+ >+ resource_uri->path = apr_pstrcat(r->pool, resource_uri->path, "/", NULL); >+ >+ return dav_remote_method_request(r, method, resource_uri, resource_path, resource, NULL, NULL, NULL, NULL); >+ } >+ >+ return NULL; >+} >+ >+DAV_DECLARE(dav_error *) dav_remote_resource_exists(request_rec *r, apr_uri_t *resource_uri, const char *resource_path, dav_resource *resource, int *exists) >+{ >+ dav_error *err; >+ conn_rec *conn; >+ >+ *exists = 0; >+ >+ if (NULL != (err = dav_remote_set_connection(r, resource_uri))) { >+ return dav_push_error(r->pool, err->status, 0, "Unable to create connection in dav_remote_resource_exists.", err); >+ } >+ >+ apr_table_clear(r->headers_out); >+ apr_table_add(r->headers_out, "Host", resource_uri->hostname); >+ apr_table_add(r->headers_out, "Content-Length", "0"); >+ apr_table_add(r->headers_out, "Depth", "0"); >+ apr_table_add(r->headers_out, "Connection", "Keep-Alive"); >+ >+ if (NULL != (err = dav_remote_method_request(r, "HEAD", resource_uri, resource_path, resource, NULL, NULL, NULL, NULL))) { >+ return dav_push_error(r->pool, err->status, 0, "HEAD in dav_remote_resource_exists failed.", err); >+ } >+ >+ *exists = r->status != 404; >+ return 0; >+} >+ >+DAV_DECLARE(dav_error *) dav_remote_resource_delete(request_rec *r, apr_uri_t *resource_uri, const char *resource_path, dav_resource *resource, int *deleted) >+{ >+ dav_error *err; >+ conn_rec *conn; >+ >+ if (NULL != (err = dav_remote_set_connection(r, resource_uri))) { >+ return dav_push_error(r->pool, err->status, 0, "Unable to create connection in dav_remote_resource_delete.", err); >+ } >+ >+ apr_table_clear(r->headers_out); >+ apr_table_add(r->headers_out, "Host", resource_uri->hostname); >+ apr_table_add(r->headers_out, "Content-Length", "0"); >+ apr_table_add(r->headers_out, "Connection", "Keep-Alive"); >+ >+ if (NULL != (err = dav_remote_method_request(r, "DELETE", resource_uri, resource_path, resource, NULL, NULL, NULL, NULL))) { >+ return dav_push_error(r->pool, err->status, 0, "DELETE in dav_remote_resource_delete failed.", err); >+ } >+ >+ *deleted = r->status == 200 || r->status == 202 || r->status == 204 || r->status == 404; >+ >+ return 0; >+} >+ >+DAV_DECLARE(dav_error *) dav_remote_resource_put(request_rec *r, apr_uri_t *resource_uri, const char *resource_path, dav_resource *resource) >+{ >+ dav_error *err; >+ conn_rec *conn; >+ >+ if (NULL != (err = dav_remote_set_connection(r, resource_uri))) { >+ return dav_push_error(r->pool, err->status, 0, "Unable to create connection in dav_remote_resource_delete.", err); >+ } >+ >+ apr_table_clear(r->headers_out); >+ apr_table_add(r->headers_out, "Host", resource_uri->hostname); >+ apr_table_add(r->headers_out, "Connection", "Keep-Alive"); >+ >+ if ((err = (*resource->hooks->set_headers)(r, resource)) != NULL) { >+ return dav_push_error(r->pool, err->status, 0, >+ "Unable to set up HTTP headers.", >+ err); >+ } >+ >+ if (NULL != (err = dav_remote_method_request(r, "PUT", resource_uri, resource_path, resource, >+ dav_remote_send_resource_content, resource, >+ NULL, NULL))) { >+ return dav_push_error(r->pool, err->status, 0, "DELETE in dav_remote_resource_delete failed.", err); >+ } >+ >+ if (r->status != 201 && r->status != 204) { >+ return dav_new_error(r->pool, r->status, 0, "Remote server does not accept resource"); >+ } >+ >+ return 0; >+} >+ >+static int dav_remote_copymove(request_rec *r, dav_resource *resource, const char *dest, int is_move, int overwrite) >+{ >+ dav_error *err; >+ apr_uri_t dest_uri; >+ conn_rec *conn; >+ request_rec *rp; >+ int exists; >+ int deleted; >+ >+ if (APR_SUCCESS != apr_uri_parse(r->pool, dest, &dest_uri)) { >+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, >+ "Destination URI cannot be parsed.", NULL); >+ return HTTP_BAD_REQUEST; >+ } >+ >+ if (!dest_uri.port) { >+ dest_uri.port = apr_uri_port_of_scheme(dest_uri.scheme); >+ } >+ >+ // 1. create request >+ rp = dav_remote_make_fake_request(r); >+ >+ >+ if (!overwrite) { >+ // 2. check if exists >+ if (NULL != (err = dav_remote_resource_exists(rp, &dest_uri, dest, resource, &exists))) { >+ return dav_handle_err(r, err, NULL); >+ } >+ >+ if (exists) >+ return HTTP_PRECONDITION_FAILED; >+ } >+ else { >+ // 2. delete old resource >+ if (NULL != (err = dav_remote_resource_delete(rp, &dest_uri, dest, resource, &deleted))) { >+ return dav_handle_err(r, err, NULL); >+ } >+ >+ if (!deleted) >+ return HTTP_FORBIDDEN; >+ } >+ >+ // 3. send content >+ if ((err = dav_remote_resource_put(rp, &dest_uri, dest, resource)) != NULL) { >+ return dav_handle_err(r, err, NULL); >+ } >+ >+ return HTTP_NO_CONTENT; >+} >+ > /* handle the COPY and MOVE methods */ > static int dav_method_copymove(request_rec *r, int is_move) > { >@@ -2609,6 +3151,13 @@ > return HTTP_BAD_REQUEST; > } > >+ /* get and parse the overwrite header value */ >+ if ((overwrite = dav_get_overwrite(r)) < 0) { >+ /* dav_get_overwrite() supplies additional information for the >+ * default message. */ >+ return HTTP_BAD_REQUEST; >+ } >+ > lookup = dav_lookup_uri(dest, r, 1 /* must_be_absolute */); > if (lookup.rnew == NULL) { > if (lookup.err.status == HTTP_BAD_REQUEST) { >@@ -2618,6 +3167,12 @@ > return HTTP_BAD_REQUEST; > } > >+ if (!is_move && lookup.err.status == HTTP_BAD_GATEWAY) { >+ err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */, >+ &resource); >+ return dav_remote_copymove(r, resource, dest, is_move, overwrite); >+ } >+ > /* ### this assumes that dav_lookup_uri() only generates a status > * ### that Apache can provide a status line for!! */ > >@@ -2650,20 +3206,11 @@ > return dav_handle_err(r, err, NULL); > > /* are the two resources handled by the same repository? */ >- if (resource->hooks != resnew->hooks) { >+ if (!is_move && resource->hooks != resnew->hooks) { >+ err = dav_get_resource(r, 1 /* label_allowed */, 0 /* use_checked_in */, >+ &resource); > /* ### this message exposes some backend config, but screw it... */ >- return dav_error_response(r, HTTP_BAD_GATEWAY, >- "Destination URI is handled by a " >- "different repository than the source URI. " >- "MOVE or COPY between repositories is " >- "not possible."); >- } >- >- /* get and parse the overwrite header value */ >- if ((overwrite = dav_get_overwrite(r)) < 0) { >- /* dav_get_overwrite() supplies additional information for the >- * default message. */ >- return HTTP_BAD_REQUEST; >+ return dav_remote_copymove(r, resource, dest, is_move, overwrite); > } > > /* quick failure test: if dest exists and overwrite is false. */ >diff -urbB httpd-2.2.9-orig/modules/dav/main/util.c httpd-2.2.9/modules/dav/main/util.c >--- httpd-2.2.9-orig/modules/dav/main/util.c 2008-01-05 10:45:07.000000000 +0100 >+++ httpd-2.2.9/modules/dav/main/util.c 2008-07-17 19:19:19.000000000 +0200 >@@ -216,10 +216,9 @@ > request. the port must match our port. > */ > port = r->connection->local_addr->port; >+ > if (strcasecmp(comp.scheme, scheme) != 0 >-#ifdef APACHE_PORT_HANDLING_IS_BUSTED > || comp.port != port >-#endif > ) { > result.err.status = HTTP_BAD_GATEWAY; > result.err.desc = apr_psprintf(r->pool,
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 45449
:
22295
|
22304
|
22320
|
22321
|
22345