diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2015-11-12 19:20:36 +0100 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2015-11-12 19:20:36 +0100 |
commit | ecdc04287a9a245b9947aee21a86dc2f09a1bdcf (patch) | |
tree | 8ea8e1d8f8235a26e22b578b2eba37572e43d82a | |
parent | 3f5877d18f0385044a5fffc579582bbeed296d32 (diff) | |
parent | 027bbaa72145c81b0d57b74bb9cf8fc9cb70db11 (diff) | |
download | libgit2-ecdc04287a9a245b9947aee21a86dc2f09a1bdcf.tar.gz |
Merge pull request #3448 from libgit2/cmn/custom-agent
Support setting custom user-agent
-rw-r--r-- | CHANGELOG.md | 3 | ||||
-rw-r--r-- | include/git2/common.h | 3 | ||||
-rw-r--r-- | src/global.c | 5 | ||||
-rw-r--r-- | src/global.h | 2 | ||||
-rw-r--r-- | src/settings.c | 16 | ||||
-rw-r--r-- | src/transports/http.c | 13 | ||||
-rw-r--r-- | src/transports/winhttp.c | 36 | ||||
-rw-r--r-- | tests/core/useragent.c | 11 |
8 files changed, 86 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 359e78dbd..7d5a4166a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ v0.23 + 1 * Symlinks are now followed when locking a file, which can be necessary when multiple worktrees share a base repository. +* You can now set your own user-agent to be sent for HTTP requests by + using the `GIT_OPT_SET_USER_AGENT` with `git_libgit2_opts()`. + ### API additions * `git_config_lock()` has been added, which allow for diff --git a/include/git2/common.h b/include/git2/common.h index 577906115..bf341e79f 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -145,6 +145,7 @@ typedef enum { GIT_OPT_GET_TEMPLATE_PATH, GIT_OPT_SET_TEMPLATE_PATH, GIT_OPT_SET_SSL_CERT_LOCATIONS, + GIT_OPT_SET_USER_AGENT, } git_libgit2_opt_t; /** @@ -240,6 +241,8 @@ typedef enum { * > * > Either parameter may be `NULL`, but not both. * + * * opts(GIT_OPT_SET_USER_AGENT, const char *user_agent) + * * @param option Option key * @param ... value to set the option * @return 0 on success, <0 on failure diff --git a/src/global.c b/src/global.c index 3d37ee4de..0eab8d552 100644 --- a/src/global.c +++ b/src/global.c @@ -31,6 +31,7 @@ static git_mutex *openssl_locks; static git_global_shutdown_fn git__shutdown_callbacks[MAX_SHUTDOWN_CB]; static git_atomic git__n_shutdown_callbacks; static git_atomic git__n_inits; +char *git__user_agent; void git__on_shutdown(git_global_shutdown_fn callback) { @@ -269,6 +270,8 @@ int git_libgit2_shutdown(void) git_win32__crtdbg_stacktrace_cleanup(); git_win32__stack_cleanup(); #endif + + git__free(git__user_agent); } /* Exit the lock */ @@ -369,6 +372,7 @@ int git_libgit2_shutdown(void) git__global_state_cleanup(ptr); git__free(ptr); + git__free(git__user_agent); pthread_key_delete(_tls_key); git_mutex_free(&git__mwindow_mutex); @@ -423,6 +427,7 @@ int git_libgit2_shutdown(void) git__shutdown(); git__global_state_cleanup(&__state); uninit_ssl(); + git__free(git__user_agent); return 0; } diff --git a/src/global.h b/src/global.h index 37e909ac6..9fdcee573 100644 --- a/src/global.h +++ b/src/global.h @@ -35,4 +35,6 @@ extern void git__on_shutdown(git_global_shutdown_fn callback); extern void git__free_tls_data(void); +extern const char *git_libgit2__user_agent(void); + #endif diff --git a/src/settings.c b/src/settings.c index 2097ca314..030d28537 100644 --- a/src/settings.c +++ b/src/settings.c @@ -57,6 +57,13 @@ static int config_level_to_sysdir(int config_level) return val; } +extern char *git__user_agent; + +const char *git_libgit2__user_agent() +{ + return git__user_agent; +} + int git_libgit2_opts(int key, ...) { int error = 0; @@ -153,6 +160,15 @@ int git_libgit2_opts(int key, ...) error = -1; #endif break; + case GIT_OPT_SET_USER_AGENT: + git__free(git__user_agent); + git__user_agent = git__strdup(va_arg(ap, const char *)); + if (!git__user_agent) { + giterr_set_oom(); + error = -1; + } + + break; } va_end(ap); diff --git a/src/transports/http.c b/src/transports/http.c index e5f2b9f28..88b124bf7 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -10,6 +10,7 @@ #include "http_parser.h" #include "buffer.h" #include "netops.h" +#include "global.h" #include "remote.h" #include "smart.h" #include "auth.h" @@ -186,6 +187,16 @@ static int apply_credentials(git_buf *buf, http_subtransport *t) return context->next_token(buf, context, cred); } +static const char *user_agent(void) +{ + const char *custom = git_libgit2__user_agent(); + + if (custom) + return custom; + + return "libgit2 " LIBGIT2_VERSION; +} + static int gen_request( git_buf *buf, http_stream *s, @@ -197,7 +208,7 @@ static int gen_request( git_buf_printf(buf, "%s %s%s HTTP/1.1\r\n", s->verb, path, s->service_url); - git_buf_puts(buf, "User-Agent: git/1.0 (libgit2 " LIBGIT2_VERSION ")\r\n"); + git_buf_printf(buf, "User-Agent: git/1.0 (%s)\r\n", user_agent()); git_buf_printf(buf, "Host: %s\r\n", t->connection_data.host); if (s->chunked || content_length > 0) { diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index b364e906e..77d939bd3 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -15,6 +15,7 @@ #include "smart.h" #include "remote.h" #include "repository.h" +#include "global.h" #include <wincrypt.h> #include <winhttp.h> @@ -567,12 +568,28 @@ static int winhttp_close_connection(winhttp_subtransport *t) return ret; } +static int user_agent(git_buf *ua) +{ + const char *custom = git_libgit2__user_agent(); + + git_buf_clear(ua); + git_buf_PUTS(ua, "git/1.0 ("); + + if (custom) + git_buf_puts(ua, custom); + else + git_buf_PUTS(ua, "libgit2 " LIBGIT2_VERSION); + + return git_buf_putc(ua, ')'); +} + static int winhttp_connect( winhttp_subtransport *t) { - wchar_t *ua = L"git/1.0 (libgit2 " WIDEN(LIBGIT2_VERSION) L")"; wchar_t *wide_host; int32_t port; + wchar_t *wide_ua; + git_buf ua = GIT_BUF_INIT; int error = -1; int default_timeout = TIMEOUT_INFINITE; int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT; @@ -590,9 +607,23 @@ static int winhttp_connect( return -1; } + if ((error = user_agent(&ua)) < 0) { + git__free(wide_host); + return error; + } + + if (git__utf8_to_16_alloc(&wide_ua, git_buf_cstr(&ua)) < 0) { + giterr_set(GITERR_OS, "Unable to convert host to wide characters"); + git__free(wide_host); + git_buf_free(&ua); + return -1; + } + + git_buf_free(&ua); + /* Establish session */ t->session = WinHttpOpen( - ua, + wide_ua, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, @@ -628,6 +659,7 @@ on_error: winhttp_close_connection(t); git__free(wide_host); + git__free(wide_ua); return error; } diff --git a/tests/core/useragent.c b/tests/core/useragent.c new file mode 100644 index 000000000..6d06693a8 --- /dev/null +++ b/tests/core/useragent.c @@ -0,0 +1,11 @@ +#include "clar_libgit2.h" +#include "global.h" + +void test_core_useragent__get(void) +{ + const char *custom_name = "super duper git"; + + cl_assert_equal_p(NULL, git_libgit2__user_agent()); + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_USER_AGENT, custom_name)); + cl_assert_equal_s(custom_name, git_libgit2__user_agent()); +} |