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/07/16 23:27:59 UTC
svn commit: r1503895 - in /subversion/branches/1.8.x: ./
subversion/libsvn_ra_serf/ subversion/libsvn_subr/ subversion/svn/
Author: breser
Date: Tue Jul 16 21:27:58 2013
New Revision: 1503895
URL: http://svn.apache.org/r1503895
Log:
Merge the 1.8.x-tristate-chunked-request branch:
* r1502401, r1502674
Implement the tristate version of http-chunked-request.
Branch: ^/subversion/branches/1.8.x-tristate-chunked-request
Justification:
Better behavior over the boolean (see the mailing list for details)
Notes:
Revisions are actually from ^/subversion/branches/tristate-chunked-request
Votes:
+1: breser, danielsh, ivan, philip, rhuijben
-0: gstein
Modified:
subversion/branches/1.8.x/ (props changed)
subversion/branches/1.8.x/configure.ac (props changed)
subversion/branches/1.8.x/subversion/libsvn_ra_serf/options.c
subversion/branches/1.8.x/subversion/libsvn_ra_serf/ra_serf.h
subversion/branches/1.8.x/subversion/libsvn_ra_serf/serf.c
subversion/branches/1.8.x/subversion/libsvn_ra_serf/util.c
subversion/branches/1.8.x/subversion/libsvn_subr/config_file.c
subversion/branches/1.8.x/subversion/svn/svn.c (props changed)
Propchange: subversion/branches/1.8.x/
------------------------------------------------------------------------------
Merged /subversion/branches/tristate-chunked-request:r1502401,1502673
Merged /subversion/trunk:r1489117,1496470,1497975,1497980,1498012,1499423,1499595,1502097
Merged /subversion/branches/1.8.x-busted-proxy:r1499222-1502434
Merged /subversion/branches/1.8.x-tristate-chunked-request:r1502435-1503894
Propchange: subversion/branches/1.8.x/configure.ac
------------------------------------------------------------------------------
Merged /subversion/branches/1.8.x-busted-proxy/configure.ac:r1499222-1502434
Merged /subversion/branches/1.8.x-tristate-chunked-request/configure.ac:r1502435-1503894
Modified: subversion/branches/1.8.x/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x/subversion/libsvn_ra_serf/options.c?rev=1503895&r1=1503894&r2=1503895&view=diff
==============================================================================
--- subversion/branches/1.8.x/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/1.8.x/subversion/libsvn_ra_serf/options.c Tue Jul 16 21:27:58 2013
@@ -520,6 +520,65 @@ svn_ra_serf__exchange_capabilities(svn_r
}
+static svn_error_t *
+create_simple_options_body(serf_bucket_t **body_bkt,
+ void *baton,
+ serf_bucket_alloc_t *alloc,
+ apr_pool_t *pool)
+{
+ serf_bucket_t *body;
+ serf_bucket_t *s;
+
+ body = serf_bucket_aggregate_create(alloc);
+ svn_ra_serf__add_xml_header_buckets(body, alloc);
+
+ s = SERF_BUCKET_SIMPLE_STRING("<D:options xmlns:D=\"DAV:\" />", alloc);
+ serf_bucket_aggregate_append(body, s);
+
+ *body_bkt = body;
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_ra_serf__probe_proxy(svn_ra_serf__session_t *serf_sess,
+ apr_pool_t *scratch_pool)
+{
+ svn_ra_serf__handler_t *handler;
+
+ handler = apr_pcalloc(scratch_pool, sizeof(*handler));
+ handler->handler_pool = scratch_pool;
+ handler->method = "OPTIONS";
+ handler->path = serf_sess->session_url.path;
+ handler->conn = serf_sess->conns[0];
+ handler->session = serf_sess;
+
+ /* We don't care about the response body, so discard it. */
+ handler->response_handler = svn_ra_serf__handle_discard_body;
+
+ /* We need a simple body, in order to send it in chunked format. */
+ handler->body_delegate = create_simple_options_body;
+
+ /* No special headers. */
+
+ SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));
+ /* Some versions of nginx in reverse proxy mode will return 411. They want
+ a Content-Length header, rather than chunked requests. We can keep other
+ HTTP/1.1 features, but will disable the chunking. */
+ if (handler->sline.code == 411)
+ {
+ serf_sess->using_chunked_requests = FALSE;
+
+ return SVN_NO_ERROR;
+ }
+ SVN_ERR(svn_ra_serf__error_on_status(handler->sline,
+ handler->path,
+ handler->location));
+
+ return SVN_NO_ERROR;
+}
+
+
svn_error_t *
svn_ra_serf__has_capability(svn_ra_session_t *ra_session,
svn_boolean_t *has,
Modified: subversion/branches/1.8.x/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x/subversion/libsvn_ra_serf/ra_serf.h?rev=1503895&r1=1503894&r2=1503895&view=diff
==============================================================================
--- subversion/branches/1.8.x/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/1.8.x/subversion/libsvn_ra_serf/ra_serf.h Tue Jul 16 21:27:58 2013
@@ -144,6 +144,13 @@ struct svn_ra_serf__session_t {
HTTP/1.0. Thus, we cannot send chunked requests. */
svn_boolean_t http10;
+ /* Should we use Transfer-Encoding: chunked for HTTP/1.1 servers. */
+ svn_boolean_t using_chunked_requests;
+
+ /* Do we need to detect whether the connection supports chunked requests?
+ i.e. is there a (reverse) proxy that does not support them? */
+ svn_boolean_t detect_chunking;
+
/* Our Version-Controlled-Configuration; may be NULL until we know it. */
const char *vcc_url;
@@ -186,7 +193,7 @@ struct svn_ra_serf__session_t {
const char *activity_collection_url;
/* Are we using a proxy? */
- int using_proxy;
+ svn_boolean_t using_proxy;
const char *proxy_username;
const char *proxy_password;
@@ -1334,6 +1341,14 @@ svn_ra_serf__run_merge(const svn_commit_
/** OPTIONS-related functions **/
+/* When running with a proxy, we may need to detect and correct for problems.
+ This probing function will send a simple OPTIONS request to detect problems
+ with the connection. */
+svn_error_t *
+svn_ra_serf__probe_proxy(svn_ra_serf__session_t *serf_sess,
+ apr_pool_t *scratch_pool);
+
+
/* On HTTPv2 connections, run an OPTIONS request over CONN to fetch the
current youngest revnum, returning it in *YOUNGEST.
Modified: subversion/branches/1.8.x/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x/subversion/libsvn_ra_serf/serf.c?rev=1503895&r1=1503894&r2=1503895&view=diff
==============================================================================
--- subversion/branches/1.8.x/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/1.8.x/subversion/libsvn_ra_serf/serf.c Tue Jul 16 21:27:58 2013
@@ -137,6 +137,10 @@ load_http_auth_types(apr_pool_t *pool, s
runtime configuration variable. */
#define DEFAULT_HTTP_TIMEOUT 600
+/* Private symbol for the 1.9-public SVN_CONFIG_OPTION_HTTP_CHUNKED_REQUESTS */
+#define OPTION_HTTP_CHUNKED_REQUESTS "http-chunked-requests"
+
+
static svn_error_t *
load_config(svn_ra_serf__session_t *session,
apr_hash_t *config_hash,
@@ -149,6 +153,7 @@ load_config(svn_ra_serf__session_t *sess
const char *timeout_str = NULL;
const char *exceptions;
apr_port_t proxy_port;
+ svn_tristate_t chunked_requests;
if (config_hash)
{
@@ -225,6 +230,12 @@ load_config(svn_ra_serf__session_t *sess
SVN_CONFIG_OPTION_HTTP_MAX_CONNECTIONS,
SVN_CONFIG_DEFAULT_OPTION_HTTP_MAX_CONNECTIONS));
+ /* Should we use chunked transfer encoding. */
+ SVN_ERR(svn_config_get_tristate(config, &chunked_requests,
+ SVN_CONFIG_SECTION_GLOBAL,
+ OPTION_HTTP_CHUNKED_REQUESTS,
+ "auto", svn_tristate_unknown));
+
if (config)
server_group = svn_config_find_group(config,
session->session_url.hostname,
@@ -281,6 +292,12 @@ load_config(svn_ra_serf__session_t *sess
server_group,
SVN_CONFIG_OPTION_HTTP_MAX_CONNECTIONS,
session->max_connections));
+
+ /* Should we use chunked transfer encoding. */
+ SVN_ERR(svn_config_get_tristate(config, &chunked_requests,
+ server_group,
+ OPTION_HTTP_CHUNKED_REQUESTS,
+ "auto", chunked_requests));
}
/* Don't allow the http-max-connections value to be larger than our
@@ -355,6 +372,24 @@ load_config(svn_ra_serf__session_t *sess
session->using_proxy = FALSE;
}
+ /* Setup detect_chunking and using_chunked_requests based on
+ * the chunked_requests tristate */
+ if (chunked_requests == svn_tristate_unknown)
+ {
+ session->detect_chunking = TRUE;
+ session->using_chunked_requests = TRUE;
+ }
+ else if (chunked_requests == svn_tristate_true)
+ {
+ session->detect_chunking = FALSE;
+ session->using_chunked_requests = TRUE;
+ }
+ else /* chunked_requests == svn_tristate_false */
+ {
+ session->detect_chunking = FALSE;
+ session->using_chunked_requests = FALSE;
+ }
+
/* Setup authentication. */
SVN_ERR(load_http_auth_types(pool, config, server_group,
&session->authn_types));
@@ -442,6 +477,10 @@ svn_ra_serf__open(svn_ra_session_t *sess
HTTP/1.1 is supported, we can upgrade. */
serf_sess->http10 = TRUE;
+ /* If we switch to HTTP/1.1, then we will use chunked requests. We may disable
+ this, if we find an intervening proxy does not support chunked requests. */
+ serf_sess->using_chunked_requests = TRUE;
+
SVN_ERR(load_config(serf_sess, config, serf_sess->pool));
serf_sess->conns[0] = apr_pcalloc(serf_sess->pool,
@@ -486,8 +525,17 @@ svn_ra_serf__open(svn_ra_session_t *sess
if (err && err->apr_err == APR_EGENERAL)
err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, err,
_("Connection to '%s' failed"), session_URL);
+ SVN_ERR(err);
- return svn_error_trace(err);
+ /* We have set up a useful connection (that doesn't indication a redirect).
+ If we've been told there is possibly a worrisome proxy in our path to the
+ server AND we switched to HTTP/1.1 (chunked requests), then probe for
+ problems in any proxy. */
+ if ((corrected_url == NULL || *corrected_url == NULL)
+ && serf_sess->detect_chunking && !serf_sess->http10)
+ SVN_ERR(svn_ra_serf__probe_proxy(serf_sess, pool));
+
+ return SVN_NO_ERROR;
}
/* Implements svn_ra__vtable_t.reparent(). */
Modified: subversion/branches/1.8.x/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x/subversion/libsvn_ra_serf/util.c?rev=1503895&r1=1503894&r2=1503895&view=diff
==============================================================================
--- subversion/branches/1.8.x/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/1.8.x/subversion/libsvn_ra_serf/util.c Tue Jul 16 21:27:58 2013
@@ -373,10 +373,8 @@ conn_setup(apr_socket_t *sock,
{
conn->ssl_context = serf_bucket_ssl_encrypt_context_get(*read_bkt);
-#if SERF_VERSION_AT_LEAST(1,0,0)
serf_ssl_set_hostname(conn->ssl_context,
conn->session->session_url.hostname);
-#endif
serf_ssl_client_cert_provider_set(conn->ssl_context,
svn_ra_serf__handle_client_cert,
@@ -642,10 +640,10 @@ setup_serf_req(serf_request_t *request,
{
serf_bucket_alloc_t *allocator = serf_request_get_alloc(request);
-#if SERF_VERSION_AT_LEAST(1, 1, 0)
svn_spillbuf_t *buf;
+ svn_boolean_t set_CL = session->http10 || !session->using_chunked_requests;
- if (session->http10 && body_bkt != NULL)
+ if (set_CL && body_bkt != NULL)
{
/* Ugh. Use HTTP/1.0 to talk to the server because we don't know if
it speaks HTTP/1.1 (and thus, chunked requests), or because the
@@ -665,7 +663,6 @@ setup_serf_req(serf_request_t *request,
request_pool,
scratch_pool);
}
-#endif
/* Create a request bucket. Note that this sucker is kind enough to
add a "Host" header for us. */
@@ -674,15 +671,13 @@ setup_serf_req(serf_request_t *request,
/* Set the Content-Length value. This will also trigger an HTTP/1.0
request (rather than the default chunked request). */
-#if SERF_VERSION_AT_LEAST(1, 1, 0)
- if (session->http10)
+ if (set_CL)
{
if (body_bkt == NULL)
serf_bucket_request_set_CL(*req_bkt, 0);
else
serf_bucket_request_set_CL(*req_bkt, svn_spillbuf__get_size(buf));
}
-#endif
*hdrs_bkt = serf_bucket_request_get_headers(*req_bkt);
@@ -696,10 +691,10 @@ setup_serf_req(serf_request_t *request,
serf_bucket_headers_setn(*hdrs_bkt, "Content-Type", content_type);
}
-#if SERF_VERSION_AT_LEAST(1, 1, 0)
if (session->http10)
+ {
serf_bucket_headers_setn(*hdrs_bkt, "Connection", "keep-alive");
-#endif
+ }
if (accept_encoding)
{
@@ -2418,8 +2413,10 @@ svn_ra_serf__error_on_status(serf_status
case 411:
return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
- _("DAV request failed: "
- "Content length required"));
+ _("DAV request failed: 411 Content length required. The "
+ "server or an intermediate proxy does not accept "
+ "chunked encoding. Try setting 'http-chunked-requests' "
+ "to 'auto' or 'no' in your client configuration."));
}
if (sline.code >= 300)
Modified: subversion/branches/1.8.x/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.8.x/subversion/libsvn_subr/config_file.c?rev=1503895&r1=1503894&r2=1503895&view=diff
==============================================================================
--- subversion/branches/1.8.x/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/1.8.x/subversion/libsvn_subr/config_file.c Tue Jul 16 21:27:58 2013
@@ -834,6 +834,8 @@ svn_config_ensure(const char *config_dir
"### http-max-connections Maximum number of parallel server" NL
"### connections to use for any given" NL
"### HTTP operation." NL
+ "### http-chunked-requests Whether to use chunked transfer" NL
+ "### encoding for HTTP requests body." NL
"### neon-debug-mask Debug mask for Neon HTTP library" NL
"### ssl-authority-files List of files, each of a trusted CA"
NL
Propchange: subversion/branches/1.8.x/subversion/svn/svn.c
------------------------------------------------------------------------------
Merged /subversion/branches/1.8.x-tristate-chunked-request/subversion/svn/svn.c:r1502435-1503894
Merged /subversion/trunk/subversion/svn/svn.c:r1488693,1489117,1490721,1491756,1491868,1494657,1495063,1495204,1495209,1495214,1495256,1495329,1495597,1495805,1495978,1496470,1497975,1497980,1498012,1498449,1498455,1498483-1498484,1498486,1498997,1499034,1499064,1499100,1499403,1499423,1499438,1499447,1499460,1499483,1499492,1499496,1499498,1499595,1500175,1500226,1500695,1500762,1500799,1500801-1500802,1500904,1500928,1502097
Merged /subversion/branches/1.8.x-busted-proxy/subversion/svn/svn.c:r1499222-1502434
Merged /subversion/branches/1.8.x-r1495063/subversion/svn/svn.c:r1495804-1501074