You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2013/10/14 15:34:32 UTC

svn commit: r1531890 - in /subversion/trunk/subversion: include/svn_client.h include/svn_ra.h libsvn_client/ra.c libsvn_ra_svn/client.c tests/libsvn_ra/ra-test.c

Author: brane
Date: Mon Oct 14 13:34:32 2013
New Revision: 1531890

URL: http://svn.apache.org/r1531890
Log:
Add another callback for ra_svn tunnels that determines whether the
default tunnel implementation should be used, based on the tunnel name.

* subversion/include/svn_ra.h (svn_ra_check_tunnel_func_t): New callback type.
  (svn_ra_callbacks2_t): Add check_tunnel_func callback. Update docstrings
   of open_tunnel_func and close_tunnel_func.
* subversion/include/svn_client.h (svn_client_ctx_t): Add check_tunnel_func
   callback. Update docstrings of open_tunnel_func and close_tunnel_func.
* subversion/libsvn_client/ra.c (svn_client__open_ra_session_internal):
   Pass check_tunnel_func to the RA session callbacks.
* subversion/libsvn_ra_svn/client.c (open_session): Change predicate
   for call to make_tunnel, based on tunnel_argv being non-null.
  (ra_svn_open): Call the check-tunnel callback to determine if
   a given tunnel type should be handled by the callbacks or by
   the default implementation.

* subversion/tests/libsvn_ra/ra-test.c
  (check_tunnel, last_tunnel_check): New.
  (check_tunnel_callback_test): New test.
  (tunel_callback_test): Verify last_tunnel_check.
  (test_funcs): Add check_tunnel_callback_test.

Modified:
    subversion/trunk/subversion/include/svn_client.h
    subversion/trunk/subversion/include/svn_ra.h
    subversion/trunk/subversion/libsvn_client/ra.c
    subversion/trunk/subversion/libsvn_ra_svn/client.c
    subversion/trunk/subversion/tests/libsvn_ra/ra-test.c

Modified: subversion/trunk/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1531890&r1=1531889&r2=1531890&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Mon Oct 14 13:34:32 2013
@@ -1019,17 +1019,30 @@ typedef struct svn_client_ctx_t
    * @Since New in 1.9. */
   apr_off_t progress;
 
+  /** Check-tunnel callback
+   *
+   * If not @c NULL, and open_tunnel_func is also not @c NULL, this
+   * callback will be invoked to check if open_tunnel_func should be
+   * used to create a specific tunnel, or if the default tunnel
+   * implementation (either built-in or configured in the client
+   * configuration file) should be used instead.
+   * @since New in 1.9.
+   */
+  svn_ra_check_tunnel_func_t check_tunnel_func;
+
   /** Open-tunnel callback
-   * If not @c null, this callback will be invoked to create an ra_svn
-   * connection that needs a tunnel, overriding any tunnel definitions
-   * in the client config file. This callback is used only for ra_svn
-   * and ignored by the other RA modules.
+   *
+   * If not @c NULL, this callback will be invoked to create a tunnel
+   * for a ra_svn connection that needs one, overriding any tunnel
+   * definitions in the client config file. This callback is used only
+   * for ra_svn and ignored by the other RA modules.
    * @since New in 1.9.
    */
   svn_ra_open_tunnel_func_t open_tunnel_func;
 
   /** Close-tunnel callback
-   * If not @c null, this callback will be invoked when the pool that
+   *
+   * If not @c NULL, this callback will be invoked when the pool that
    * owns the connection created by the open_tunnel callback is
    * cleared or destroyed. This callback is used only for ra_svn and
    * ignored by the other RA modules.

Modified: subversion/trunk/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_ra.h?rev=1531890&r1=1531889&r2=1531890&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_ra.h (original)
+++ subversion/trunk/subversion/include/svn_ra.h Mon Oct 14 13:34:32 2013
@@ -272,6 +272,18 @@ typedef svn_error_t *(*svn_ra_replay_rev
 
 
 /**
+ * Callback function that checks if an ra_svn tunnel called
+ * @a tunnel_name is handled by the callbakcs or the default
+ * implementation.
+ *
+ * @a tunnel_baton is the baton as originally passed to ra_open.
+ *
+ * @since New in 1.9.
+ */
+typedef svn_boolean_t (*svn_ra_check_tunnel_func_t)(
+    void *tunnel_baton, const char *tunnel_name);
+
+/**
  * Callback function for opening a tunnel in ra_svn.
  *
  * Given the @a tunnel_name, tunnel @a user and server @a hostname and
@@ -581,17 +593,30 @@ typedef struct svn_ra_callbacks2_t
    */
   svn_ra_get_wc_contents_func_t get_wc_contents;
 
