@@ -10,22 +10,27 @@ use indexmap::IndexMap;
10
10
11
11
use crate :: {
12
12
codecs:: { EncodingConfigWithFraming , SinkType } ,
13
- http:: { get_http_scheme_from_uri , Auth , HttpClient , MaybeAuth } ,
13
+ http:: { Auth , HttpClient , MaybeAuth } ,
14
14
sinks:: {
15
15
prelude:: * ,
16
16
util:: {
17
- http:: RequestConfig ,
18
- http_service:: { HttpRetryLogic , HttpService } ,
17
+ http:: { HttpStatusRetryLogic , RequestConfig } ,
19
18
RealtimeSizeBasedDefaultBatchSettings , UriSerde ,
20
19
} ,
21
20
} ,
22
21
} ;
23
22
24
23
use super :: {
25
- encoder:: HttpEncoder , request_builder:: HttpRequestBuilder , service:: HttpSinkRequestBuilder ,
24
+ encoder:: HttpEncoder ,
25
+ request_builder:: HttpRequestBuilder ,
26
+ service:: { HttpResponse , HttpService , HttpSinkRequestBuilder } ,
26
27
sink:: HttpSink ,
27
28
} ;
28
29
30
+ const CONTENT_TYPE_TEXT : & str = "text/plain" ;
31
+ const CONTENT_TYPE_NDJSON : & str = "application/x-ndjson" ;
32
+ const CONTENT_TYPE_JSON : & str = "application/json" ;
33
+
29
34
/// Configuration for the `http` sink.
30
35
#[ configurable_component( sink( "http" , "Deliver observability event data to an HTTP server." ) ) ]
31
36
#[ derive( Clone , Debug ) ]
@@ -238,10 +243,6 @@ impl SinkConfig for HttpSinkConfig {
238
243
let ( payload_prefix, payload_suffix) =
239
244
validate_payload_wrapper ( & self . payload_prefix , & self . payload_suffix , & encoder) ?;
240
245
241
- let endpoint = self . uri . with_default_parts ( ) ;
242
-
243
- let protocol = get_http_scheme_from_uri ( & endpoint. uri ) ;
244
-
245
246
let client = self . build_http_client ( & cx) ?;
246
247
247
248
let healthcheck = match cx. healthcheck . uri {
@@ -251,27 +252,49 @@ impl SinkConfig for HttpSinkConfig {
251
252
None => future:: ok ( ( ) ) . boxed ( ) ,
252
253
} ;
253
254
255
+ let content_type = {
256
+ use Framer :: * ;
257
+ use Serializer :: * ;
258
+ match ( encoder. serializer ( ) , encoder. framer ( ) ) {
259
+ ( RawMessage ( _) | Text ( _) , _) => Some ( CONTENT_TYPE_TEXT . to_owned ( ) ) ,
260
+ ( Json ( _) , NewlineDelimited ( _) ) => Some ( CONTENT_TYPE_NDJSON . to_owned ( ) ) ,
261
+ ( Json ( _) , CharacterDelimited ( CharacterDelimitedEncoder { delimiter : b',' } ) ) => {
262
+ Some ( CONTENT_TYPE_JSON . to_owned ( ) )
263
+ }
264
+ _ => None ,
265
+ }
266
+ } ;
267
+
254
268
let request_builder = HttpRequestBuilder {
255
- encoder : HttpEncoder :: new ( encoder. clone ( ) , transformer) ,
269
+ encoder : HttpEncoder :: new ( encoder, transformer, payload_prefix, payload_suffix) ,
270
+ compression : self . compression ,
256
271
} ;
257
272
273
+ let content_encoding = self . compression . is_compressed ( ) . then ( || {
274
+ self . compression
275
+ . content_encoding ( )
276
+ . expect ( "Encoding should be specified for compression." )
277
+ . to_string ( )
278
+ } ) ;
279
+
258
280
let http_service_request_builder = HttpSinkRequestBuilder {
259
281
uri : self . uri . with_default_parts ( ) ,
260
282
method : self . method ,
261
283
auth : self . auth . choose_one ( & self . uri . auth ) ?,
262
284
headers,
263
- payload_prefix,
264
- payload_suffix,
265
- compression : self . compression ,
266
- encoder,
285
+ content_type,
286
+ content_encoding,
267
287
} ;
268
288
269
- let service = HttpService :: new ( http_service_request_builder , client, protocol . to_string ( ) ) ;
289
+ let service = HttpService :: new ( client, http_service_request_builder ) ;
270
290
271
291
let request_limits = self . request . tower . unwrap_with ( & Default :: default ( ) ) ;
272
292
293
+ let retry_logic =
294
+ HttpStatusRetryLogic :: new ( |req : & HttpResponse | req. http_response . status ( ) ) ;
295
+
273
296
let service = ServiceBuilder :: new ( )
274
- . settings ( request_limits, HttpRetryLogic )
297
+ . settings ( request_limits, retry_logic )
275
298
. service ( service) ;
276
299
277
300
let sink = HttpSink :: new ( service, batch_settings, request_builder) ;
0 commit comments