From fbb430b4d8f7acddc353e6062c7a7dd42d2020af Mon Sep 17 00:00:00 2001 From: "Matthew M. Keeler" Date: Wed, 15 May 2024 13:03:10 -0400 Subject: [PATCH] feat: Enable gzip support for event payloads (#270) --- contract-tests/service.rb | 1 + launchdarkly-server-sdk.gemspec | 1 + lib/ldclient-rb/impl/event_sender.rb | 7 ++++++- spec/http_util.rb | 13 +++++++------ spec/impl/event_sender_spec.rb | 8 ++++---- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/contract-tests/service.rb b/contract-tests/service.rb index 954715ee..dc5705e5 100644 --- a/contract-tests/service.rb +++ b/contract-tests/service.rb @@ -34,6 +34,7 @@ 'secure-mode-hash', 'tags', 'migrations', + 'event-gzip', 'event-sampling', 'context-comparison', 'polling-gzip', diff --git a/launchdarkly-server-sdk.gemspec b/launchdarkly-server-sdk.gemspec index be94a681..26c73c8d 100644 --- a/launchdarkly-server-sdk.gemspec +++ b/launchdarkly-server-sdk.gemspec @@ -39,6 +39,7 @@ Gem::Specification.new do |spec| spec.add_runtime_dependency "concurrent-ruby", "~> 1.1" spec.add_runtime_dependency "ld-eventsource", "2.2.2" spec.add_runtime_dependency "observer", "~> 0.1.2" + spec.add_runtime_dependency "zlib", "~> 3.1" unless RUBY_PLATFORM == "java" # Please keep ld-eventsource dependency as an exact version so that bugfixes to # that LD library are always associated with a new SDK version. diff --git a/lib/ldclient-rb/impl/event_sender.rb b/lib/ldclient-rb/impl/event_sender.rb index 4f4561d6..4fcdaf13 100644 --- a/lib/ldclient-rb/impl/event_sender.rb +++ b/lib/ldclient-rb/impl/event_sender.rb @@ -2,6 +2,8 @@ require "securerandom" require "http" +require "stringio" +require "zlib" module LaunchDarkly module Impl @@ -42,14 +44,17 @@ def send_event_data(event_data, description, is_diagnostic) @logger.debug { "[LDClient] sending #{description}: #{event_data}" } headers = {} headers["content-type"] = "application/json" + headers["content-encoding"] = "gzip" Impl::Util.default_http_headers(@sdk_key, @config).each { |k, v| headers[k] = v } unless is_diagnostic headers["X-LaunchDarkly-Event-Schema"] = CURRENT_SCHEMA_VERSION.to_s headers["X-LaunchDarkly-Payload-ID"] = payload_id end + gzip = Zlib::GzipWriter.new(StringIO.new) + gzip << event_data response = http_client.request("POST", uri, { headers: headers, - body: event_data, + body: gzip.close.string, }) rescue StandardError => exn @logger.warn { "[LDClient] Error sending events: #{exn.inspect}." } diff --git a/spec/http_util.rb b/spec/http_util.rb index 447c775a..ffc318b0 100644 --- a/spec/http_util.rb +++ b/spec/http_util.rb @@ -1,6 +1,8 @@ require "webrick" require "webrick/httpproxy" require "webrick/https" +require "stringio" +require "zlib" class StubHTTPServer attr_reader :requests, :port @@ -73,14 +75,13 @@ def record_request(req, res) @requests_queue << [req, req.body] end - def await_request - r = @requests_queue.pop - r[0] - end - def await_request_with_body r = @requests_queue.pop - [r[0], r[1]] + body = r[1] + + gz = Zlib::GzipReader.new(StringIO.new(body.to_s)) + + [r[0], gz.read] end end diff --git a/spec/impl/event_sender_spec.rb b/spec/impl/event_sender_spec.rb index c79855bc..dd48fcb4 100644 --- a/spec/impl/event_sender_spec.rb +++ b/spec/impl/event_sender_spec.rb @@ -37,8 +37,8 @@ def with_sender_and_server expect(result.must_shutdown).to be false expect(result.time_from_server).not_to be_nil - req = server.await_request - expect(req.body).to eq fake_data + req, body = server.await_request_with_body + expect(body).to eq fake_data expect(req.header).to include({ "authorization" => [ sdk_key ], "content-type" => [ "application/json" ], @@ -63,8 +63,8 @@ def with_sender_and_server result = es.send_event_data(fake_data, "", false) expect(result.success).to be true - req = server.await_request - expect(req.body).to eq fake_data + req, body = server.await_request_with_body + expect(body).to eq fake_data expect(req.host).to eq "fake-event-server" end end