Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting sdk_name at runtime #834

Merged
merged 11 commits into from
Apr 28, 2023
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
**Features**:

- Extend API with ptr/len-string interfaces. ([#827](https://github.com/getsentry/sentry-native/pull/827))
- Allow setting sdk_name at runtime ([#834](https://github.com/getsentry/sentry-native/pull/834))

## 0.6.1

Expand Down
32 changes: 30 additions & 2 deletions include/sentry.h
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,32 @@ SENTRY_API void sentry_options_set_transport_thread_name_n(
SENTRY_API const char *sentry_options_get_transport_thread_name(
const sentry_options_t *opts);

/*
* Configures the name of the sentry SDK. Returns 0 on success.
*/
SENTRY_API int sentry_options_set_sdk_name(
sentry_options_t *opts, const char *sdk_name);

/*
* Configures the name of the sentry SDK. Returns 0 on success.
*/
SENTRY_API int sentry_options_set_sdk_name_n(
sentry_options_t *opts, const char *sdk_name, size_t sdk_name_len);

/**
* Returns the configured sentry SDK name. Unless overwritten this defaults to
* SENTRY_SDK_NAME.
*/
SENTRY_API const char *sentry_options_get_sdk_name(
const sentry_options_t *opts);

/**
* Returns the user agent. Unless overwritten this defaults to
* "SENTRY_SDK_NAME / SENTRY_SDK_VERSION".
*/
SENTRY_API const char *sentry_options_get_user_agent(
const sentry_options_t *opts);

/**
* Enables or disables debug printing mode.
*/
Expand Down Expand Up @@ -1983,12 +2009,14 @@ SENTRY_EXPERIMENTAL_API int sentry_clear_crashed_last_run(void);
SENTRY_EXPERIMENTAL_API const char *sentry_sdk_version(void);

/**
* Sentry SDK name.
* Sentry SDK name set during build time.
* Deprecated: Please use sentry_options_get_sdk_name instead.
*/
SENTRY_EXPERIMENTAL_API const char *sentry_sdk_name(void);

/**
* Sentry SDK User-Agent.
* Sentry SDK User-Agent set during build time.
* Deprecated: Please use sentry_options_get_user_agent instead.
*/
SENTRY_EXPERIMENTAL_API const char *sentry_sdk_user_agent(void);

Expand Down
3 changes: 2 additions & 1 deletion src/backends/sentry_backend_crashpad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,8 @@ sentry__crashpad_backend_startup(
data->db = crashpad::CrashReportDatabase::Initialize(database).release();

crashpad::CrashpadClient client;
char *minidump_url = sentry__dsn_get_minidump_url(options->dsn);
char *minidump_url
= sentry__dsn_get_minidump_url(options->dsn, options->user_agent);
SENTRY_TRACEF("using minidump url \"%s\"", minidump_url);
std::string url = minidump_url ? std::string(minidump_url) : std::string();
sentry_free(minidump_url);
Expand Down
48 changes: 48 additions & 0 deletions src/sentry_options.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ sentry_options_new(void)
if (!opts->environment) {
opts->environment = sentry__string_clone("production");
}
sentry_options_set_sdk_name(opts, SENTRY_SDK_NAME);
opts->max_breadcrumbs = SENTRY_BREADCRUMBS_MAX;
opts->user_consent = SENTRY_USER_CONSENT_UNKNOWN;
opts->auto_session_tracking = true;
Expand Down Expand Up @@ -84,6 +85,8 @@ sentry_options_free(sentry_options_t *opts)
}
sentry__dsn_decref(opts->dsn);
sentry_free(opts->release);
sentry_free(opts->sdk_name);
sentry_free(opts->user_agent);
sentry_free(opts->environment);
sentry_free(opts->dist);
sentry_free(opts->http_proxy);
Expand Down Expand Up @@ -295,6 +298,51 @@ sentry_options_get_transport_thread_name(const sentry_options_t *opts)
return opts->transport_thread_name;
}

int
sentry_options_set_sdk_name(sentry_options_t *opts, const char *sdk_name)
{
if (!opts || !sdk_name) {
return 1;
}
const size_t sdk_name_len = strlen(sdk_name);
return sentry_options_set_sdk_name_n(opts, sdk_name, sdk_name_len);
}

int
sentry_options_set_sdk_name_n(
sentry_options_t *opts, const char *sdk_name, size_t sdk_name_len)
{
if (!opts || !sdk_name) {
return 1;
}

sentry_free(opts->sdk_name);
opts->sdk_name = sentry__string_clone_n(sdk_name, sdk_name_len);

sentry_stringbuilder_t sb;
sentry__stringbuilder_init(&sb);
sentry__stringbuilder_append(&sb, opts->sdk_name);
sentry__stringbuilder_append(&sb, "/");
sentry__stringbuilder_append(&sb, SENTRY_SDK_VERSION);

sentry_free(opts->user_agent);
opts->user_agent = sentry__stringbuilder_into_string(&sb);

return 0;
}

const char *
sentry_options_get_sdk_name(const sentry_options_t *opts)
{
return opts->sdk_name;
}

const char *
sentry_options_get_user_agent(const sentry_options_t *opts)
{
return opts->user_agent;
}

void
sentry_options_set_debug(sentry_options_t *opts, int debug)
{
Expand Down
2 changes: 2 additions & 0 deletions src/sentry_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ typedef struct sentry_options_s {
char *http_proxy;
char *ca_certs;
char *transport_thread_name;
char *sdk_name;
char *user_agent;
sentry_path_t *database_path;
sentry_path_t *handler_path;
sentry_logger_t logger;
Expand Down
11 changes: 9 additions & 2 deletions src/sentry_scope.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@ get_client_sdk(void)
{
sentry_value_t client_sdk = sentry_value_new_object();

sentry_value_t name = sentry_value_new_string(SENTRY_SDK_NAME);
sentry_value_set_by_key(client_sdk, "name", name);
SENTRY_WITH_OPTIONS (options) {
markushi marked this conversation as resolved.
Show resolved Hide resolved
sentry_value_t sdk_name = sentry_value_new_string(options->sdk_name);
sentry_value_set_by_key(client_sdk, "name", sdk_name);
}
// in case the SDK is not initialized yet, fallback to build-time value
if (sentry_value_is_null(sentry_value_get_by_key(client_sdk, "name"))) {
sentry_value_t sdk_name = sentry_value_new_string(SENTRY_SDK_NAME);
sentry_value_set_by_key(client_sdk, "name", sdk_name);
}

sentry_value_t version = sentry_value_new_string(SENTRY_SDK_VERSION);
sentry_value_set_by_key(client_sdk, "version", version);
Expand Down
5 changes: 3 additions & 2 deletions src/sentry_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ sentry_transport_free(sentry_transport_t *transport)

sentry_prepared_http_request_t *
sentry__prepare_http_request(sentry_envelope_t *envelope,
const sentry_dsn_t *dsn, const sentry_rate_limiter_t *rl)
const sentry_dsn_t *dsn, const sentry_rate_limiter_t *rl,
const char *user_agent)
{
if (!dsn || !dsn->is_valid) {
return NULL;
Expand Down Expand Up @@ -189,7 +190,7 @@ sentry__prepare_http_request(sentry_envelope_t *envelope,
sentry_prepared_http_header_t *h;
h = &req->headers[req->headers_len++];
h->key = "x-sentry-auth";
h->value = sentry__dsn_get_auth_header(dsn);
h->value = sentry__dsn_get_auth_header(dsn, user_agent);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as with options in the scope-private get_client_sdk... I would provide a fallback (even though, in this case, this is less probable to happen before the options have been initialized). But maybe we can shift the options access to sentry__curl_transport_start and add a user_agent field to curl_transport_state_s?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fact that no unit-test screams at this is also problematic. Can you please add assertions for "user-agent" in the unit tests that "cover" sentry__prepare_http_request()? Thx!

h = &req->headers[req->headers_len++];
h->key = "content-type";
Expand Down
2 changes: 1 addition & 1 deletion src/sentry_transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ typedef struct sentry_prepared_http_request_s {
*/
sentry_prepared_http_request_t *sentry__prepare_http_request(
sentry_envelope_t *envelope, const sentry_dsn_t *dsn,
const sentry_rate_limiter_t *rl);
const sentry_rate_limiter_t *rl, const char *user_agent);

/**
* Free a previously allocated HTTP request.
Expand Down
21 changes: 14 additions & 7 deletions src/sentry_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ sentry__dsn_decref(sentry_dsn_t *dsn)
}

char *
sentry__dsn_get_auth_header(const sentry_dsn_t *dsn)
sentry__dsn_get_auth_header(const sentry_dsn_t *dsn, const char *user_agent)
{
if (!dsn || !dsn->is_valid) {
return NULL;
Expand All @@ -321,8 +321,14 @@ sentry__dsn_get_auth_header(const sentry_dsn_t *dsn)
sentry__stringbuilder_init(&sb);
sentry__stringbuilder_append(&sb, "Sentry sentry_key=");
sentry__stringbuilder_append(&sb, dsn->public_key);
sentry__stringbuilder_append(
&sb, ", sentry_version=7, sentry_client=" SENTRY_SDK_USER_AGENT);
sentry__stringbuilder_append(&sb, ", sentry_version=7");

sentry__stringbuilder_append(&sb, ", sentry_client=");
if (user_agent) {
sentry__stringbuilder_append(&sb, user_agent);
} else {
sentry__stringbuilder_append(&sb, SENTRY_SDK_USER_AGENT);
}
return sentry__stringbuilder_into_string(&sb);
}

Expand Down Expand Up @@ -353,15 +359,16 @@ sentry__dsn_get_envelope_url(const sentry_dsn_t *dsn)
}

char *
sentry__dsn_get_minidump_url(const sentry_dsn_t *dsn)
sentry__dsn_get_minidump_url(const sentry_dsn_t *dsn, const char *user_agent)
{
if (!dsn || !dsn->is_valid) {
if (!dsn || !dsn->is_valid || !user_agent) {
return NULL;
}
sentry_stringbuilder_t sb;
init_string_builder_for_url(&sb, dsn);
sentry__stringbuilder_append(
&sb, "/minidump/?sentry_client=" SENTRY_SDK_USER_AGENT "&sentry_key=");
sentry__stringbuilder_append(&sb, "/minidump/?sentry_client=");
sentry__stringbuilder_append(&sb, user_agent);
sentry__stringbuilder_append(&sb, "&sentry_key=");
sentry__stringbuilder_append(&sb, dsn->public_key);
return sentry__stringbuilder_into_string(&sb);
}
Expand Down
6 changes: 4 additions & 2 deletions src/sentry_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ void sentry__dsn_decref(sentry_dsn_t *dsn);
* described here:
* https://docs.sentry.io/development/sdk-dev/overview/#authentication
*/
char *sentry__dsn_get_auth_header(const sentry_dsn_t *dsn);
char *sentry__dsn_get_auth_header(
const sentry_dsn_t *dsn, const char *user_agent);

/**
* Returns the envelope endpoint url used for normal uploads as a newly
Expand All @@ -92,7 +93,8 @@ char *sentry__dsn_get_envelope_url(const sentry_dsn_t *dsn);
* Returns the minidump endpoint url used for uploads done by the out-of-process
* crashpad backend as a newly allocated string.
*/
char *sentry__dsn_get_minidump_url(const sentry_dsn_t *dsn);
char *sentry__dsn_get_minidump_url(
const sentry_dsn_t *dsn, const char *user_agent);

/**
* Returns the number of milliseconds since the unix epoch.
Expand Down
5 changes: 4 additions & 1 deletion src/transports/sentry_transport_curl.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
typedef struct curl_transport_state_s {
sentry_dsn_t *dsn;
CURL *curl_handle;
char *user_agent;
char *http_proxy;
char *ca_certs;
sentry_rate_limiter_t *ratelimiter;
Expand Down Expand Up @@ -52,6 +53,7 @@ sentry__curl_bgworker_state_free(void *_state)
sentry__dsn_decref(state->dsn);
sentry__rate_limiter_free(state->ratelimiter);
sentry_free(state->ca_certs);
sentry_free(state->user_agent);
sentry_free(state->http_proxy);
sentry_free(state);
}
Expand Down Expand Up @@ -100,6 +102,7 @@ sentry__curl_transport_start(

state->dsn = sentry__dsn_incref(options->dsn);
state->http_proxy = sentry__string_clone(options->http_proxy);
state->user_agent = sentry__string_clone(options->user_agent);
state->ca_certs = sentry__string_clone(options->ca_certs);
state->curl_handle = curl_easy_init();
state->debug = options->debug;
Expand Down Expand Up @@ -168,7 +171,7 @@ sentry__curl_send_task(void *_envelope, void *_state)
curl_bgworker_state_t *state = (curl_bgworker_state_t *)_state;

sentry_prepared_http_request_t *req = sentry__prepare_http_request(
envelope, state->dsn, state->ratelimiter);
envelope, state->dsn, state->ratelimiter, state->user_agent);
if (!req) {
return;
}
Expand Down
7 changes: 5 additions & 2 deletions src/transports/sentry_transport_winhttp.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ sentry__winhttp_transport_start(
winhttp_bgworker_state_t *state = sentry__bgworker_get_state(bgworker);

state->dsn = sentry__dsn_incref(opts->dsn);
state->user_agent = sentry__string_to_wstr(SENTRY_SDK_USER_AGENT);
state->user_agent = sentry__string_to_wstr(opts->user_agent);
state->debug = opts->debug;

sentry__bgworker_setname(bgworker, opts->transport_thread_name);
Expand Down Expand Up @@ -152,9 +152,11 @@ sentry__winhttp_send_task(void *_envelope, void *_state)

uint64_t started = sentry__monotonic_time();

char *user_agent = sentry__string_from_wstr(state->user_agent);
sentry_prepared_http_request_t *req = sentry__prepare_http_request(
envelope, state->dsn, state->ratelimiter);
envelope, state->dsn, state->ratelimiter, user_agent);
if (!req) {
sentry_free(user_agent);
return;
}

Expand Down Expand Up @@ -283,6 +285,7 @@ sentry__winhttp_send_task(void *_envelope, void *_state)
state->request = NULL;
WinHttpCloseHandle(request);
}
sentry_free(user_agent);
sentry_free(url);
sentry_free(headers);
sentry__prepared_http_request_free(req);
Expand Down
1 change: 1 addition & 0 deletions tests/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ add_executable(sentry_test_unit
test_logger.c
test_modulefinder.c
test_mpack.c
test_options.c
test_path.c
test_ratelimiter.c
test_sampling.c
Expand Down
8 changes: 4 additions & 4 deletions tests/unit/test_envelopes.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ SENTRY_TEST(basic_http_request_preparation_for_event)
sentry__envelope_add_event(envelope, event);

sentry_prepared_http_request_t *req
= sentry__prepare_http_request(envelope, dsn, NULL);
= sentry__prepare_http_request(envelope, dsn, NULL, NULL);
TEST_CHECK_STRING_EQUAL(req->method, "POST");
TEST_CHECK_STRING_EQUAL(
req->url, "https://sentry.invalid:443/api/42/envelope/");
Expand Down Expand Up @@ -58,7 +58,7 @@ SENTRY_TEST(basic_http_request_preparation_for_transaction)
sentry__envelope_add_transaction(envelope, transaction);

sentry_prepared_http_request_t *req
= sentry__prepare_http_request(envelope, dsn, NULL);
= sentry__prepare_http_request(envelope, dsn, NULL, NULL);
TEST_CHECK_STRING_EQUAL(req->method, "POST");
TEST_CHECK_STRING_EQUAL(
req->url, "https://sentry.invalid:443/api/42/envelope/");
Expand Down Expand Up @@ -91,7 +91,7 @@ SENTRY_TEST(basic_http_request_preparation_for_event_with_attachment)
envelope, msg, sizeof(msg) - 1, "attachment");

sentry_prepared_http_request_t *req
= sentry__prepare_http_request(envelope, dsn, NULL);
= sentry__prepare_http_request(envelope, dsn, NULL, NULL);
TEST_CHECK_STRING_EQUAL(req->method, "POST");
TEST_CHECK_STRING_EQUAL(
req->url, "https://sentry.invalid:443/api/42/envelope/");
Expand Down Expand Up @@ -120,7 +120,7 @@ SENTRY_TEST(basic_http_request_preparation_for_minidump)
envelope, msg, sizeof(msg) - 1, "attachment");

sentry_prepared_http_request_t *req
= sentry__prepare_http_request(envelope, dsn, NULL);
= sentry__prepare_http_request(envelope, dsn, NULL, NULL);
TEST_CHECK_STRING_EQUAL(req->method, "POST");
TEST_CHECK_STRING_EQUAL(
req->url, "https://sentry.invalid:443/api/42/envelope/");
Expand Down
Loading