+  /** Check-tunnel callback
+   *
+   * If not @c NULL, and open_tunnel_func is also not @c NULL, this
+   * callback will be invoked to check if open_tunnel_func should be
+   * used to create a specific tunnel, or if the default tunnel
+   * implementation (either built-in or configured in the client
+   * configuration file) should be used instead.
+   * @since New in 1.9.
+   */
+  svn_ra_check_tunnel_func_t check_tunnel_func;
+
   /** Open-tunnel callback
-   * If not @c null, this callback will be invoked to create an ra_svn
-   * connection that needs a tunnel, overriding any tunnel definitions
-   * in the client config file. This callback is used only for ra_svn
-   * and ignored by the other RA modules.
+   *
+   * If not @c NULL, this callback will be invoked to create a tunnel
+   * for a ra_svn connection that needs one, overriding any tunnel
+   * definitions in the client config file. This callback is used only
+   * for ra_svn and ignored by the other RA modules.
    * @since New in 1.9.
    */
   svn_ra_open_tunnel_func_t open_tunnel_func;
 
   /** Close-tunnel callback
-   * If not @c null, this callback will be invoked when the pool that
+   *
+   * If not @c NULL, this callback will be invoked when the pool that
    * owns the connection created by the open_tunnel callback is
    * cleared or destroyed. This callback is used only for ra_svn and
    * ignored by the other RA modules.

Modified: subversion/trunk/subversion/libsvn_client/ra.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/ra.c?rev=1531890&r1=1531889&r2=1531890&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/ra.c (original)
+++ subversion/trunk/subversion/libsvn_client/ra.c Mon Oct 14 13:34:32 2013
@@ -350,6 +350,7 @@ svn_client__open_ra_session_internal(svn
   cbtable->get_client_string = get_client_string;
   if (base_dir_abspath)
     cbtable->get_wc_contents = get_wc_contents;
+  cbtable->check_tunnel_func = ctx->check_tunnel_func;
   cbtable->open_tunnel_func = ctx->open_tunnel_func;
   cbtable->close_tunnel_func = ctx->close_tunnel_func;
   cbtable->tunnel_baton = ctx->tunnel_baton;

Modified: subversion/trunk/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_svn/client.c?rev=1531890&r1=1531889&r2=1531890&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/trunk/subversion/libsvn_ra_svn/client.c Mon Oct 14 13:34:32 2013
@@ -625,7 +625,7 @@ static svn_error_t *open_session(svn_ra_
 
   if (tunnel_name)
     {
-      if (!callbacks->open_tunnel_func)
+      if (tunnel_argv)
         SVN_ERR(make_tunnel(tunnel_argv, &conn, pool));
       else
         {
@@ -799,7 +799,14 @@ static svn_error_t *ra_svn_open(svn_ra_s
 
   parse_tunnel(url, &tunnel, pool);
 
-  if (tunnel && !callbacks->open_tunnel_func)
+  /* Use the default tunnel implementation if we got a tunnel name,
+     but either do not have tunnel handler callbacks installed, or
+     the handlers don't like the tunnel name. */
+  if (tunnel
+      && (!callbacks->open_tunnel_func
+          || (callbacks->check_tunnel_func && callbacks->open_tunnel_func
+              && !callbacks->check_tunnel_func(callbacks->tunnel_baton,
+                                               tunnel))))
     SVN_ERR(find_tunnel_agent(tunnel, uri.hostinfo, &tunnel_argv, config,
                               pool));
   else

