Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 45BE110AF9 for ; Mon, 14 Oct 2013 13:34:59 +0000 (UTC) Received: (qmail 46192 invoked by uid 500); 14 Oct 2013 13:34:58 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 45569 invoked by uid 500); 14 Oct 2013 13:34:55 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 45560 invoked by uid 99); 14 Oct 2013 13:34:54 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 14 Oct 2013 13:34:54 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 14 Oct 2013 13:34:53 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id E5A592388A56; Mon, 14 Oct 2013 13:34:32 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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 Date: Mon, 14 Oct 2013 13:34:32 -0000 To: commits@subversion.apache.org From: brane@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20131014133432.E5A592388A56@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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