Author: cmpilato
Date: Mon May 17 18:09:28 2010
New Revision: 945280
URL: http://svn.apache.org/viewvc?rev=945280&view=rev
Log:
Expand the HTTPv2 POST handler for general purpose use, similar to the
read-only REPORT functionality offered elsewhere.
* build.conf
(mod_dav_svn): Add posts/*.c to sources.
* subversion/mod_dav_svn/posts,
* subversion/mod_dav_svn/posts/create-transaction.c,
* subversion/mod_dav_svn/dav_svn.h
(dav_svn__create_transaction_post): New POST handler function. And
file to hold it. And folder to hold *that*.
* subversion/mod_dav_svn/repos.c
(dav_svn__method_post): Expand this function for use as a more
general-purpose dispatcher of various custom HTTPv2 POST requests.
* subversion/libsvn_ra_serf/commit.c
Generate more fully formed create-transaction POST requests now.
Added:
subversion/trunk/subversion/mod_dav_svn/posts/ (with props)
subversion/trunk/subversion/mod_dav_svn/posts/create-transaction.c (with
props)
Modified:
subversion/trunk/build.conf
subversion/trunk/subversion/libsvn_ra_serf/commit.c
subversion/trunk/subversion/mod_dav_svn/dav_svn.h
subversion/trunk/subversion/mod_dav_svn/repos.c
Modified: subversion/trunk/build.conf
URL:
http://svn.apache.org/viewvc/subversion/trunk/build.conf?rev=945280&r1=945279&r2=945280&view=diff
==============================================================================
--- subversion/trunk/build.conf (original)
+++ subversion/trunk/build.conf Mon May 17 18:09:28 2010
@@ -337,7 +337,7 @@ msvc-export = svn_wc.h private\svn_wc_pr
description = Subversion plug-in for the Apache DAV module
type = apache-mod
path = subversion/mod_dav_svn
-sources = *.c reports/*.c
+sources = *.c reports/*.c posts/*.c
libs = libsvn_repos libsvn_fs libsvn_delta libsvn_subr
nonlibs = apr aprutil
install = apache-mod
Modified: subversion/trunk/subversion/libsvn_ra_serf/commit.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/commit.c?rev=945280&r1=945279&r2=945280&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/commit.c Mon May 17 18:09:28 2010
@@ -1046,6 +1046,24 @@ post_headers_iterator_callback(void *bat
}
+static serf_bucket_t *
+create_post_body(void *baton,
+ serf_bucket_alloc_t *alloc,
+ apr_pool_t *pool)
+{
+ serf_bucket_t *body_bkt;
+
+ body_bkt = serf_bucket_aggregate_create(alloc);
+
+ svn_ra_serf__add_xml_header_buckets(body_bkt, alloc);
+ svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "S:create-transaction",
+ "xmlns:S", SVN_XML_NAMESPACE, NULL);
+ svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "S:create-transaction");
+
+ return body_bkt;
+}
+
+
/* A custom serf_response_handler_t which is mostly a wrapper around
svn_ra_serf__handle_status_only -- it just notices POST response
headers, too.
@@ -1106,6 +1124,10 @@ open_root(void *edit_baton,
handler->response_handler = post_response_handler;
handler->response_baton = prc;
+ handler->body_delegate = create_post_body;
+ handler->body_delegate_baton = post_ctx;
+ handler->body_type = "text/xml";
+
svn_ra_serf__request_create(handler);
SVN_ERR(svn_ra_serf__context_run_wait(&post_ctx->done, ctx->session,
Modified: subversion/trunk/subversion/mod_dav_svn/dav_svn.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/dav_svn.h?rev=945280&r1=945279&r2=945280&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/trunk/subversion/mod_dav_svn/dav_svn.h Mon May 17 18:09:28 2010
@@ -594,7 +594,7 @@ static const dav_report_elem dav_svn__re
};
-/* The various report handlers, defined in reports/, and used by version.c. */
+/* The various REPORT handlers, defined in reports/, and used by version.c. */
dav_error *
dav_svn__update_report(const dav_resource *resource,
const apr_xml_doc *doc,
@@ -637,6 +637,14 @@ dav_svn__get_deleted_rev_report(const da
const apr_xml_doc *doc,
ap_filter_t *output);
+/* The various POST handlers, defined in posts/, and used by
+ dav_svn__method_post(). */
+int
+dav_svn__create_transaction_post(const dav_resource *resource,
+ const apr_xml_doc *doc,
+ ap_filter_t *output);
+
+
/*** authz.c ***/
/* A baton needed by dav_svn__authz_read_func(). */
Propchange: subversion/trunk/subversion/mod_dav_svn/posts/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Mon May 17 18:09:28 2010
@@ -0,0 +1 @@
+.libs
Added: subversion/trunk/subversion/mod_dav_svn/posts/create-transaction.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/posts/create-transaction.c?rev=945280&view=auto
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/posts/create-transaction.c (added)
+++ subversion/trunk/subversion/mod_dav_svn/posts/create-transaction.c Mon May
17 18:09:28 2010
@@ -0,0 +1,71 @@
+/*
+ * create-transaction.c: mod_dav_svn POST handler for creating a new
+ * commit transaction
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+#include <apr_tables.h>
+
+#include <httpd.h>
+#include <mod_dav.h>
+
+#include "svn_dav.h"
+#include "../dav_svn.h"
+
+
+/* Respond to a S:dated-rev-report request. */
+int
+dav_svn__create_transaction_post(const dav_resource *resource,
+ const apr_xml_doc *doc,
+ ap_filter_t *output)
+{
+ request_rec *r = resource->info->r;
+ apr_bucket_brigade *bb;
+ apr_status_t apr_err;
+ dav_error *derr = NULL;
+ const char *txn_name;
+
+ /* Create a Subversion repository transaction based on HEAD, and
+ return the new transaction's name in a custom "201 Created"
+ response header. */
+ derr = dav_svn__create_txn(resource->info->repos, &txn_name, resource->pool);
+ if (derr)
+ return dav_svn__error_response_tag(r, derr);
+
+ /* We'll set this header only because some early 1.7-dev client
+ expect it. */
+ apr_table_set(r->headers_out, SVN_DAV_TXN_NAME_HEADER, txn_name);
+ r->status = HTTP_CREATED;
+
+ bb = apr_brigade_create(resource->pool, output->c->bucket_alloc);
+ apr_err = ap_fprintf(output, bb,
+ DAV_XML_HEADER DEBUG_CR
+ "<S:transaction xmlns:S=\"" SVN_XML_NAMESPACE "\""
+ ">%ld</S:transaction",
+ apr_xml_quote_string(resource->pool, txn_name, 0));
+ if (apr_err)
+ derr = dav_svn__convert_err(svn_error_create(apr_err, 0, NULL),
+ HTTP_INTERNAL_SERVER_ERROR,
+ "Error writing POST response.",
+ resource->pool);
+
+ return dav_svn__final_flush_or_error(r, bb, output, derr, resource->pool);
+}
Propchange: subversion/trunk/subversion/mod_dav_svn/posts/create-transaction.c
------------------------------------------------------------------------------
svn:mime-type = text/x-csrc
Modified: subversion/trunk/subversion/mod_dav_svn/repos.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/repos.c?rev=945280&r1=945279&r2=945280&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/repos.c (original)
+++ subversion/trunk/subversion/mod_dav_svn/repos.c Mon May 17 18:09:28 2010
@@ -4270,21 +4270,6 @@ dav_svn__create_version_resource(dav_res
many different kinds of operations as specified by the body of the
POST request itself.
- ### TODO: Define what the format of those POST bodies might be. If
- ### XML, we have access to Apache's streamy XML parsing code, but
- ### ... it's XML. Meh. If skels, we get skels! But we need to
- ### write our own streamy skel parsing routine around a brigade
- ### read loop. Ewww...
- ###
- ### Today we only support transaction creation requests, but we
- ### could conceivable support the likes of a multi-path lock
- ### and/or unlock request, or some other thing for which stock
- ### WebDAV doesn't work or doesn't work well enough.
- ###
- ### Fortunately, today we don't use the POST body at all, and we'll
- ### be able to get away with not defining the body format in the
- ### future thanks to the following:
-
As a special consideration, an empty POST body is interpreted as a
simple request to create a new commit transaction based on the HEAD
revision. The new transaction name will be returned via a custom
@@ -4295,27 +4280,89 @@ int dav_svn__method_post(request_rec *r)
dav_resource *resource;
dav_error *derr;
const char *txn_name;
+ const char *content_type;
- derr = get_resource(r, dav_svn__get_root_dir(r),
- "ignored", 0, &resource);
- if (derr != NULL)
- return derr->status;
-
- if (resource->info->restype != DAV_SVN_RESTYPE_ME)
- return HTTP_BAD_REQUEST;
+ content_type = apr_table_get(r->headers_in, "Content-Type");
- /* Create a Subversion repository transaction based on HEAD. */
- derr = dav_svn__create_txn(resource->info->repos, &txn_name, resource->pool);
- if (derr)
- return dav_svn__error_response_tag(r, derr);
-
- /* Build a "201 Created" response with header that tells the client
- our new transaction's name. */
- apr_table_set(resource->info->r->headers_out, SVN_DAV_TXN_NAME_HEADER,
- txn_name);
- r->status = HTTP_CREATED;
-
- return OK;
+ derr = get_resource(r, dav_svn__get_root_dir(r), "ignored", 0, &resource);
+ if (derr != NULL)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "Error fetching resource for POST request.");
+ return derr->status;
+ }
+
+ if (resource->info->restype == DAV_SVN_RESTYPE_ME)
+ {
+ /* XML request type. Parse the document, and dispatch to
+ working functions based on the outermost tag. */
+ if (content_type && (strcmp(content_type, "text/xml") == 0))
+ {
+ int result;
+ apr_xml_doc *doc;
+
+ /* Parse the XML. */
+ if ((result = ap_xml_parse_input(r, &doc)) != OK)
+ return result;
+
+ /* Uh-ohs. No XML document! */
+ if (! doc)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "XML POST request body must specify a report.");
+ return HTTP_BAD_REQUEST;
+ }
+
+ /* Okey dokey. We've got an XML document. Let's hand off
+ to helper functions to do the dirty work. */
+ if (doc->root->ns == dav_svn__find_ns(doc->namespaces,
+ SVN_XML_NAMESPACE))
+ {
+ if (strcmp(doc->root->name, "create-transaction") == 0)
+ {
+ return dav_svn__create_transaction_post(resource, doc,
+ r->output_filters);
+ }
+ /*
+ else if (strcmp(doc->root->name, "lock-paths") == 0)
+ {
+ return dav_svn__lock_paths_post(resource, doc,
+ r->output_filters);
+ }
+ else if (strcmp(doc->root->name, "lock-paths") == 0)
+ {
+ return dav_svn__unlock_paths_post(resource, doc,
+ r->output_filters);
+ }
+ */
+ }
+
+ /* Hrm. Nobody handled the request. Must be something we
+ don't understand. */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "Unsupported POST operation type.");
+ return HTTP_NOT_IMPLEMENTED;
+ }
+ else if (content_type)
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "Unsupported POST content-type.");
+ return HTTP_BAD_REQUEST;
+ }
+
+ /* ### Some 1.7-dev clients expect an empty POST request to
+ ### create a new transaction, so we'll support that as a sort
+ ### of default operation for POST against the "me resource". */
+ return dav_svn__create_transaction_post(resource, NULL,
+ r->output_filters);
+ }
+ else
+ {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "Invalid POST target resource.");
+ return HTTP_BAD_REQUEST;
+ }
+ /* ### shouldn't get here ### */
}