char *get_user_agent() { char *uagent_str = DA_NULL; DA_LOG_FUNC_START(Default); uagent_str = get_client_user_agent_string(); if (!uagent_str) { da_result_t ret = DA_RESULT_OK; ret = get_user_agent_string(&uagent_str); if (ret != DA_RESULT_OK) return NULL; } return uagent_str; }
/* Implements svn_ra__vtable_t.open_session(). */ static svn_error_t * svn_ra_serf__open(svn_ra_session_t *session, const char **corrected_url, const char *session_URL, const svn_ra_callbacks2_t *callbacks, void *callback_baton, svn_auth_baton_t *auth_baton, apr_hash_t *config, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { apr_status_t status; 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; serf_sess = apr_pcalloc(result_pool, sizeof(*serf_sess)); serf_sess->pool = result_pool; if (config) SVN_ERR(svn_config_copy_config(&serf_sess->config, config, result_pool)); else serf_sess->config = NULL; serf_sess->wc_callbacks = callbacks; serf_sess->wc_callback_baton = callback_baton; serf_sess->auth_baton = auth_baton; serf_sess->progress_func = callbacks->progress_func; serf_sess->progress_baton = callbacks->progress_baton; serf_sess->cancel_func = callbacks->cancel_func; serf_sess->cancel_baton = callback_baton; /* todo: reuse serf context across sessions */ serf_sess->context = serf_context_create(serf_sess->pool); SVN_ERR(svn_ra_serf__blncache_create(&serf_sess->blncache, serf_sess->pool)); SVN_ERR(svn_ra_serf__uri_parse(&url, session_URL, serf_sess->pool)); if (!url.port) { url.port = apr_uri_port_of_scheme(url.scheme); } serf_sess->session_url = url; serf_sess->session_url_str = apr_pstrdup(serf_sess->pool, session_URL); serf_sess->using_ssl = (svn_cstring_casecmp(url.scheme, "https") == 0); serf_sess->supports_deadprop_count = svn_tristate_unknown; serf_sess->capabilities = apr_hash_make(serf_sess->pool); /* We have to assume that the server only supports HTTP/1.0. Once it's clear 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, sizeof(*serf_sess->conns[0])); serf_sess->conns[0]->bkt_alloc = serf_bucket_allocator_create(serf_sess->pool, NULL, NULL); serf_sess->conns[0]->session = serf_sess; serf_sess->conns[0]->last_status_code = -1; /* create the user agent string */ if (callbacks->get_client_string) SVN_ERR(callbacks->get_client_string(callback_baton, &client_string, scratch_pool)); if (client_string) serf_sess->useragent = apr_pstrcat(result_pool, get_user_agent_string(scratch_pool), " ", client_string, SVN_VA_NULL); else serf_sess->useragent = get_user_agent_string(result_pool); /* go ahead and tell serf about the connection. */ status = serf_connection_create2(&serf_sess->conns[0]->conn, serf_sess->context, url, svn_ra_serf__conn_setup, serf_sess->conns[0], svn_ra_serf__conn_closed, serf_sess->conns[0], serf_sess->pool); if (status) return svn_ra_serf__wrap_err(status, NULL); /* Set the progress callback. */ serf_context_set_progress_cb(serf_sess->context, svn_ra_serf__progress, serf_sess); serf_sess->num_conns = 1; session->priv = serf_sess; /* The following code explicitly works around a bug in serf <= r2319 / 1.3.8 where serf doesn't report the request as failed/cancelled when the authorization request handler fails to handle the request. As long as we allocate the request in a subpool of the serf connection pool, we know that the handler is always cleaned before the connection. Luckily our caller now passes us two pools which handle this case. */ #if defined(SVN_DEBUG) && !SERF_VERSION_AT_LEAST(1,4,0) /* Currently ensured by svn_ra_open4(). If failing causes segfault in basic_tests.py 48, "basic auth test" */ SVN_ERR_ASSERT((serf_sess->pool != scratch_pool) && apr_pool_is_ancestor(serf_sess->pool, scratch_pool)); #endif err = svn_ra_serf__exchange_capabilities(serf_sess, corrected_url, result_pool, scratch_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, scratch_pool)); return SVN_NO_ERROR; }