Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ecdc042

Browse files
committed
Merge pull request libgit2#3448 from libgit2/cmn/custom-agent
Support setting custom user-agent
2 parents 3f5877d + 027bbaa commit ecdc042

File tree

8 files changed

+86
-3
lines changed

8 files changed

+86
-3
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ v0.23 + 1
1010
* Symlinks are now followed when locking a file, which can be
1111
necessary when multiple worktrees share a base repository.
1212

13+
* You can now set your own user-agent to be sent for HTTP requests by
14+
using the `GIT_OPT_SET_USER_AGENT` with `git_libgit2_opts()`.
15+
1316
### API additions
1417

1518
* `git_config_lock()` has been added, which allow for

include/git2/common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ typedef enum {
145145
GIT_OPT_GET_TEMPLATE_PATH,
146146
GIT_OPT_SET_TEMPLATE_PATH,
147147
GIT_OPT_SET_SSL_CERT_LOCATIONS,
148+
GIT_OPT_SET_USER_AGENT,
148149
} git_libgit2_opt_t;
149150

150151
/**
@@ -240,6 +241,8 @@ typedef enum {
240241
* >
241242
* > Either parameter may be `NULL`, but not both.
242243
*
244+
* * opts(GIT_OPT_SET_USER_AGENT, const char *user_agent)
245+
*
243246
* @param option Option key
244247
* @param ... value to set the option
245248
* @return 0 on success, <0 on failure

src/global.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ static git_mutex *openssl_locks;
3131
static git_global_shutdown_fn git__shutdown_callbacks[MAX_SHUTDOWN_CB];
3232
static git_atomic git__n_shutdown_callbacks;
3333
static git_atomic git__n_inits;
34+
char *git__user_agent;
3435

3536
void git__on_shutdown(git_global_shutdown_fn callback)
3637
{
@@ -269,6 +270,8 @@ int git_libgit2_shutdown(void)
269270
git_win32__crtdbg_stacktrace_cleanup();
270271
git_win32__stack_cleanup();
271272
#endif
273+
274+
git__free(git__user_agent);
272275
}
273276

274277
/* Exit the lock */
@@ -369,6 +372,7 @@ int git_libgit2_shutdown(void)
369372

370373
git__global_state_cleanup(ptr);
371374
git__free(ptr);
375+
git__free(git__user_agent);
372376

373377
pthread_key_delete(_tls_key);
374378
git_mutex_free(&git__mwindow_mutex);
@@ -423,6 +427,7 @@ int git_libgit2_shutdown(void)
423427
git__shutdown();
424428
git__global_state_cleanup(&__state);
425429
uninit_ssl();
430+
git__free(git__user_agent);
426431

427432
return 0;
428433
}

src/global.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,6 @@ extern void git__on_shutdown(git_global_shutdown_fn callback);
3535

3636
extern void git__free_tls_data(void);
3737

38+
extern const char *git_libgit2__user_agent(void);
39+
3840
#endif

src/settings.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ static int config_level_to_sysdir(int config_level)
5757
return val;
5858
}
5959

60+
extern char *git__user_agent;
61+
62+
const char *git_libgit2__user_agent()
63+
{
64+
return git__user_agent;
65+
}
66+
6067
int git_libgit2_opts(int key, ...)
6168
{
6269
int error = 0;
@@ -152,6 +159,15 @@ int git_libgit2_opts(int key, ...)
152159
giterr_set(GITERR_NET, "Cannot set certificate locations: OpenSSL is not enabled");
153160
error = -1;
154161
#endif
162+
break;
163+
case GIT_OPT_SET_USER_AGENT:
164+
git__free(git__user_agent);
165+
git__user_agent = git__strdup(va_arg(ap, const char *));
166+
if (!git__user_agent) {
167+
giterr_set_oom();
168+
error = -1;
169+
}
170+
155171
break;
156172
}
157173

