@@ -2,10 +2,17 @@ use crate::{
22 reqwest:: is_http_error_recoverable, LAUNCHDARKLY_EVENT_SCHEMA_HEADER ,
33 LAUNCHDARKLY_PAYLOAD_ID_HEADER ,
44} ;
5- use std:: collections:: HashMap ;
6-
75use chrono:: DateTime ;
86use crossbeam_channel:: Sender ;
7+ use std:: collections:: HashMap ;
8+
9+ #[ cfg( feature = "event-compression" ) ]
10+ use flate2:: write:: GzEncoder ;
11+ #[ cfg( feature = "event-compression" ) ]
12+ use flate2:: Compression ;
13+ #[ cfg( feature = "event-compression" ) ]
14+ use std:: io:: Write ;
15+
916use futures:: future:: BoxFuture ;
1017use hyper:: { client:: connect:: Connection , service:: Service , Uri } ;
1118use tokio:: {
@@ -36,6 +43,10 @@ pub struct HyperEventSender<C> {
3643 sdk_key : String ,
3744 http : hyper:: Client < C > ,
3845 default_headers : HashMap < & ' static str , String > ,
46+
47+ // used with event-compression feature
48+ #[ allow( dead_code) ]
49+ compress_events : bool ,
3950}
4051
4152impl < C > HyperEventSender < C >
@@ -50,12 +61,14 @@ where
5061 url : hyper:: Uri ,
5162 sdk_key : & str ,
5263 default_headers : HashMap < & ' static str , String > ,
64+ compress_events : bool ,
5365 ) -> Self {
5466 Self {
5567 url,
5668 sdk_key : sdk_key. to_owned ( ) ,
5769 http : hyper:: Client :: builder ( ) . build ( connector) ,
5870 default_headers,
71+ compress_events,
5972 }
6073 }
6174
96109 serde_json:: to_string_pretty( & events) . unwrap_or_else( |e| e. to_string( ) )
97110 ) ;
98111
99- let json = match serde_json:: to_vec ( & events) {
112+ // mut is needed for event-compression feature
113+ #[ allow( unused_mut) ]
114+ let mut payload = match serde_json:: to_vec ( & events) {
100115 Ok ( json) => json,
101116 Err ( e) => {
102117 error ! (
@@ -107,6 +122,21 @@ where
107122 }
108123 } ;
109124
125+ // mut is needed for event-compression feature
126+ #[ allow( unused_mut) ]
127+ let mut additional_headers = self . default_headers . clone ( ) ;
128+
129+ #[ cfg( feature = "event-compression" ) ]
130+ if self . compress_events {
131+ let mut e = GzEncoder :: new ( Vec :: new ( ) , Compression :: default ( ) ) ;
132+ if e. write_all ( payload. as_slice ( ) ) . is_ok ( ) {
133+ if let Ok ( compressed) = e. finish ( ) {
134+ payload = compressed;
135+ additional_headers. insert ( "Content-Encoding" , "gzip" . into ( ) ) ;
136+ }
137+ }
138+ }
139+
110140 for attempt in 1 ..=2 {
111141 if attempt == 2 {
112142 sleep ( Duration :: from_secs ( 1 ) ) . await ;
@@ -124,11 +154,11 @@ where
124154 )
125155 . header ( LAUNCHDARKLY_PAYLOAD_ID_HEADER , uuid. to_string ( ) ) ;
126156
127- for default_header in & self . default_headers {
157+ for default_header in & additional_headers {
128158 request_builder =
129159 request_builder. header ( * default_header. 0 , default_header. 1 . as_str ( ) ) ;
130160 }
131- let request = request_builder. body ( hyper:: Body :: from ( json . clone ( ) ) ) ;
161+ let request = request_builder. body ( hyper:: Body :: from ( payload . clone ( ) ) ) ;
132162
133163 let result = self . http . request ( request. unwrap ( ) ) . await ;
134164
@@ -334,6 +364,7 @@ mod tests {
334364 url,
335365 "sdk-key" ,
336366 HashMap :: < & str , String > :: new ( ) ,
367+ false ,
337368 )
338369 }
339370}
0 commit comments