Hi,
Since my last patch got reverted because I broke the build with it (btw:
sorry for that), here's a better one which uses a callback to pull the
client string instead of using a static variable.
Stefan
--
___
oo // \\ "De Chelonian Mobile"
(_,\/ \_/ \ TortoiseSVN
\ \_/_\_/> The coolest Interface to (Sub)Version Control
/_/ \_\ http://tortoisesvn.net
[[[
Better implementation of the clientstring feature which was first
introduced in r28503 but reverted in r28513 due to a circular
dependency.
The new implementation uses a callback to pull the string from the
client instead of using a static string.
* subversion/include/svn_client.h : new member variable in
svn_client_ctx_t
* subversion/include/svn_ra.h : callback function typedef
(svn_ra_callbacks2_t) : new member variable
* subversion/libsvn_client/ra.c
(get_client_string) : new function
(svn_client__open_ra_session_internal) : copy member variable
* subversion/libsvn_ra_neon/session.c
(svn_ra_neon__open) : use the client string in the useragent string
* subversion/libsvn_ra_serf/propfind_buckets.c
(create_propfind_body) : use the client string in the useragent string
* subversion/libsvn_ra_serf/ra_serf.h : new member variable in
svn_ra_serf__connection_t
* subversion/libsvn_ra_serf/serf.c
(svn_ra_serf__open) : create the useragent string with the client
string
* subversion/libsvn_ra_serf/util.c
(svn_ra_serf__setup_serf_req) : pass the dynamic useragent string
]]]
Index: subversion/include/svn_client.h
===================================================================
--- subversion/include/svn_client.h (revision 28596)
+++ subversion/include/svn_client.h (working copy)
@@ -857,6 +857,10 @@
svn_wc_conflict_resolver_func_t conflict_func;
void *conflict_baton;
+ /** Custom client name string, or @c null.
+ * @since New in 1.5. */
+ const char *client_name;
+
} svn_client_ctx_t;
/** @} end group: Client context management */
Index: subversion/include/svn_ra.h
===================================================================
--- subversion/include/svn_ra.h (revision 28596)
+++ subversion/include/svn_ra.h (working copy)
@@ -117,6 +117,16 @@
(void *session_baton,
svn_revnum_t *latest_revnum);
+/** A function type which allows the RA layer to ask about any
+ * customizations to the client name string. This is primarily used
+ * by HTTP-based RA layers wishing to extend the string reported to
+ * Apache/mod_dav_svn via the User-agent HTTP header.
+ */
+typedef svn_error_t *(*svn_ra_get_client_string_func_t)(void *baton,
+ const char **name,
+ apr_pool_t *pool);
+
+
/**
* A callback function type for use in @c get_file_revs.
* @a baton is provided by the caller, @a path is the pathname of the file
@@ -488,6 +498,11 @@
*/
svn_cancel_func_t cancel_func;
+ /** Client string customization callback function
+ * @since New in 1.5
+ */
+ svn_ra_get_client_string_func_t get_client_string;
+
} svn_ra_callbacks2_t;
/** Similar to svn_ra_callbacks2_t, except that the progress
Index: subversion/libsvn_client/ra.c
===================================================================
--- subversion/libsvn_client/ra.c (revision 28596)
+++ subversion/libsvn_client/ra.c (working copy)
@@ -268,6 +268,19 @@
return (b->ctx->cancel_func)(b->ctx->cancel_baton);
}
+
+static svn_error_t *
+get_client_string(void *baton,
+ const char **name,
+ apr_pool_t *pool)
+{
+ svn_client__callback_baton_t *b = baton;
+
+ *name = apr_pstrdup(pool, b->ctx->client_name);
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_client__open_ra_session_internal(svn_ra_session_t **ra_session,
const char *base_url,
@@ -291,6 +304,7 @@
cbtable->progress_func = ctx->progress_func;
cbtable->progress_baton = ctx->progress_baton;
cbtable->cancel_func = ctx->cancel_func ? cancel_callback : NULL;
+ cbtable->get_client_string = get_client_string;
cb->base_dir = base_dir;
cb->base_access = base_access;
Index: subversion/libsvn_ra_neon/session.c
===================================================================
--- subversion/libsvn_ra_neon/session.c (revision 28596)
+++ subversion/libsvn_ra_neon/session.c (working copy)
@@ -826,7 +826,27 @@
unsigned int neon_auth_types = 0;
neonprogress_baton_t *neonprogress_baton =
apr_pcalloc(pool, sizeof(*neonprogress_baton));
+ const char * useragent = NULL;
+ const char * client_string = NULL;
+ if (callbacks->get_client_string)
+ {
+ callbacks->get_client_string(callback_baton, &client_string, pool);
+ }
+ if (client_string)
+ {
+ useragent = apr_pstrcat(pool,
+ "SVN/",
+ SVN_VERSION,
+ "/",
+ client_string,
+ NULL);
+ }
+ else
+ {
+ useragent = "SVN/" SVN_VERSION;
+ }
+
/* Sanity check the URI */
SVN_ERR(parse_url(uri, repos_URL));
@@ -935,9 +955,16 @@
ne_set_read_timeout(sess2, timeout);
}
- ne_set_useragent(sess, "SVN/" SVN_VERSION);
- ne_set_useragent(sess2, "SVN/" SVN_VERSION);
-
+ if (useragent)
+ {
+ ne_set_useragent(sess, useragent);
+ ne_set_useragent(sess2, useragent);
+ }
+ else
+ {
+ ne_set_useragent(sess, "SVN/" SVN_VERSION);
+ ne_set_useragent(sess2, "SVN/" SVN_VERSION);
+ }
/* clean up trailing slashes from the URL */
len = strlen(uri->path);
if (len > 1 && (uri->path)[len - 1] == '/')
Index: subversion/libsvn_ra_serf/propfind_buckets.c
===================================================================
--- subversion/libsvn_ra_serf/propfind_buckets.c (revision 28596)
+++ subversion/libsvn_ra_serf/propfind_buckets.c (working copy)
@@ -158,7 +158,8 @@
hdrs_bkt = serf_bucket_request_get_headers(bucket);
serf_bucket_headers_setn(hdrs_bkt, "Host", ctx->conn->hostinfo);
- serf_bucket_headers_setn(hdrs_bkt, "User-Agent", USER_AGENT);
+ serf_bucket_headers_setn(hdrs_bkt, "User-Agent", ctx->conn->useragent);
+
if (ctx->conn->using_compression == TRUE)
{
serf_bucket_headers_setn(hdrs_bkt, "Accept-Encoding", "gzip");
Index: subversion/libsvn_ra_serf/ra_serf.h
===================================================================
--- subversion/libsvn_ra_serf/ra_serf.h (revision 28596)
+++ subversion/libsvn_ra_serf/ra_serf.h (working copy)
@@ -104,6 +104,9 @@
/* Current authorization value used for the proxy server; may be NULL */
char *proxy_auth_value;
+
+ /* user agent string */
+ const char *useragent;
} svn_ra_serf__connection_t;
Index: subversion/libsvn_ra_serf/serf.c
===================================================================
--- subversion/libsvn_ra_serf/serf.c (revision 28596)
+++ subversion/libsvn_ra_serf/serf.c (working copy)
@@ -379,6 +379,7 @@
apr_status_t status;
svn_ra_serf__session_t *serf_sess;
apr_uri_t url;
+ const char * client_string = NULL;
serf_sess = apr_pcalloc(pool, sizeof(*serf_sess));
apr_pool_create(&serf_sess->pool, pool);
@@ -441,7 +442,26 @@
serf_sess->conns[0]->hostinfo = url.hostinfo;
serf_sess->conns[0]->auth_header = NULL;
serf_sess->conns[0]->auth_value = NULL;
+ serf_sess->conns[0]->useragent = NULL;
+ /* create the user agent string */
+ if (callbacks->get_client_string)
+ {
+ callbacks->get_client_string(callback_baton, &client_string, pool);
+ }
+ if (client_string)
+ {
+ serf_sess->conns[0]->useragent = apr_pstrcat(pool,
+ USER_AGENT,
+ "/",
+ client_string,
+ NULL);
+ }
+ else
+ {
+ serf_sess->conns[0]->useragent = USER_AGENT;
+ }
+
/* go ahead and tell serf about the connection. */
serf_sess->conns[0]->conn =
serf_connection_create(serf_sess->context, serf_sess->conns[0]->address,
Index: subversion/libsvn_ra_serf/util.c
===================================================================
--- subversion/libsvn_ra_serf/util.c (revision 28596)
+++ subversion/libsvn_ra_serf/util.c (working copy)
@@ -271,7 +271,8 @@
hdrs_bkt = serf_bucket_request_get_headers(*req_bkt);
serf_bucket_headers_setn(hdrs_bkt, "Host", conn->hostinfo);
- serf_bucket_headers_setn(hdrs_bkt, "User-Agent", USER_AGENT);
+ serf_bucket_headers_setn(hdrs_bkt, "User-Agent", conn->useragent);
+
if (content_type)
{
serf_bucket_headers_setn(hdrs_bkt, "Content-Type", content_type);
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Thu Dec 20 22:20:02 2007