src/transports/http.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "http_parser.h"
1111
#include "buffer.h"
1212
#include "netops.h"
13+
#include "global.h"
1314
#include "remote.h"
1415
#include "smart.h"
1516
#include "auth.h"
@@ -186,6 +187,16 @@ static int apply_credentials(git_buf *buf, http_subtransport *t)
186187
return context->next_token(buf, context, cred);
187188
}
188189

190+
static const char *user_agent(void)
191+
{
192+
const char *custom = git_libgit2__user_agent();
193+
194+
if (custom)
195+
return custom;
196+
197+
return "libgit2 " LIBGIT2_VERSION;
198+
}
199+
189200
static int gen_request(
190201
git_buf *buf,
191202
http_stream *s,
@@ -197,7 +208,7 @@ static int gen_request(
197208

198209
git_buf_printf(buf, "%s %s%s HTTP/1.1\r\n", s->verb, path, s->service_url);
199210

200-
git_buf_puts(buf, "User-Agent: git/1.0 (libgit2 " LIBGIT2_VERSION ")\r\n");
211+
git_buf_printf(buf, "User-Agent: git/1.0 (%s)\r\n", user_agent());
201212
git_buf_printf(buf, "Host: %s\r\n", t->connection_data.host);
202213

203214
if (s->chunked || content_length > 0) {

src/transports/winhttp.c

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "smart.h"
1616
#include "remote.h"
1717
#include "repository.h"
18+
#include "global.h"
1819

1920
#include <wincrypt.h>
2021
#include <winhttp.h>
@@ -567,12 +568,28 @@ static int winhttp_close_connection(winhttp_subtransport *t)
567568
return ret;
568569
}
569570

571+
static int user_agent(git_buf *ua)
572+
{
573+
const char *custom = git_libgit2__user_agent();
574+
575+
git_buf_clear(ua);
576+
git_buf_PUTS(ua, "git/1.0 (");
577+
578+
if (custom)
579+
git_buf_puts(ua, custom);
580+
else
581+
git_buf_PUTS(ua, "libgit2 " LIBGIT2_VERSION);
582+
583+
return git_buf_putc(ua, ')');
584+
}
585+
570586
static int winhttp_connect(
571587
winhttp_subtransport *t)
572588
{
573-
wchar_t *ua = L"git/1.0 (libgit2 " WIDEN(LIBGIT2_VERSION) L")";
574589
wchar_t *wide_host;
575590
int32_t port;
591+
wchar_t *wide_ua;
592+
git_buf ua = GIT_BUF_INIT;
576593
int error = -1;
577594
int default_timeout = TIMEOUT_INFINITE;
578595
int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT;
@@ -590,9 +607,23 @@ static int winhttp_connect(
590607
return -1;
591608
}
592609

610+
if ((error = user_agent(&ua)) < 0) {
611+
git__free(wide_host);
612+
return error;
613+
}
614+
615+
if (git__utf8_to_16_alloc(&wide_ua, git_buf_cstr(&ua)) < 0) {
616+
giterr_set(GITERR_OS, "Unable to convert host to wide characters");
617+
git__free(wide_host);
618+
git_buf_free(&ua);
619+
return -1;
620+
}
621+
622+
git_buf_free(&ua);
623+
593624
/* Establish session */
594625
t->session = WinHttpOpen(
595-
ua,
626+
wide_ua,
596627
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
597628
WINHTTP_NO_PROXY_NAME,
598629
WINHTTP_NO_PROXY_BYPASS,
@@ -628,6 +659,7 @@ static int winhttp_connect(
628659
winhttp_close_connection(t);
629660

630661
git__free(wide_host);
662+
git__free(wide_ua);
631663

632664
return error;
633665
}

tests/core/useragent.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "clar_libgit2.h"
2+
#include "global.h"
3+
4+
void test_core_useragent__get(void)
5+
{
6+
const char *custom_name = "super duper git";
7+
8+
cl_assert_equal_p(NULL, git_libgit2__user_agent());
9+
cl_git_pass(git_libgit2_opts(GIT_OPT_SET_USER_AGENT, custom_name));
10+
cl_assert_equal_s(custom_name, git_libgit2__user_agent());
11+
}

0 commit comments

Comments
 (0)