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;
}
Пример #2
0
/* 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;
}