You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by gs...@apache.org on 2012/05/08 04:41:14 UTC
svn commit: r1335329 - /subversion/trunk/subversion/libsvn_ra_serf/util.c
Author: gstein
Date: Tue May 8 02:41:13 2012
New Revision: 1335329
URL: http://svn.apache.org/viewvc?rev=1335329&view=rev
Log:
Fix basic 6 and copy 25. The errors from the server were not passed
back to the client properly because I was using the wrong XML
processing callbacks.
* subversion/libsvn_ra_serf/util.c:
(begin_error_parsing): factor out some basic setup for server_error_t
structures.
(svn_ra_serf__handle_discard_body): leave a note about future use of
begin_error_parsing. can't use it now since the caller allocates
the server_error_t.
(svn_ra_serf__expect_empty_body): effectively copy
handle_multistatus_only, but use a different set of xml callbacks.
the *_error callbacks extract human-readable from the server's
response.
(svn_ra_serf__handle_multistatus_only): factor out the
begin_error_parsing function and use it, with the *_207 callbacks
Modified:
subversion/trunk/subversion/libsvn_ra_serf/util.c
Modified: subversion/trunk/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/util.c?rev=1335329&r1=1335328&r2=1335329&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/util.c Tue May 8 02:41:13 2012
@@ -864,6 +864,31 @@ drain_bucket(serf_bucket_t *bucket)
}
+static svn_ra_serf__server_error_t *
+begin_error_parsing(svn_ra_serf__xml_start_element_t start,
+ svn_ra_serf__xml_end_element_t end,
+ svn_ra_serf__xml_cdata_chunk_handler_t cdata,
+ apr_pool_t *result_pool)
+{
+ svn_ra_serf__server_error_t *server_err;
+
+ server_err = apr_pcalloc(result_pool, sizeof(*server_err));
+ server_err->init = TRUE;
+ server_err->error = svn_error_create(APR_SUCCESS, NULL, NULL);
+ server_err->has_xml_response = TRUE;
+ server_err->contains_precondition_error = FALSE;
+ server_err->cdata = svn_stringbuf_create_empty(server_err->error->pool);
+ server_err->collect_cdata = FALSE;
+ server_err->parser.pool = server_err->error->pool;
+ server_err->parser.user_data = server_err;
+ server_err->parser.start = start;
+ server_err->parser.end = end;
+ server_err->parser.cdata = cdata;
+ server_err->parser.ignore_errors = TRUE;
+
+ return server_err;
+}
+
/* Implements svn_ra_serf__response_handler_t */
svn_error_t *
svn_ra_serf__handle_discard_body(serf_request_t *request,
@@ -886,6 +911,8 @@ svn_ra_serf__handle_discard_body(serf_re
val = serf_bucket_headers_get(hdrs, "Content-Type");
if (val && strncasecmp(val, "text/xml", sizeof("text/xml") - 1) == 0)
{
+ /* ### we should figure out how to reuse begin_error_parsing */
+
server_err->error = svn_error_create(APR_SUCCESS, NULL, NULL);
server_err->has_xml_response = TRUE;
server_err->contains_precondition_error = FALSE;
@@ -960,9 +987,49 @@ svn_ra_serf__expect_empty_body(serf_requ
void *baton,
apr_pool_t *scratch_pool)
{
- /* This is the same as handle_multistatus_only, I think ... */
- return svn_error_trace(svn_ra_serf__handle_multistatus_only(
- request, response, baton, scratch_pool));
+ svn_ra_serf__handler_t *handler = baton;
+ serf_bucket_t *hdrs;
+ const char *val;
+
+ /* This function is just like handle_multistatus_only() except for the
+ XML parsing callbacks. We want to look for the human-readable element. */
+
+ /* We should see this just once, in order to initialize SERVER_ERROR.
+ At that point, the core error processing will take over. If we choose
+ not to parse an error, then we'll never return here (because we
+ change the response handler). */
+ SVN_ERR_ASSERT(handler->server_error == NULL);
+
+ hdrs = serf_bucket_response_get_headers(response);
+ val = serf_bucket_headers_get(hdrs, "Content-Type");
+ if (val && strncasecmp(val, "text/xml", sizeof("text/xml") - 1) == 0)
+ {
+ svn_ra_serf__server_error_t *server_err;
+
+ server_err = begin_error_parsing(start_error, end_error, cdata_error,
+ handler->handler_pool);
+
+ /* Get the parser to set our DONE flag. */
+ server_err->parser.done = &handler->done;
+
+ handler->server_error = server_err;
+ }
+ else
+ {
+ /* ### hmm. this is a bit early. we have not seen EOF. if the
+ ### caller thinks we are "done", then it may never call into
+ ### serf_context_run() again to flush the response. */
+ handler->done = TRUE;
+
+ /* The body was not text/xml, so we don't know what to do with it.
+ Toss anything that arrives. */
+ handler->discard_body = TRUE;
+ }
+
+ /* Returning SVN_NO_ERROR will return APR_SUCCESS to serf, which tells it
+ to call the response handler again. That will start up the XML parsing,
+ or it will be dropped on the floor (per the decision above). */
+ return SVN_NO_ERROR;
}
@@ -1101,6 +1168,10 @@ svn_ra_serf__handle_multistatus_only(ser
{
svn_ra_serf__handler_t *handler = baton;
+ /* This function is just like expect_empty_body() except for the
+ XML parsing callbacks. We are looking for very limited pieces of
+ the multistatus response. */
+
/* We should see this just once, in order to initialize SERVER_ERROR.
At that point, the core error processing will take over. If we choose
not to parse an error, then we'll never return here (because we
@@ -1117,19 +1188,8 @@ svn_ra_serf__handle_multistatus_only(ser
{
svn_ra_serf__server_error_t *server_err;
- server_err = apr_pcalloc(handler->handler_pool, sizeof(*server_err));
- server_err->init = TRUE;
- server_err->error = svn_error_create(APR_SUCCESS, NULL, NULL);
- server_err->has_xml_response = TRUE;
- server_err->contains_precondition_error = FALSE;
- server_err->cdata = svn_stringbuf_create_empty(server_err->error->pool);
- server_err->collect_cdata = FALSE;
- server_err->parser.pool = server_err->error->pool;
- server_err->parser.user_data = server_err;
- server_err->parser.start = start_207;
- server_err->parser.end = end_207;
- server_err->parser.cdata = cdata_207;
- server_err->parser.ignore_errors = TRUE;
+ server_err = begin_error_parsing(start_207, end_207, cdata_207,
+ handler->handler_pool);
/* Get the parser to set our DONE flag. */
server_err->parser.done = &handler->done;