diff --git a/include/sentry.h b/include/sentry.h index 43203151a..03f1bb641 100644 --- a/include/sentry.h +++ b/include/sentry.h @@ -1253,6 +1253,12 @@ SENTRY_API uint64_t sentry_options_get_shutdown_timeout(sentry_options_t *opts); SENTRY_API void sentry_options_set_backend( sentry_options_t *opts, sentry_backend_t *backend); +/** + * Sets a user-defined user-agent. + */ +SENTRY_API void sentry_options_set_app_user_agent( + sentry_options_t *opts, const char *app_user_agent); + /* -- Global APIs -- */ /** diff --git a/src/sentry_options.c b/src/sentry_options.c index 014ec491f..eee135b0a 100644 --- a/src/sentry_options.c +++ b/src/sentry_options.c @@ -87,6 +87,7 @@ sentry_options_free(sentry_options_t *opts) sentry_free(opts->release); sentry_free(opts->sdk_name); sentry_free(opts->user_agent); + sentry_free(opts->app_user_agent); sentry_free(opts->environment); sentry_free(opts->dist); sentry_free(opts->http_proxy); @@ -594,3 +595,11 @@ sentry_options_set_backend(sentry_options_t *opts, sentry_backend_t *backend) sentry__backend_free(opts->backend); opts->backend = backend; } + +void +sentry_options_set_app_user_agent( + sentry_options_t *opts, const char *app_user_agent) +{ + sentry_free(opts->app_user_agent); + opts->app_user_agent = sentry__string_clone(app_user_agent); +} diff --git a/src/sentry_options.h b/src/sentry_options.h index 060b17f70..0d80e916f 100644 --- a/src/sentry_options.h +++ b/src/sentry_options.h @@ -40,6 +40,7 @@ typedef struct sentry_options_s { char *transport_thread_name; char *sdk_name; char *user_agent; + char *app_user_agent; sentry_path_t *database_path; sentry_path_t *handler_path; sentry_logger_t logger; diff --git a/src/transports/sentry_transport_curl.c b/src/transports/sentry_transport_curl.c index 11f87e5d2..bbb2d4e0d 100644 --- a/src/transports/sentry_transport_curl.c +++ b/src/transports/sentry_transport_curl.c @@ -203,6 +203,7 @@ sentry__curl_send_task(void *_envelope, void *_state) curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req->body); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)req->body_len); + // TODO: curl 支持 app_user_agent curl_easy_setopt(curl, CURLOPT_USERAGENT, SENTRY_SDK_USER_AGENT); char error_buf[CURL_ERROR_SIZE]; diff --git a/src/transports/sentry_transport_winhttp.c b/src/transports/sentry_transport_winhttp.c index ffb114eb9..40d5c8f04 100644 --- a/src/transports/sentry_transport_winhttp.c +++ b/src/transports/sentry_transport_winhttp.c @@ -64,6 +64,15 @@ sentry__winhttp_transport_start( state->dsn = sentry__dsn_incref(opts->dsn); state->user_agent = sentry__string_to_wstr(opts->user_agent); + wchar_t *full_user_agent = state->user_agent; + bool user_agent_owned = false; + if (opts->app_user_agent) { + char user_agent[255]; + snprintf(user_agent, sizeof(user_agent), "%s %s", opts->app_user_agent, + opts->user_agent); + full_user_agent = sentry__string_to_wstr(user_agent); + user_agent_owned = true; + } state->debug = opts->debug; sentry__bgworker_setname(bgworker, opts->transport_thread_name); @@ -84,22 +93,25 @@ sentry__winhttp_transport_start( if (state->proxy) { state->session - = WinHttpOpen(state->user_agent, WINHTTP_ACCESS_TYPE_NAMED_PROXY, + = WinHttpOpen(full_user_agent, WINHTTP_ACCESS_TYPE_NAMED_PROXY, state->proxy, WINHTTP_NO_PROXY_BYPASS, 0); } else { #if _WIN32_WINNT >= 0x0603 - state->session = WinHttpOpen(state->user_agent, + state->session = WinHttpOpen(full_user_agent, WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); #endif // On windows 8.0 or lower, WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY does // not work on error we fallback to WINHTTP_ACCESS_TYPE_DEFAULT_PROXY if (!state->session) { - state->session = WinHttpOpen(state->user_agent, + state->session = WinHttpOpen(full_user_agent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); } } + if (user_agent_owned) { + sentry_free(full_user_agent); + } if (!state->session) { SENTRY_WARN("`WinHttpOpen` failed"); return 1;