On Sat, Jun 29, 2013 at 5:17 AM, gst...@apache.org <gst...@apache.org> wrote: > Author: gstein > Date: Sat Jun 29 03:17:58 2013 > New Revision: 1497980 > > URL: http://svn.apache.org/r1497980 > Log: > Introduce dynamic detection proxies that cannot handle chunked requests. > > * subversion/libsvn_ra_serf/ra_serf.h: > (svn_ra_serf__probe_proxy): new helper to determine proxy problems > > * subversion/libsvn_ra_serf/serf.c: > (load_config): don't bother clearing USING_CHUNKED_REQUESTS. the > probe (later) will deal with that. > (svn_ra_serf__open): if we're potentially using a busted proxy, then > probe the sucker > > * subversion/libsvn_ra_serf/options.c: > (create_simple_options_body): a body delegate that constructs a > small OPTIONS request body. > (svn_ra_serf__probe_proxy): send a small OPTIONS request. toss the > body. we're only looking for a 411 response. > > Modified: > subversion/trunk/subversion/libsvn_ra_serf/options.c > subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h > subversion/trunk/subversion/libsvn_ra_serf/serf.c > > Modified: subversion/trunk/subversion/libsvn_ra_serf/options.c > URL: > http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/options.c?rev=1497980&r1=1497979&r2=1497980&view=diff > ============================================================================== > --- subversion/trunk/subversion/libsvn_ra_serf/options.c (original) > +++ subversion/trunk/subversion/libsvn_ra_serf/options.c Sat Jun 29 03:17:58 > 2013 > @@ -518,6 +518,74 @@ 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; > + svn_error_t *err; > + > + 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. */ > + > + err = svn_ra_serf__context_run_one(handler, scratch_pool); > + if (err) > + { > + /* 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; > + > + svn_error_clear(err); > + return SVN_NO_ERROR; > + } > + > + return svn_error_trace( > + svn_error_compose_create( > + svn_ra_serf__error_on_status(handler->sline, > + serf_sess->session_url.path, > + handler->location), > + err)); > + } > + > + return SVN_NO_ERROR; > +} > + > + > svn_error_t * > svn_ra_serf__has_capability(svn_ra_session_t *ra_session, > svn_boolean_t *has, > > Modified: subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h > URL: > http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h?rev=1497980&r1=1497979&r2=1497980&view=diff > ============================================================================== > --- subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h (original) > +++ subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h Sat Jun 29 03:17:58 > 2013 > @@ -1341,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/trunk/subversion/libsvn_ra_serf/serf.c > URL: > http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/serf.c?rev=1497980&r1=1497979&r2=1497980&view=diff > ============================================================================== > --- subversion/trunk/subversion/libsvn_ra_serf/serf.c (original) > +++ subversion/trunk/subversion/libsvn_ra_serf/serf.c Sat Jun 29 03:17:58 2013 > @@ -368,12 +368,6 @@ load_config(svn_ra_serf__session_t *sess > session->using_proxy = FALSE; > } > > - /* If we're using a proxy, *and* it might be busted, > - then disable chunked requests. */ > - /* ### we'll switch this to dynamic shortly. */ > - if (session->using_proxy && session->busted_proxy) > - session->using_chunked_requests = FALSE; > - > /* Setup authentication. */ > SVN_ERR(load_http_auth_types(pool, config, server_group, > &session->authn_types)); > @@ -509,8 +503,14 @@ 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); > + > + /* We have set up a useful connection. If we have a proxy AND it might be > busted > + AND we switched to HTTP/1.1 (chunked requests), then probe the proxy. > */ > + if (serf_sess->using_proxy && serf_sess->busted_proxy && > !serf_sess->http10) > + SVN_ERR(svn_ra_serf__probe_proxy(serf_sess, pool));
This assumes the busted proxy is on the client's side, but that's not necessary the case. I'd drop the first condition. > - return svn_error_trace(err); > + return SVN_NO_ERROR; > } > > /* Implements svn_ra__vtable_t.reparent(). */ > > Missing from this patch is the instruction to the user to set the busted-prody flag. I don't have a test setup so I can test it, but from looking at the code it can be as simple as changing the error text in svn_ra_serf__error_on_status. Lieven