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

feat: sentry add gzipped with compression #954

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

## Unreleased

**Features**
**Features**:

Add user feedback capability to the Native SDK ([#966](https://github.com/getsentry/sentry-native/pull/966))
- Add optional Gzip transport compression via build option `SENTRY_TRANSPORT_COMPRESSION`. Requires system `zlib`. ([#954](https://github.com/getsentry/sentry-native/pull/954))
- Add user feedback capability to the Native SDK ([#966](https://github.com/getsentry/sentry-native/pull/966))

**Internal**:

Expand All @@ -14,6 +15,10 @@

- Add usage of the breadcrumb `data` property to the example. [#951](https://github.com/getsentry/sentry-native/pull/951)

**Thank you**:

- [@Strive-Sun](https://github.com/Strive-Sun)

## 0.7.0

**Breaking changes**:
Expand All @@ -39,6 +44,7 @@ Features, fixes and improvements in this release have been contributed by:

- [@compnerd](https://github.com/compnerd)
- [@stima](https://github.com/stima)
- [@hyp](https://github.com/hyp)

## 0.6.7

Expand Down
30 changes: 16 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ endif()

option(SENTRY_PIC "Build sentry (and dependent) libraries as position independent libraries" ON)

option(SENTRY_TRANSPORT_COMPRESSION "Enable transport gzip compression" OFF)

option(SENTRY_BUILD_TESTS "Build sentry-native tests" "${SENTRY_MAIN_PROJECT}")
option(SENTRY_BUILD_EXAMPLES "Build sentry-native example(s)" "${SENTRY_MAIN_PROJECT}")

Expand Down Expand Up @@ -278,17 +280,20 @@ if(SENTRY_TRANSPORT_CURL)
find_package(CURL REQUIRED COMPONENTS AsynchDNS)
endif()

if(TARGET CURL::libcurl) # Only available in cmake 3.12+
target_link_libraries(sentry PRIVATE CURL::libcurl)
else()
# Needed for cmake < 3.12 support (cmake 3.12 introduced the target CURL::libcurl)
target_include_directories(sentry PRIVATE ${CURL_INCLUDE_DIR})
# The exported sentry target must not contain any path of the build machine, therefore use generator expressions
string(REPLACE ";" "$<SEMICOLON>" GENEX_CURL_LIBRARIES "${CURL_LIBRARIES}")
string(REPLACE ";" "$<SEMICOLON>" GENEX_CURL_COMPILE_DEFINITIONS "${CURL_COMPILE_DEFINITIONS}")
target_link_libraries(sentry PRIVATE $<BUILD_INTERFACE:${GENEX_CURL_LIBRARIES}>)
target_compile_definitions(sentry PRIVATE $<BUILD_INTERFACE:${GENEX_CURL_COMPILE_DEFINITIONS}>)
target_link_libraries(sentry PRIVATE CURL::libcurl)
endif()

if(SENTRY_TRANSPORT_COMPRESSION)
if(NOT ZLIB_FOUND)
find_package(ZLIB REQUIRED)
endif()

supervacuus marked this conversation as resolved.
Show resolved Hide resolved
if(SENTRY_BACKEND_CRASHPAD)
set(CRASHPAD_ZLIB_SYSTEM ON CACHE BOOL "Force CRASHPAD_ZLIB_SYSTEM when enabling transport compression" FORCE)
supervacuus marked this conversation as resolved.
Show resolved Hide resolved
endif()

target_link_libraries(sentry PRIVATE ZLIB::ZLIB)
target_compile_definitions(sentry PRIVATE SENTRY_TRANSPORT_COMPRESSION)
endif()

set_property(TARGET sentry PROPERTY C_VISIBILITY_PRESET hidden)
Expand Down Expand Up @@ -413,9 +418,6 @@ if(SENTRY_WITH_LIBUNWINDSTACK)
endif()

if(SENTRY_BACKEND_CRASHPAD)
# FIXME: required for cmake 3.12 and lower:
# - NEW behavior lets normal variable override option
cmake_policy(SET CMP0077 NEW)
if(SENTRY_BUILD_SHARED_LIBS)
set(CRASHPAD_ENABLE_INSTALL OFF CACHE BOOL "Enable crashpad installation" FORCE)
else()
Expand Down Expand Up @@ -593,4 +595,4 @@ endif()
if(SENTRY_BUILD_SHARED_LIBS)
target_link_libraries(sentry PRIVATE
"$<$<OR:$<PLATFORM_ID:Linux>,$<PLATFORM_ID:Android>>:-Wl,--build-id=sha1,--version-script=${PROJECT_SOURCE_DIR}/src/exports.map>")
endif()
endif()
2 changes: 1 addition & 1 deletion external/crashpad
85 changes: 84 additions & 1 deletion src/sentry_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,19 @@
#include "sentry_ratelimiter.h"
#include "sentry_string.h"

#ifdef SENTRY_TRANSPORT_COMPRESSION
# include "zlib.h"
#endif

#define ENVELOPE_MIME "application/x-sentry-envelope"
supervacuus marked this conversation as resolved.
Show resolved Hide resolved
#ifdef SENTRY_TRANSPORT_COMPRESSION
// The headers we use are: `x-sentry-auth`, `content-type`, `content-encoding`,
// `content-length`
# define MAX_HTTP_HEADERS 4
#else
// The headers we use are: `x-sentry-auth`, `content-type`, `content-length`
#define MAX_HTTP_HEADERS 3
# define MAX_HTTP_HEADERS 3
#endif

typedef struct sentry_transport_s {
void (*send_envelope_func)(sentry_envelope_t *envelope, void *state);
Expand Down Expand Up @@ -148,6 +158,56 @@ sentry_transport_free(sentry_transport_t *transport)
sentry_free(transport);
}

#ifdef SENTRY_TRANSPORT_COMPRESSION
static bool
gzipped_with_compression(const char *body, const size_t body_len,
char **compressed_body, size_t *compressed_body_len)
{
if (!body || body_len == 0) {
return false;
}

z_stream stream;
memset(&stream, 0, sizeof(stream));
stream.next_in = body;
stream.avail_in = body_len;

int err = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
MAX_WBITS + 16, 9, Z_DEFAULT_STRATEGY);
if (err != Z_OK) {
SENTRY_TRACEF("deflateInit2 failed: %d", err);
return false;
}

size_t len = compressBound(body_len);
char *buffer = sentry_malloc(len);
if (!buffer) {
deflateEnd(&stream);
return false;
}

while (err == Z_OK) {
stream.next_out = buffer + stream.total_out;
stream.avail_out = len - stream.total_out;
err = deflate(&stream, Z_FINISH);
}

if (err != Z_STREAM_END) {
SENTRY_TRACEF("deflate failed: %d", err);
sentry_free(buffer);
buffer = NULL;
deflateEnd(&stream);
return false;
}

*compressed_body_len = stream.total_out;
*compressed_body = buffer;

deflateEnd(&stream);
return true;
}
#endif

sentry_prepared_http_request_t *
sentry__prepare_http_request(sentry_envelope_t *envelope,
const sentry_dsn_t *dsn, const sentry_rate_limiter_t *rl,
Expand All @@ -165,6 +225,23 @@ sentry__prepare_http_request(sentry_envelope_t *envelope,
return NULL;
}

bool compressed = false;
#ifdef SENTRY_TRANSPORT_COMPRESSION
char *compressed_body = NULL;
size_t compressed_body_len = 0;
compressed = gzipped_with_compression(
body, body_len, &compressed_body, &compressed_body_len);
if (compressed) {
if (body_owned) {
sentry_free(body);
body_owned = false;
}
body = compressed_body;
body_len = compressed_body_len;
body_owned = true;
}
#endif

sentry_prepared_http_request_t *req
= SENTRY_MAKE(sentry_prepared_http_request_t);
if (!req) {
Expand Down Expand Up @@ -196,6 +273,12 @@ sentry__prepare_http_request(sentry_envelope_t *envelope,
h->key = "content-type";
h->value = sentry__string_clone(ENVELOPE_MIME);

if (compressed) {
h = &req->headers[req->headers_len++];
h->key = "content-encoding";
h->value = sentry__string_clone("gzip");
}

h = &req->headers[req->headers_len++];
h->key = "content-length";
h->value = sentry__int64_to_string((int64_t)body_len);
Expand Down
Loading