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 07:22:59 UTC

svn commit: r1335339 - in /subversion/trunk/subversion/libsvn_ra_serf: locks.c util.c

Author: gstein
Date: Tue May  8 05:22:59 2012
New Revision: 1335339

URL: http://svn.apache.org/viewvc?rev=1335339&view=rev
Log:
Switch the locks processing over to proper error parsing/handling.

* subversion/libsvn_ra_serf/locks.c:
  (lock_info_t): remove DONE member.
  (determine_error): new helper for resolving the correct error to
    return from locking operations.
  (handle_lock): for errors 403 and 423, switch over to processing the
    body for a potential human-readable server error. drop the older
    error handling.
  (svn_ra_serf__get_lock, svn_ra_serf__lock): switch to HANDLER->DONE
    and run_one(), and use determine_error() to select the returned error.

* subversion/libsvn_ra_serf/util.c:
  (handle_response_cb): ensure that DONE is set if we ever see EOF

Modified:
    subversion/trunk/subversion/libsvn_ra_serf/locks.c
    subversion/trunk/subversion/libsvn_ra_serf/util.c

Modified: subversion/trunk/subversion/libsvn_ra_serf/locks.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/locks.c?rev=1335339&r1=1335338&r2=1335339&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/locks.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/locks.c Tue May  8 05:22:59 2012
@@ -72,8 +72,6 @@ typedef struct lock_info_t {
 
   svn_ra_serf__handler_t *handler;
 
-  /* are we done? */
-  svn_boolean_t done;
 } lock_info_t;
 
 
@@ -331,6 +329,42 @@ set_lock_headers(serf_bucket_t *headers,
   return APR_SUCCESS;
 }
 
