diff options
Diffstat (limited to 'subversion/libsvn_ra_serf')
-rw-r--r-- | subversion/libsvn_ra_serf/blame.c | 2 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/commit.c | 6 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/getdate.c | 13 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/getlocations.c | 2 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/getlocationsegments.c | 2 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/getlocks.c | 2 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/inherited_props.c | 2 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/log.c | 2 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/mergeinfo.c | 15 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/options.c | 68 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/property.c | 2 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/ra_serf.h | 19 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/replay.c | 4 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/serf.c | 58 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/update.c | 6 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/util.c | 35 | ||||
-rw-r--r-- | subversion/libsvn_ra_serf/xml.c | 8 |
17 files changed, 200 insertions, 46 deletions
diff --git a/subversion/libsvn_ra_serf/blame.c b/subversion/libsvn_ra_serf/blame.c index fa4243c0840b..b6f136a2bdad 100644 --- a/subversion/libsvn_ra_serf/blame.c +++ b/subversion/libsvn_ra_serf/blame.c @@ -366,7 +366,7 @@ svn_ra_serf__get_file_revs(svn_ra_session_t *ra_session, err = svn_ra_serf__context_run_one(handler, pool); err = svn_error_compose_create( - svn_ra_serf__error_on_status(handler->sline.code, + svn_ra_serf__error_on_status(handler->sline, handler->path, handler->location), err); diff --git a/subversion/libsvn_ra_serf/commit.c b/subversion/libsvn_ra_serf/commit.c index aaf17177d9d4..56a2bcea1e3b 100644 --- a/subversion/libsvn_ra_serf/commit.c +++ b/subversion/libsvn_ra_serf/commit.c @@ -223,7 +223,7 @@ return_response_err(svn_ra_serf__handler_t *handler) /* Try to return one of the standard errors for 301, 404, etc., then look for an error embedded in the response. */ return svn_error_compose_create(svn_ra_serf__error_on_status( - handler->sline.code, + handler->sline, handler->path, handler->location), err); @@ -2269,7 +2269,9 @@ abort_edit(void *edit_baton, && handler->sline.code != 404 ) { - SVN_ERR_MALFUNCTION(); + return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, + _("DELETE returned unexpected status: %d"), + handler->sline.code); } return SVN_NO_ERROR; diff --git a/subversion/libsvn_ra_serf/getdate.c b/subversion/libsvn_ra_serf/getdate.c index 867e86fbd501..cc1014ef0297 100644 --- a/subversion/libsvn_ra_serf/getdate.c +++ b/subversion/libsvn_ra_serf/getdate.c @@ -131,6 +131,7 @@ svn_ra_serf__get_dated_revision(svn_ra_session_t *ra_session, svn_ra_serf__handler_t *handler; svn_ra_serf__xml_context_t *xmlctx; const char *report_target; + svn_error_t *err; date_ctx = apr_palloc(pool, sizeof(*date_ctx)); date_ctx->time = tm; @@ -155,7 +156,15 @@ svn_ra_serf__get_dated_revision(svn_ra_session_t *ra_session, *date_ctx->revision = SVN_INVALID_REVNUM; - /* ### use svn_ra_serf__error_on_status() ? */ + err = svn_ra_serf__context_run_one(handler, pool); - return svn_error_trace(svn_ra_serf__context_run_one(handler, pool)); + SVN_ERR(svn_error_compose_create( + svn_ra_serf__error_on_status(handler->sline, + report_target, + handler->location), + err)); + + SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(*revision)); + + return SVN_NO_ERROR; } diff --git a/subversion/libsvn_ra_serf/getlocations.c b/subversion/libsvn_ra_serf/getlocations.c index d3e3175fac3d..1ae4f82dd8c8 100644 --- a/subversion/libsvn_ra_serf/getlocations.c +++ b/subversion/libsvn_ra_serf/getlocations.c @@ -192,7 +192,7 @@ svn_ra_serf__get_locations(svn_ra_session_t *ra_session, err = svn_ra_serf__context_run_one(handler, pool); SVN_ERR(svn_error_compose_create( - svn_ra_serf__error_on_status(handler->sline.code, + svn_ra_serf__error_on_status(handler->sline, req_url, handler->location), err)); diff --git a/subversion/libsvn_ra_serf/getlocationsegments.c b/subversion/libsvn_ra_serf/getlocationsegments.c index d2b69bf685c4..e5c58a90b5a7 100644 --- a/subversion/libsvn_ra_serf/getlocationsegments.c +++ b/subversion/libsvn_ra_serf/getlocationsegments.c @@ -194,7 +194,7 @@ svn_ra_serf__get_location_segments(svn_ra_session_t *ra_session, err = svn_ra_serf__context_run_one(handler, pool); err = svn_error_compose_create( - svn_ra_serf__error_on_status(handler->sline.code, + svn_ra_serf__error_on_status(handler->sline, handler->path, handler->location), err); diff --git a/subversion/libsvn_ra_serf/getlocks.c b/subversion/libsvn_ra_serf/getlocks.c index 61b8b8c7b051..04e556179936 100644 --- a/subversion/libsvn_ra_serf/getlocks.c +++ b/subversion/libsvn_ra_serf/getlocks.c @@ -266,7 +266,7 @@ svn_ra_serf__get_locks(svn_ra_session_t *ra_session, have existed earlier (E.g. 'svn ls http://s/svn/trunk/file@1' */ if (handler->sline.code != 404) { - SVN_ERR(svn_ra_serf__error_on_status(handler->sline.code, + SVN_ERR(svn_ra_serf__error_on_status(handler->sline, handler->path, handler->location)); } diff --git a/subversion/libsvn_ra_serf/inherited_props.c b/subversion/libsvn_ra_serf/inherited_props.c index 9283a5a53005..54eae0b5be7c 100644 --- a/subversion/libsvn_ra_serf/inherited_props.c +++ b/subversion/libsvn_ra_serf/inherited_props.c @@ -332,7 +332,7 @@ svn_ra_serf__get_inherited_props(svn_ra_session_t *ra_session, err = svn_ra_serf__context_run_one(handler, scratch_pool); SVN_ERR(svn_error_compose_create( - svn_ra_serf__error_on_status(handler->sline.code, + svn_ra_serf__error_on_status(handler->sline, handler->path, handler->location), err)); diff --git a/subversion/libsvn_ra_serf/log.c b/subversion/libsvn_ra_serf/log.c index e44753b07ae6..58a57d890ee4 100644 --- a/subversion/libsvn_ra_serf/log.c +++ b/subversion/libsvn_ra_serf/log.c @@ -595,7 +595,7 @@ svn_ra_serf__get_log(svn_ra_session_t *ra_session, err = svn_ra_serf__context_run_one(handler, pool); SVN_ERR(svn_error_compose_create( - svn_ra_serf__error_on_status(handler->sline.code, + svn_ra_serf__error_on_status(handler->sline, req_url, handler->location), err)); diff --git a/subversion/libsvn_ra_serf/mergeinfo.c b/subversion/libsvn_ra_serf/mergeinfo.c index b0bf8337cdfd..bd4fcbab5e7b 100644 --- a/subversion/libsvn_ra_serf/mergeinfo.c +++ b/subversion/libsvn_ra_serf/mergeinfo.c @@ -191,7 +191,7 @@ svn_ra_serf__get_mergeinfo(svn_ra_session_t *ra_session, svn_boolean_t include_descendants, apr_pool_t *pool) { - svn_error_t *err, *err2; + svn_error_t *err; mergeinfo_context_t *mergeinfo_ctx; svn_ra_serf__session_t *session = ra_session->priv; svn_ra_serf__handler_t *handler; @@ -229,15 +229,10 @@ svn_ra_serf__get_mergeinfo(svn_ra_session_t *ra_session, err = svn_ra_serf__context_run_one(handler, pool); - err2 = svn_ra_serf__error_on_status(handler->sline.code, handler->path, - handler->location); - if (err2) - { - svn_error_clear(err); - return err2; - } - - SVN_ERR(err); + SVN_ERR(svn_error_compose_create( + svn_ra_serf__error_on_status(handler->sline, handler->path, + handler->location), + err)); if (handler->done && apr_hash_count(mergeinfo_ctx->result_catalog)) *catalog = mergeinfo_ctx->result_catalog; diff --git a/subversion/libsvn_ra_serf/options.c b/subversion/libsvn_ra_serf/options.c index 0af0b1599c6d..a3c2fb95c881 100644 --- a/subversion/libsvn_ra_serf/options.c +++ b/subversion/libsvn_ra_serf/options.c @@ -362,6 +362,8 @@ options_response_handler(serf_request_t *request, capability_no); svn_hash_sets(session->capabilities, SVN_RA_CAPABILITY_EPHEMERAL_TXNPROPS, capability_no); + svn_hash_sets(session->capabilities, SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE, + capability_no); /* Then see which ones we can discover. */ serf_bucket_headers_do(hdrs, capabilities_headers_iterator_callback, @@ -436,11 +438,12 @@ svn_ra_serf__v2_get_youngest_revnum(svn_revnum_t *youngest, SVN_ERR(create_options_req(&opt_ctx, session, conn, scratch_pool)); SVN_ERR(svn_ra_serf__context_run_one(opt_ctx->handler, scratch_pool)); - SVN_ERR(svn_ra_serf__error_on_status(opt_ctx->handler->sline.code, + SVN_ERR(svn_ra_serf__error_on_status(opt_ctx->handler->sline, opt_ctx->handler->path, opt_ctx->handler->location)); *youngest = opt_ctx->youngest_rev; + SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(*youngest)); return SVN_NO_ERROR; } @@ -460,7 +463,7 @@ svn_ra_serf__v1_get_activity_collection(const char **activity_url, SVN_ERR(create_options_req(&opt_ctx, session, conn, scratch_pool)); SVN_ERR(svn_ra_serf__context_run_one(opt_ctx->handler, scratch_pool)); - SVN_ERR(svn_ra_serf__error_on_status(opt_ctx->handler->sline.code, + SVN_ERR(svn_ra_serf__error_on_status(opt_ctx->handler->sline, opt_ctx->handler->path, opt_ctx->handler->location)); @@ -499,7 +502,7 @@ svn_ra_serf__exchange_capabilities(svn_ra_serf__session_t *serf_sess, } SVN_ERR(svn_error_compose_create( - svn_ra_serf__error_on_status(opt_ctx->handler->sline.code, + svn_ra_serf__error_on_status(opt_ctx->handler->sline, serf_sess->session_url.path, opt_ctx->handler->location), err)); @@ -517,6 +520,65 @@ svn_ra_serf__exchange_capabilities(svn_ra_serf__session_t *serf_sess, } +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, diff --git a/subversion/libsvn_ra_serf/property.c b/subversion/libsvn_ra_serf/property.c index 63972e8597f1..586d38ff46ca 100644 --- a/subversion/libsvn_ra_serf/property.c +++ b/subversion/libsvn_ra_serf/property.c @@ -635,7 +635,7 @@ svn_ra_serf__wait_for_props(svn_ra_serf__handler_t *handler, err = svn_ra_serf__context_run_one(handler, scratch_pool); - err2 = svn_ra_serf__error_on_status(handler->sline.code, + err2 = svn_ra_serf__error_on_status(handler->sline, handler->path, handler->location); diff --git a/subversion/libsvn_ra_serf/ra_serf.h b/subversion/libsvn_ra_serf/ra_serf.h index 3f3f3ded05af..f6310b351dc7 100644 --- a/subversion/libsvn_ra_serf/ra_serf.h +++ b/subversion/libsvn_ra_serf/ra_serf.h @@ -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_info_t **commit_info, /** 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. @@ -1744,7 +1759,7 @@ svn_ra_serf__credentials_callback(char **username, char **password, * where it necessary. */ svn_error_t * -svn_ra_serf__error_on_status(int status_code, +svn_ra_serf__error_on_status(serf_status_line sline, const char *path, const char *location); diff --git a/subversion/libsvn_ra_serf/replay.c b/subversion/libsvn_ra_serf/replay.c index 1fcecf43f878..2d385f345f36 100644 --- a/subversion/libsvn_ra_serf/replay.c +++ b/subversion/libsvn_ra_serf/replay.c @@ -696,7 +696,7 @@ svn_ra_serf__replay(svn_ra_session_t *ra_session, err = svn_ra_serf__context_run_wait(&replay_ctx->done, session, pool); SVN_ERR(svn_error_compose_create( - svn_ra_serf__error_on_status(handler->sline.code, + svn_ra_serf__error_on_status(handler->sline, handler->path, handler->location), err)); @@ -905,7 +905,7 @@ svn_ra_serf__replay_range(svn_ra_session_t *ra_session, svn_ra_serf__handler_t *done_handler = ctx->report_handler; done_list = done_list->next; - SVN_ERR(svn_ra_serf__error_on_status(done_handler->sline.code, + SVN_ERR(svn_ra_serf__error_on_status(done_handler->sline, done_handler->path, done_handler->location)); svn_pool_destroy(ctx->src_rev_pool); diff --git a/subversion/libsvn_ra_serf/serf.c b/subversion/libsvn_ra_serf/serf.c index 601615738043..b0b6346c5a92 100644 --- a/subversion/libsvn_ra_serf/serf.c +++ b/subversion/libsvn_ra_serf/serf.c @@ -137,6 +137,10 @@ load_http_auth_types(apr_pool_t *pool, svn_config_t *config, 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 *session, 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 *session, 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 *session, 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 *session, 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)); @@ -392,6 +427,7 @@ svn_ra_serf__open(svn_ra_session_t *session, svn_ra_serf__session_t *serf_sess; apr_uri_t url; const char *client_string = NULL; + svn_error_t *err; if (corrected_url) *corrected_url = NULL; @@ -441,6 +477,10 @@ svn_ra_serf__open(svn_ra_session_t *session, 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, @@ -479,7 +519,23 @@ svn_ra_serf__open(svn_ra_session_t *session, session->priv = serf_sess; - return svn_ra_serf__exchange_capabilities(serf_sess, corrected_url, pool); + err = svn_ra_serf__exchange_capabilities(serf_sess, corrected_url, pool); + + /* serf should produce a usable error code instead of APR_EGENERAL */ + 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 (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(). */ diff --git a/subversion/libsvn_ra_serf/update.c b/subversion/libsvn_ra_serf/update.c index 21ed2dfc9cd9..06a16c06effd 100644 --- a/subversion/libsvn_ra_serf/update.c +++ b/subversion/libsvn_ra_serf/update.c @@ -1268,7 +1268,7 @@ handle_stream(serf_request_t *request, /* ### new field. make sure we didn't miss some initialization. */ SVN_ERR_ASSERT(fetch_ctx->handler != NULL); - err = svn_ra_serf__error_on_status(fetch_ctx->handler->sline.code, + err = svn_ra_serf__error_on_status(fetch_ctx->handler->sline, fetch_ctx->info->name, fetch_ctx->handler->location); if (err) @@ -2739,7 +2739,7 @@ setup_update_report_headers(serf_bucket_t *headers, if (report->sess->using_compression) { serf_bucket_headers_setn(headers, "Accept-Encoding", - "gzip;svndiff1;q=0.9,svndiff;q=0.8"); + "gzip,svndiff1;q=0.9,svndiff;q=0.8"); } else { @@ -2891,7 +2891,7 @@ finish_report(void *report_baton, { return svn_error_trace( svn_error_compose_create( - svn_ra_serf__error_on_status(handler->sline.code, + svn_ra_serf__error_on_status(handler->sline, handler->path, handler->location), err)); diff --git a/subversion/libsvn_ra_serf/util.c b/subversion/libsvn_ra_serf/util.c index c7a171627e2b..ce1e31a94c8a 100644 --- a/subversion/libsvn_ra_serf/util.c +++ b/subversion/libsvn_ra_serf/util.c @@ -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, @@ -477,7 +475,7 @@ connection_closed(svn_ra_serf__connection_t *conn, { if (why) { - SVN_ERR_MALFUNCTION(); + return svn_error_wrap_apr(why, NULL); } if (conn->session->using_ssl) @@ -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) { @@ -2390,17 +2385,17 @@ svn_ra_serf__report_resource(const char **report_target, } svn_error_t * -svn_ra_serf__error_on_status(int status_code, +svn_ra_serf__error_on_status(serf_status_line sline, const char *path, const char *location) { - switch(status_code) + switch(sline.code) { case 301: case 302: case 307: return svn_error_createf(SVN_ERR_RA_DAV_RELOCATED, NULL, - (status_code == 301) + (sline.code == 301) ? _("Repository moved permanently to '%s';" " please relocate") : _("Repository moved temporarily to '%s';" @@ -2415,8 +2410,20 @@ svn_ra_serf__error_on_status(int status_code, case 423: return svn_error_createf(SVN_ERR_FS_NO_LOCK_TOKEN, NULL, _("'%s': no lock token available"), path); + + case 411: + return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL, + _("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) + return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL, + _("Unexpected HTTP status %d '%s' on '%s'\n"), + sline.code, sline.reason, path); + return SVN_NO_ERROR; } diff --git a/subversion/libsvn_ra_serf/xml.c b/subversion/libsvn_ra_serf/xml.c index 95017d5e3be4..a95eaccd2199 100644 --- a/subversion/libsvn_ra_serf/xml.c +++ b/subversion/libsvn_ra_serf/xml.c @@ -615,6 +615,14 @@ svn_ra_serf__xml_cb_start(svn_ra_serf__xml_context_t *xmlctx, } if (scan->ns == NULL) { + if (current->state == 0) + { + return svn_error_createf( + SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, + _("XML Parsing failed: Unexpected root element '%s'"), + elemname.name); + } + xmlctx->waiting = elemname; /* ### return? */ return SVN_NO_ERROR; |