[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] custom useragent string

From: Stefan Küng <tortoisesvn_at_gmail.com>
Date: 2007-12-20 22:19:46 CET

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

This is an archived mail posted to the Subversion Dev mailing list.