+
+/* Register an error within the session. If something is already there,
+   then it will take precedence.  */
+static svn_error_t *
+determine_error(svn_ra_serf__handler_t *handler,
+                svn_error_t *err)
+{
+  /* If we found an error in the response, then blend it in.  */
+  if (handler->server_error)
+    {
+      /* Client-side error takes precedence.  */
+      err = svn_error_compose_create(err, handler->server_error->error);
+    }
+  else
+    {
+      apr_status_t errcode;
+
+      if (handler->sline.code == 423)
+        errcode = SVN_ERR_FS_PATH_ALREADY_LOCKED;
+      else if (handler->sline.code == 403)
+        errcode = SVN_ERR_RA_DAV_FORBIDDEN;
+      else
+        return err;
+
+      /* The server did not send us a detailed human-readable error.
+         Provide a generic error.  */
+      err = svn_error_createf(errcode, err,
+                              _("Lock request failed: %d %s"),
+                              handler->sline.code,
+                              handler->sline.reason);
+    }
+
+  return err;
+}
+
+
 /* Implements svn_ra_serf__response_handler_t */
 static svn_error_t *
 handle_lock(serf_request_t *request,
@@ -340,30 +374,24 @@ handle_lock(serf_request_t *request,
 {
   svn_ra_serf__xml_parser_t *xml_ctx = handler_baton;
   lock_info_t *ctx = xml_ctx->user_data;
-  svn_error_t *err;
+
+  /* 403 (Forbidden) when a lock doesn't exist.
+     423 (Locked) when a lock already exists.  */
+  if (ctx->handler->sline.code == 403
+      || ctx->handler->sline.code == 423)
+    {
+      /* Go look in the body for a server-provided error. This will
+         reset flags for the core handler to Do The Right Thing. We
+         won't be back to this handler again.  */
+      return svn_error_trace(svn_ra_serf__expect_empty_body(
+                               request, response, ctx->handler, pool));
+    }
 
   if (ctx->read_headers == FALSE)
     {
       serf_bucket_t *headers;
       const char *val;
 
-      /* 423 == Locked */
-      if (ctx->handler->sline.code == 423)
-        {
-          /* Older servers may not give a descriptive error, so we'll
-             make one of our own if we can't find one in the response. */
-          err = svn_ra_serf__handle_server_error(request, response, pool);
-          if (!err)
-            {
-              err = svn_error_createf(SVN_ERR_FS_PATH_ALREADY_LOCKED,
-                                      NULL,
-                                      _("Lock request failed: %d %s"),
-                                      ctx->handler->sline.code,
-                                      ctx->handler->sline.reason);
-            }
-          return err;
-        }
-
       headers = serf_bucket_response_get_headers(response);
 
       val = serf_bucket_headers_get(headers, SVN_DAV_LOCK_OWNER_HEADER);
@@ -382,24 +410,6 @@ handle_lock(serf_request_t *request,
       ctx->read_headers = TRUE;
     }
 
-  /* Forbidden when a lock doesn't exist. */
-  if (ctx->handler->sline.code == 403)
-    {
-      /* If we get an "unexpected EOF" error, we'll wrap it with
-         generic request failure error. */
-      err = svn_ra_serf__handle_discard_body(request, response, NULL, pool);
-      if (err && APR_STATUS_IS_EOF(err->apr_err))
-        {
-          ctx->done = TRUE;
-          err = svn_error_createf(SVN_ERR_RA_DAV_FORBIDDEN,
-                                  err,
-                                  _("Lock request failed: %d %s"),
-                                  ctx->handler->sline.code,
-                                  ctx->handler->sline.reason);
-        }
-      return err;
-    }
-
   return svn_ra_serf__handle_xml_parser(request, response,
                                         handler_baton, pool);
 }
@@ -513,7 +523,7 @@ svn_ra_serf__get_lock(svn_ra_session_t *
   parser_ctx->start = start_lock;
   parser_ctx->end = end_lock;
   parser_ctx->cdata = cdata_lock;
-  parser_ctx->done = &lock_ctx->done;
+  parser_ctx->done = &handler->done;
 
   handler->body_delegate = create_getlock_body;
   handler->body_delegate_baton = lock_ctx;
@@ -526,8 +536,8 @@ svn_ra_serf__get_lock(svn_ra_session_t *
 
   lock_ctx->handler = handler;
 
-  svn_ra_serf__request_create(handler);
-  err = svn_ra_serf__context_run_wait(&lock_ctx->done, session, pool);
+  err = svn_ra_serf__context_run_one(handler, pool);
+  err = determine_error(handler, err);
 
   if (handler->sline.code == 404)
     {
@@ -608,7 +618,7 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
       parser_ctx->start = start_lock;
       parser_ctx->end = end_lock;
       parser_ctx->cdata = cdata_lock;
-      parser_ctx->done = &lock_ctx->done;
+      parser_ctx->done = &handler->done;
 
       handler->header_delegate = set_lock_headers;
       handler->header_delegate_baton = lock_ctx;
@@ -621,8 +631,8 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
 
       lock_ctx->handler = handler;
 
-      svn_ra_serf__request_create(handler);
-      err = svn_ra_serf__context_run_wait(&lock_ctx->done, session, iterpool);
+      err = svn_ra_serf__context_run_one(handler, iterpool);
+      err = determine_error(handler, err);
 
       if (lock_func)
         new_err = lock_func(lock_baton, lock_ctx->path, TRUE, lock_ctx->lock,

Modified: subversion/trunk/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/util.c?rev=1335339&r1=1335338&r2=1335339&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/util.c Tue May  8 05:22:59 2012
@@ -1916,7 +1916,6 @@ handle_response_cb(serf_request_t *reque
                    apr_pool_t *scratch_pool)
 {
   svn_ra_serf__handler_t *handler = baton;
-  svn_ra_serf__session_t *session = handler->session;
   svn_error_t *err;
   apr_status_t inner_status;
   apr_status_t outer_status;
@@ -1925,8 +1924,16 @@ handle_response_cb(serf_request_t *reque
                                         handler, &inner_status,
                                         scratch_pool));
 
-  outer_status = save_error(session, err);
-  return outer_status ? outer_status : inner_status;
+  /* Select the right status value to return.  */
+  outer_status = save_error(handler->session, err);
+  if (!outer_status)
+    outer_status = inner_status;
+
+  /* Make sure the DONE flag is set properly.  */
+  if (APR_STATUS_IS_EOF(outer_status) || APR_STATUS_IS_EOF(inner_status))
+    handler->done = TRUE;
+
+  return outer_status;
 }
 
 /* Perform basic request setup, with special handling for HEAD requests,