Modified: subversion/trunk/subversion/tests/libsvn_ra/ra-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_ra/ra-test.c?rev=1531890&r1=1531889&r2=1531890&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_ra/ra-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_ra/ra-test.c Mon Oct 14 13:34:32 2013
@@ -94,8 +94,16 @@ commit_changes(svn_ra_session_t *session
   return SVN_NO_ERROR;
 }
 
+static svn_boolean_t last_tunnel_check;
 static int tunnel_open_count;
 
+static svn_boolean_t
+check_tunnel(void *tunnel_baton, const char *tunnel_name)
+{
+  last_tunnel_check = (0 == strcmp(tunnel_name, "test"));
+  return last_tunnel_check;
+}
+
 static svn_error_t *
 open_tunnel(apr_file_t **request, apr_file_t **response,
             void **tunnel_context, void *tunnel_baton,
@@ -226,6 +234,36 @@ location_segments_test(const svn_test_op
 
 
 /* Test ra_svn tunnel callbacks. */
+
+static svn_error_t *
+check_tunnel_callback_test(const svn_test_opts_t *opts,
+                           apr_pool_t *pool)
+{
+  svn_ra_callbacks2_t *cbtable;
+  svn_ra_session_t *session;
+  svn_error_t *err;
+
+  SVN_ERR(svn_ra_create_callbacks(&cbtable, pool));
+  cbtable->check_tunnel_func = check_tunnel;
+  cbtable->open_tunnel_func = open_tunnel;
+  cbtable->close_tunnel_func = close_tunnel;
+  SVN_ERR(svn_cmdline_create_auth_baton(&cbtable->auth_baton,
+                                        TRUE  /* non_interactive */,
+                                        "jrandom", "rayjandom",
+                                        NULL,
+                                        TRUE  /* no_auth_cache */,
+                                        FALSE /* trust_server_cert */,
+                                        NULL, NULL, NULL, pool));
+
+  last_tunnel_check = TRUE;
+  err = svn_ra_open4(&session, NULL, "svn+foo://localhost/no-repo",
+                     NULL, cbtable, NULL, NULL, pool);
+  svn_error_clear(err);
+  SVN_TEST_ASSERT(err);
+  SVN_TEST_ASSERT(!last_tunnel_check);
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 tunel_callback_test(const svn_test_opts_t *opts,
                     apr_pool_t *pool)
@@ -241,6 +279,7 @@ tunel_callback_test(const svn_test_opts_
 
   url = apr_pstrcat(pool, "svn+test://localhost/", tunnel_repos_name, NULL);
   SVN_ERR(svn_ra_create_callbacks(&cbtable, pool));
+  cbtable->check_tunnel_func = check_tunnel;
   cbtable->open_tunnel_func = open_tunnel;
   cbtable->close_tunnel_func = close_tunnel;
   SVN_ERR(svn_cmdline_create_auth_baton(&cbtable->auth_baton,
@@ -251,6 +290,7 @@ tunel_callback_test(const svn_test_opts_
                                         FALSE /* trust_server_cert */,
                                         NULL, NULL, NULL, pool));
 
+  last_tunnel_check = FALSE;
   tunnel_open_count = 0;
   connection_pool = svn_pool_create(pool);
   err = svn_ra_open4(&session, NULL, url, NULL, cbtable, NULL, NULL,
@@ -262,6 +302,7 @@ tunel_callback_test(const svn_test_opts_
       return SVN_NO_ERROR;
     }
   SVN_ERR(err);
+  SVN_TEST_ASSERT(last_tunnel_check);
   SVN_TEST_ASSERT(tunnel_open_count > 0);
   svn_pool_destroy(connection_pool);
   SVN_TEST_ASSERT(tunnel_open_count == 0);
@@ -276,6 +317,8 @@ struct svn_test_descriptor_t test_funcs[
     SVN_TEST_NULL,
     SVN_TEST_OPTS_PASS(location_segments_test,
                        "test svn_ra_get_location_segments"),
+    SVN_TEST_OPTS_PASS(check_tunnel_callback_test,
+                       "test ra_svn tunnel callback check"),
     SVN_TEST_OPTS_PASS(tunel_callback_test,
                        "test ra_svn tunnel creation callbacks"),
     SVN_TEST_NULL