logstash-output-http 5.2.5 → 5.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +10 -0
 - data/docs/index.asciidoc +68 -11
 - data/lib/logstash/outputs/http.rb +29 -4
 - data/logstash-output-http.gemspec +2 -2
 - data/spec/outputs/http_spec.rb +235 -42
 - metadata +5 -6
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 6f8c174b5f5725b3dff206924edcff21ebc71899e386c1a301860dba438bbec5
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: dd6f158c15357a1dee6bfc3ad6e0faa4f6080c3fc2a89b6050b188bd3d016d4a
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 2d668381891939636b2462361fe0011d5ced8461b5a1a5e7f2662aa765e4672b6377e2dd37a05073eaa8e0602d60632496fa48ec9c42ab5063839f02214f2e9d
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: b3ff1de393aee131f18a1d8d75f05389f6a74642e695626b1e9b4b03eec99b7a26017cea50b97315f35594013650785a8b3e11bfcc7acd4e5d32ed118340f208
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,3 +1,13 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ## 5.4.1
         
     | 
| 
      
 2 
     | 
    
         
            +
              - Fix retry indefinitely in termination process. This feature requires Logstash 8.1 [#129](https://github.com/logstash-plugins/logstash-output-http/pull/129)
         
     | 
| 
      
 3 
     | 
    
         
            +
              - Docs: Add retry policy description [#130](https://github.com/logstash-plugins/logstash-output-http/pull/130)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ## 5.4.0
         
     | 
| 
      
 6 
     | 
    
         
            +
              - Introduce retryable unknown exceptions for "connection reset by peer" and "timeout" [#127](https://github.com/logstash-plugins/logstash-output-http/pull/127)
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            ## 5.3.0
         
     | 
| 
      
 9 
     | 
    
         
            +
              - Feat: support ssl_verification_mode option [#126](https://github.com/logstash-plugins/logstash-output-http/pull/126)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       1 
11 
     | 
    
         
             
            ## 5.2.5
         
     | 
| 
       2 
12 
     | 
    
         
             
              - Reduce amount of default logging on a failed request [#122](https://github.com/logstash-plugins/logstash-output-http/pull/122)
         
     | 
| 
       3 
13 
     | 
    
         | 
    
        data/docs/index.asciidoc
    CHANGED
    
    | 
         @@ -31,6 +31,40 @@ guaranteed! 
     | 
|
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
            Beware, this gem does not yet support codecs. Please use the 'format' option for now.
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
      
 34 
     | 
    
         
            +
            [id="plugins-{type}s-{plugin}-retry_policy"]
         
     | 
| 
      
 35 
     | 
    
         
            +
            ==== Retry policy
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            This output has two levels of retry: library and plugin.
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            [id="plugins-{type}s-{plugin}-library_retry"]
         
     | 
| 
      
 40 
     | 
    
         
            +
            ===== Library retry
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            The library retry applies to IO related failures. 
         
     | 
| 
      
 43 
     | 
    
         
            +
            Non retriable errors include SSL related problems, unresolvable hosts,
         
     | 
| 
      
 44 
     | 
    
         
            +
            connection issues, and OS/JVM level interruptions happening during a request.
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            The options for library retry are: 
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            * <<plugins-{type}s-{plugin}-automatic_retries,`automatic_retries`>>. 
         
     | 
| 
      
 49 
     | 
    
         
            +
            Controls the number of times the plugin should retry after failures at the library level.
         
     | 
| 
      
 50 
     | 
    
         
            +
            * <<plugins-{type}s-{plugin}-retry_non_idempotent,`retry_non_idempotent`>>. 
         
     | 
| 
      
 51 
     | 
    
         
            +
            When set to `false`, GET, HEAD, PUT, DELETE, OPTIONS, and TRACE requests will be
         
     | 
| 
      
 52 
     | 
    
         
            +
            retried.
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            [id="plugins-{type}s-{plugin}-plugin_retry"]
         
     | 
| 
      
 55 
     | 
    
         
            +
            ===== Plugin retry
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            The options for plugin level retry are: 
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            * <<plugins-{type}s-{plugin}-retry_failed,`retry_failed`>>. 
         
     | 
| 
      
 60 
     | 
    
         
            +
            When set to `true`, the plugin retries indefinitely for HTTP error response codes defined
         
     | 
| 
      
 61 
     | 
    
         
            +
            in the <<plugins-{type}s-{plugin}-retryable_codes,`retryable_codes`>> option
         
     | 
| 
      
 62 
     | 
    
         
            +
            (429, 500, 502, 503, 504) and retryable exceptions (socket timeout/ error, DNS resolution failure and client protocol exception).
         
     | 
| 
      
 63 
     | 
    
         
            +
            * <<plugins-{type}s-{plugin}-retryable_codes,`retryable_codes`>>. 
         
     | 
| 
      
 64 
     | 
    
         
            +
            Sets http response codes that trigger a retry. 
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            NOTE: The `retry_failed` option does not control the library level retry.
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
       34 
68 
     | 
    
         
             
            [id="plugins-{type}s-{plugin}-options"]
         
     | 
| 
       35 
69 
     | 
    
         
             
            ==== Http Output Configuration Options
         
     | 
| 
       36 
70 
     | 
    
         | 
| 
         @@ -66,6 +100,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ 
     | 
|
| 
       66 
100 
     | 
    
         
             
            | <<plugins-{type}s-{plugin}-retry_non_idempotent>> |<<boolean,boolean>>|No
         
     | 
| 
       67 
101 
     | 
    
         
             
            | <<plugins-{type}s-{plugin}-retryable_codes>> |<<number,number>>|No
         
     | 
| 
       68 
102 
     | 
    
         
             
            | <<plugins-{type}s-{plugin}-socket_timeout>> |<<number,number>>|No
         
     | 
| 
      
 103 
     | 
    
         
            +
            | <<plugins-{type}s-{plugin}-ssl_verification_mode>> |<<string,string>>|No
         
     | 
| 
       69 
104 
     | 
    
         
             
            | <<plugins-{type}s-{plugin}-truststore>> |a valid filesystem path|No
         
     | 
| 
       70 
105 
     | 
    
         
             
            | <<plugins-{type}s-{plugin}-truststore_password>> |<<password,password>>|No
         
     | 
| 
       71 
106 
     | 
    
         
             
            | <<plugins-{type}s-{plugin}-truststore_type>> |<<string,string>>|No
         
     | 
| 
         @@ -84,12 +119,10 @@ output plugins. 
     | 
|
| 
       84 
119 
     | 
    
         
             
              * Value type is <<number,number>>
         
     | 
| 
       85 
120 
     | 
    
         
             
              * Default value is `1`
         
     | 
| 
       86 
121 
     | 
    
         | 
| 
       87 
     | 
    
         
            -
            How many times should the client retry a failing URL. We  
     | 
| 
       88 
     | 
    
         
            -
            to zero if keepalive is enabled.  
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
            unless `retry_failed` is set.
         
     | 
| 
       92 
     | 
    
         
            -
            Note: if `retry_non_idempotent` is NOT set only GET, HEAD, PUT, DELETE, OPTIONS, and TRACE requests will be retried.
         
     | 
| 
      
 122 
     | 
    
         
            +
            How many times should the client retry a failing URL. We recommend setting this option
         
     | 
| 
      
 123 
     | 
    
         
            +
            to a value other than zero if the <<plugins-{type}s-{plugin}-keepalive,`keepalive` option>> is enabled. 
         
     | 
| 
      
 124 
     | 
    
         
            +
            Some servers incorrectly end keepalives early, requiring a retry.
         
     | 
| 
      
 125 
     | 
    
         
            +
            See <<plugins-{type}s-{plugin}-retry_policy,Retry Policy>> for more information.
         
     | 
| 
       93 
126 
     | 
    
         | 
| 
       94 
127 
     | 
    
         
             
            [id="plugins-{type}s-{plugin}-cacert"]
         
     | 
| 
       95 
128 
     | 
    
         
             
            ===== `cacert` 
         
     | 
| 
         @@ -310,7 +343,12 @@ Timeout (in seconds) for the entire request 
     | 
|
| 
       310 
343 
     | 
    
         
             
              * Value type is <<boolean,boolean>>
         
     | 
| 
       311 
344 
     | 
    
         
             
              * Default value is `true`
         
     | 
| 
       312 
345 
     | 
    
         | 
| 
       313 
     | 
    
         
            -
             
     | 
| 
      
 346 
     | 
    
         
            +
            Note that this option controls plugin-level retries only. 
         
     | 
| 
      
 347 
     | 
    
         
            +
            It has no affect on library-level retries. 
         
     | 
| 
      
 348 
     | 
    
         
            +
             
     | 
| 
      
 349 
     | 
    
         
            +
            Set this option to `false` if you want to disable infinite retries for HTTP error response codes defined in the <<plugins-{type}s-{plugin}-retryable_codes,`retryable_codes`>> or 
         
     | 
| 
      
 350 
     | 
    
         
            +
            retryable exceptions (Timeout, SocketException, ClientProtocolException, ResolutionFailure and SocketTimeout).
         
     | 
| 
      
 351 
     | 
    
         
            +
            See <<plugins-{type}s-{plugin}-retry_policy,Retry policy>> for more information.
         
     | 
| 
       314 
352 
     | 
    
         | 
| 
       315 
353 
     | 
    
         
             
            [id="plugins-{type}s-{plugin}-retry_non_idempotent"]
         
     | 
| 
       316 
354 
     | 
    
         
             
            ===== `retry_non_idempotent` 
         
     | 
| 
         @@ -318,8 +356,10 @@ Set this to false if you don't want this output to retry failed requests 
     | 
|
| 
       318 
356 
     | 
    
         
             
              * Value type is <<boolean,boolean>>
         
     | 
| 
       319 
357 
     | 
    
         
             
              * Default value is `false`
         
     | 
| 
       320 
358 
     | 
    
         | 
| 
       321 
     | 
    
         
            -
             
     | 
| 
       322 
     | 
    
         
            -
             
     | 
| 
      
 359 
     | 
    
         
            +
            When this option is set to `false` and `automatic_retries` is enabled, GET, HEAD, PUT, DELETE, OPTIONS, and TRACE requests will be retried.
         
     | 
| 
      
 360 
     | 
    
         
            +
             
     | 
| 
      
 361 
     | 
    
         
            +
            When set to `true` and `automatic_retries` is enabled, this will cause non-idempotent HTTP verbs (such as POST) to be retried.
         
     | 
| 
      
 362 
     | 
    
         
            +
            See <<plugins-{type}s-{plugin}-retry_policy,Retry Policy>> for more information.
         
     | 
| 
       323 
363 
     | 
    
         | 
| 
       324 
364 
     | 
    
         
             
            [id="plugins-{type}s-{plugin}-retryable_codes"]
         
     | 
| 
       325 
365 
     | 
    
         
             
            ===== `retryable_codes` 
         
     | 
| 
         @@ -327,7 +367,8 @@ This only affects connectivity related errors (see related `automatic_retries` s 
     | 
|
| 
       327 
367 
     | 
    
         
             
              * Value type is <<number,number>>
         
     | 
| 
       328 
368 
     | 
    
         
             
              * Default value is `[429, 500, 502, 503, 504]`
         
     | 
| 
       329 
369 
     | 
    
         | 
| 
       330 
     | 
    
         
            -
            If  
     | 
| 
      
 370 
     | 
    
         
            +
            If the plugin encounters these response codes, the plugin will retry indefinitely.
         
     | 
| 
      
 371 
     | 
    
         
            +
            See <<plugins-{type}s-{plugin}-retry_policy,Retry Policy>> for more information.
         
     | 
| 
       331 
372 
     | 
    
         | 
| 
       332 
373 
     | 
    
         
             
            [id="plugins-{type}s-{plugin}-socket_timeout"]
         
     | 
| 
       333 
374 
     | 
    
         
             
            ===== `socket_timeout` 
         
     | 
| 
         @@ -337,6 +378,22 @@ If encountered as response codes this plugin will retry these requests 
     | 
|
| 
       337 
378 
     | 
    
         | 
| 
       338 
379 
     | 
    
         
             
            Timeout (in seconds) to wait for data on the socket. Default is `10s`
         
     | 
| 
       339 
380 
     | 
    
         | 
| 
      
 381 
     | 
    
         
            +
            [id="plugins-{type}s-{plugin}-ssl_verification_mode"]
         
     | 
| 
      
 382 
     | 
    
         
            +
            ===== `ssl_verification_mode`
         
     | 
| 
      
 383 
     | 
    
         
            +
             
     | 
| 
      
 384 
     | 
    
         
            +
              * Value type is <<string,string>>
         
     | 
| 
      
 385 
     | 
    
         
            +
              * Supported values are: `full`, `none`
         
     | 
| 
      
 386 
     | 
    
         
            +
              * Default value is `full`
         
     | 
| 
      
 387 
     | 
    
         
            +
             
     | 
| 
      
 388 
     | 
    
         
            +
            Controls the verification of server certificates.
         
     | 
| 
      
 389 
     | 
    
         
            +
            The `full` option verifies that the provided certificate is signed by a trusted authority (CA)
         
     | 
| 
      
 390 
     | 
    
         
            +
            and also that the server’s hostname (or IP address) matches the names identified within the certificate.
         
     | 
| 
      
 391 
     | 
    
         
            +
             
     | 
| 
      
 392 
     | 
    
         
            +
            The `none` setting performs no verification of the server’s certificate.
         
     | 
| 
      
 393 
     | 
    
         
            +
            This mode disables many of the security benefits of SSL/TLS and should only be used after cautious consideration.
         
     | 
| 
      
 394 
     | 
    
         
            +
            It is primarily intended as a temporary diagnostic mechanism when attempting to resolve TLS errors.
         
     | 
| 
      
 395 
     | 
    
         
            +
            Using `none`  in production environments is strongly discouraged.
         
     | 
| 
      
 396 
     | 
    
         
            +
             
     | 
| 
       340 
397 
     | 
    
         
             
            [id="plugins-{type}s-{plugin}-truststore"]
         
     | 
| 
       341 
398 
     | 
    
         
             
            ===== `truststore` 
         
     | 
| 
       342 
399 
     | 
    
         | 
| 
         @@ -388,4 +445,4 @@ See https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache 
     | 
|
| 
       388 
445 
     | 
    
         
             
            [id="plugins-{type}s-{plugin}-common-options"]
         
     | 
| 
       389 
446 
     | 
    
         
             
            include::{include_path}/{type}.asciidoc[]
         
     | 
| 
       390 
447 
     | 
    
         | 
| 
       391 
     | 
    
         
            -
            :default_codec!:
         
     | 
| 
      
 448 
     | 
    
         
            +
            :default_codec!:
         
     | 
| 
         @@ -23,6 +23,13 @@ class LogStash::Outputs::Http < LogStash::Outputs::Base 
     | 
|
| 
       23 
23 
     | 
    
         
             
                ::Manticore::SocketTimeout
         
     | 
| 
       24 
24 
     | 
    
         
             
              ]
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
      
 26 
     | 
    
         
            +
              RETRYABLE_UNKNOWN_EXCEPTION_STRINGS = [
         
     | 
| 
      
 27 
     | 
    
         
            +
                /Connection reset by peer/i,
         
     | 
| 
      
 28 
     | 
    
         
            +
                /Read Timed out/i
         
     | 
| 
      
 29 
     | 
    
         
            +
              ]
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              class PluginInternalQueueLeftoverError < StandardError; end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
       26 
33 
     | 
    
         
             
              # This output lets you send events to a
         
     | 
| 
       27 
34 
     | 
    
         
             
              # generic HTTP(S) endpoint
         
     | 
| 
       28 
35 
     | 
    
         
             
              #
         
     | 
| 
         @@ -138,10 +145,11 @@ class LogStash::Outputs::Http < LogStash::Outputs::Base 
     | 
|
| 
       138 
145 
     | 
    
         
             
              end
         
     | 
| 
       139 
146 
     | 
    
         | 
| 
       140 
147 
     | 
    
         
             
              def log_retryable_response(response)
         
     | 
| 
      
 148 
     | 
    
         
            +
                retry_msg = @retry_failed ? 'will retry' : "won't retry"
         
     | 
| 
       141 
149 
     | 
    
         
             
                if (response.code == 429)
         
     | 
| 
       142 
     | 
    
         
            -
                  @logger.debug? && @logger.debug("Encountered a 429 response,  
     | 
| 
      
 150 
     | 
    
         
            +
                  @logger.debug? && @logger.debug("Encountered a 429 response, #{retry_msg}. This is not serious, just flow control via HTTP")
         
     | 
| 
       143 
151 
     | 
    
         
             
                else
         
     | 
| 
       144 
     | 
    
         
            -
                  @logger.warn("Encountered a retryable HTTP request in HTTP output,  
     | 
| 
      
 152 
     | 
    
         
            +
                  @logger.warn("Encountered a retryable HTTP request in HTTP output, #{retry_msg}", :code => response.code, :body => response.body)
         
     | 
| 
       145 
153 
     | 
    
         
             
                end
         
     | 
| 
       146 
154 
     | 
    
         
             
              end
         
     | 
| 
       147 
155 
     | 
    
         | 
| 
         @@ -172,6 +180,9 @@ class LogStash::Outputs::Http < LogStash::Outputs::Base 
     | 
|
| 
       172 
180 
     | 
    
         | 
| 
       173 
181 
     | 
    
         
             
                  event, attempt = popped
         
     | 
| 
       174 
182 
     | 
    
         | 
| 
      
 183 
     | 
    
         
            +
                  raise PluginInternalQueueLeftoverError.new("Received pipeline shutdown request but http output has unfinished events. " \
         
     | 
| 
      
 184 
     | 
    
         
            +
                          "If persistent queue is enabled, events will be retried.") if attempt > 2 && pipeline_shutdown_requested?
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
       175 
186 
     | 
    
         
             
                  action, event, attempt = send_event(event, attempt)
         
     | 
| 
       176 
187 
     | 
    
         
             
                  begin
         
     | 
| 
       177 
188 
     | 
    
         
             
                    action = :failure if action == :retry && !@retry_failed
         
     | 
| 
         @@ -216,6 +227,11 @@ class LogStash::Outputs::Http < LogStash::Outputs::Base 
     | 
|
| 
       216 
227 
     | 
    
         
             
                raise e
         
     | 
| 
       217 
228 
     | 
    
         
             
              end
         
     | 
| 
       218 
229 
     | 
    
         | 
| 
      
 230 
     | 
    
         
            +
              def pipeline_shutdown_requested?
         
     | 
| 
      
 231 
     | 
    
         
            +
                return super if defined?(super) # since LS 8.1.0
         
     | 
| 
      
 232 
     | 
    
         
            +
                nil
         
     | 
| 
      
 233 
     | 
    
         
            +
              end
         
     | 
| 
      
 234 
     | 
    
         
            +
             
     | 
| 
       219 
235 
     | 
    
         
             
              def sleep_for_attempt(attempt)
         
     | 
| 
       220 
236 
     | 
    
         
             
                sleep_for = attempt**2
         
     | 
| 
       221 
237 
     | 
    
         
             
                sleep_for = sleep_for <= 60 ? sleep_for : 60
         
     | 
| 
         @@ -294,12 +310,21 @@ class LogStash::Outputs::Http < LogStash::Outputs::Base 
     | 
|
| 
       294 
310 
     | 
    
         
             
              end
         
     | 
| 
       295 
311 
     | 
    
         | 
| 
       296 
312 
     | 
    
         
             
              def retryable_exception?(exception)
         
     | 
| 
       297 
     | 
    
         
            -
                 
     | 
| 
      
 313 
     | 
    
         
            +
                retryable_manticore_exception?(exception) || retryable_unknown_exception?(exception)
         
     | 
| 
      
 314 
     | 
    
         
            +
              end
         
     | 
| 
      
 315 
     | 
    
         
            +
             
     | 
| 
      
 316 
     | 
    
         
            +
              def retryable_manticore_exception?(exception)
         
     | 
| 
      
 317 
     | 
    
         
            +
                RETRYABLE_MANTICORE_EXCEPTIONS.any? {|me| exception.is_a?(me)}
         
     | 
| 
      
 318 
     | 
    
         
            +
              end
         
     | 
| 
      
 319 
     | 
    
         
            +
             
     | 
| 
      
 320 
     | 
    
         
            +
              def retryable_unknown_exception?(exception)
         
     | 
| 
      
 321 
     | 
    
         
            +
                exception.is_a?(::Manticore::UnknownException) &&
         
     | 
| 
      
 322 
     | 
    
         
            +
                    RETRYABLE_UNKNOWN_EXCEPTION_STRINGS.any? { |snippet| exception.message =~ snippet }
         
     | 
| 
       298 
323 
     | 
    
         
             
              end
         
     | 
| 
       299 
324 
     | 
    
         | 
| 
       300 
325 
     | 
    
         
             
              # This is split into a separate method mostly to help testing
         
     | 
| 
       301 
326 
     | 
    
         
             
              def log_failure(message, opts)
         
     | 
| 
       302 
     | 
    
         
            -
                @logger.error( 
     | 
| 
      
 327 
     | 
    
         
            +
                @logger.error(message, opts)
         
     | 
| 
       303 
328 
     | 
    
         
             
              end
         
     | 
| 
       304 
329 
     | 
    
         | 
| 
       305 
330 
     | 
    
         
             
              # Format the HTTP body
         
     | 
| 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            Gem::Specification.new do |s|
         
     | 
| 
       2 
2 
     | 
    
         
             
              s.name            = 'logstash-output-http'
         
     | 
| 
       3 
     | 
    
         
            -
              s.version         = '5. 
     | 
| 
      
 3 
     | 
    
         
            +
              s.version         = '5.4.1'
         
     | 
| 
       4 
4 
     | 
    
         
             
              s.licenses        = ['Apache License (2.0)']
         
     | 
| 
       5 
5 
     | 
    
         
             
              s.summary         = "Sends events to a generic HTTP or HTTPS endpoint"
         
     | 
| 
       6 
6 
     | 
    
         
             
              s.description     = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
         
     | 
| 
         @@ -20,7 +20,7 @@ Gem::Specification.new do |s| 
     | 
|
| 
       20 
20 
     | 
    
         | 
| 
       21 
21 
     | 
    
         
             
              # Gem dependencies
         
     | 
| 
       22 
22 
     | 
    
         
             
              s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
         
     | 
| 
       23 
     | 
    
         
            -
              s.add_runtime_dependency "logstash-mixin-http_client", ">=  
     | 
| 
      
 23 
     | 
    
         
            +
              s.add_runtime_dependency "logstash-mixin-http_client", ">= 7.1.0", "< 8.0.0"
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
       25 
25 
     | 
    
         
             
              s.add_development_dependency 'logstash-devutils'
         
     | 
| 
       26 
26 
     | 
    
         
             
              s.add_development_dependency 'sinatra'
         
     | 
    
        data/spec/outputs/http_spec.rb
    CHANGED
    
    | 
         @@ -3,6 +3,9 @@ require "logstash/outputs/http" 
     | 
|
| 
       3 
3 
     | 
    
         
             
            require "logstash/codecs/plain"
         
     | 
| 
       4 
4 
     | 
    
         
             
            require "thread"
         
     | 
| 
       5 
5 
     | 
    
         
             
            require "sinatra"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "webrick"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "webrick/https"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'openssl'
         
     | 
| 
       6 
9 
     | 
    
         
             
            require_relative "../supports/compressed_requests"
         
     | 
| 
       7 
10 
     | 
    
         | 
| 
       8 
11 
     | 
    
         
             
            PORT = rand(65535-1024) + 1025
         
     | 
| 
         @@ -22,9 +25,20 @@ class TestApp < Sinatra::Base 
     | 
|
| 
       22 
25 
     | 
    
         
             
              # on the fly uncompress gzip content
         
     | 
| 
       23 
26 
     | 
    
         
             
              use CompressedRequests
         
     | 
| 
       24 
27 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
               
     | 
| 
      
 28 
     | 
    
         
            +
              set :environment, :production
         
     | 
| 
      
 29 
     | 
    
         
            +
              set :sessions, false
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              @@server_settings = {
         
     | 
| 
      
 32 
     | 
    
         
            +
                  :AccessLog => [], # disable WEBrick logging
         
     | 
| 
      
 33 
     | 
    
         
            +
                  :Logger => WEBrick::BasicLog::new(nil, WEBrick::BasicLog::FATAL)
         
     | 
| 
      
 34 
     | 
    
         
            +
              }
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
       26 
36 
     | 
    
         
             
              def self.server_settings
         
     | 
| 
       27 
     | 
    
         
            -
                 
     | 
| 
      
 37 
     | 
    
         
            +
                @@server_settings
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def self.server_settings=(settings)
         
     | 
| 
      
 41 
     | 
    
         
            +
                @@server_settings = settings
         
     | 
| 
       28 
42 
     | 
    
         
             
              end
         
     | 
| 
       29 
43 
     | 
    
         | 
| 
       30 
44 
     | 
    
         
             
              def self.multiroute(methods, path, &block)
         
     | 
| 
         @@ -72,31 +86,22 @@ class TestApp < Sinatra::Base 
     | 
|
| 
       72 
86 
     | 
    
         
             
              end
         
     | 
| 
       73 
87 
     | 
    
         
             
            end
         
     | 
| 
       74 
88 
     | 
    
         | 
| 
       75 
     | 
    
         
            -
            RSpec.configure do 
     | 
| 
      
 89 
     | 
    
         
            +
            RSpec.configure do
         
     | 
| 
       76 
90 
     | 
    
         
             
              #http://stackoverflow.com/questions/6557079/start-and-call-ruby-http-server-in-the-same-script
         
     | 
| 
       77 
     | 
    
         
            -
              def  
     | 
| 
      
 91 
     | 
    
         
            +
              def start_app_and_wait(app, opts = {})
         
     | 
| 
       78 
92 
     | 
    
         
             
                queue = Queue.new
         
     | 
| 
       79 
93 
     | 
    
         | 
| 
       80 
     | 
    
         
            -
                 
     | 
| 
       81 
     | 
    
         
            -
                   
     | 
| 
       82 
     | 
    
         
            -
                     
     | 
| 
       83 
     | 
    
         
            -
                       
     | 
| 
       84 
     | 
    
         
            -
                        queue.push("started")
         
     | 
| 
       85 
     | 
    
         
            -
                      end
         
     | 
| 
       86 
     | 
    
         
            -
                    rescue => e
         
     | 
| 
       87 
     | 
    
         
            -
                      puts "Error in webserver thread #{e}"
         
     | 
| 
       88 
     | 
    
         
            -
                      # ignore
         
     | 
| 
      
 94 
     | 
    
         
            +
                Thread.start do
         
     | 
| 
      
 95 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 96 
     | 
    
         
            +
                    app.start!({ server: 'WEBrick', port: PORT }.merge opts) do |server|
         
     | 
| 
      
 97 
     | 
    
         
            +
                      queue.push(server)
         
     | 
| 
       89 
98 
     | 
    
         
             
                    end
         
     | 
| 
      
 99 
     | 
    
         
            +
                  rescue => e
         
     | 
| 
      
 100 
     | 
    
         
            +
                    warn "Error starting app: #{e.inspect}" # ignore
         
     | 
| 
       90 
101 
     | 
    
         
             
                  end
         
     | 
| 
       91 
     | 
    
         
            -
                 
     | 
| 
       92 
     | 
    
         
            -
                t.daemon = true
         
     | 
| 
       93 
     | 
    
         
            -
                t.start
         
     | 
| 
       94 
     | 
    
         
            -
                queue.pop # blocks until the run! callback runs
         
     | 
| 
       95 
     | 
    
         
            -
              end
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
       96 
103 
     | 
    
         | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
                sinatra_run_wait(TestApp, :port => PORT, :server => 'webrick')
         
     | 
| 
       99 
     | 
    
         
            -
                puts "Test webserver on port #{PORT}"
         
     | 
| 
      
 104 
     | 
    
         
            +
                queue.pop # blocks until the start! callback runs
         
     | 
| 
       100 
105 
     | 
    
         
             
              end
         
     | 
| 
       101 
106 
     | 
    
         
             
            end
         
     | 
| 
       102 
107 
     | 
    
         | 
| 
         @@ -104,6 +109,15 @@ describe LogStash::Outputs::Http do 
     | 
|
| 
       104 
109 
     | 
    
         
             
              # Wait for the async request to finish in this spinlock
         
     | 
| 
       105 
110 
     | 
    
         
             
              # Requires pool_max to be 1
         
     | 
| 
       106 
111 
     | 
    
         | 
| 
      
 112 
     | 
    
         
            +
              before(:all) do
         
     | 
| 
      
 113 
     | 
    
         
            +
                @server = start_app_and_wait(TestApp)
         
     | 
| 
      
 114 
     | 
    
         
            +
              end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
              after(:all) do
         
     | 
| 
      
 117 
     | 
    
         
            +
                @server.shutdown # WEBrick::HTTPServer
         
     | 
| 
      
 118 
     | 
    
         
            +
                TestApp.stop! rescue nil
         
     | 
| 
      
 119 
     | 
    
         
            +
              end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
       107 
121 
     | 
    
         
             
              let(:port) { PORT }
         
     | 
| 
       108 
122 
     | 
    
         
             
              let(:event) {
         
     | 
| 
       109 
123 
     | 
    
         
             
                LogStash::Event.new({"message" => "hi"})
         
     | 
| 
         @@ -112,6 +126,44 @@ describe LogStash::Outputs::Http do 
     | 
|
| 
       112 
126 
     | 
    
         
             
              let(:method) { "post" }
         
     | 
| 
       113 
127 
     | 
    
         | 
| 
       114 
128 
     | 
    
         
             
              shared_examples("verb behavior") do |method|
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                shared_examples("failure log behaviour") do
         
     | 
| 
      
 131 
     | 
    
         
            +
                  it "logs failure" do
         
     | 
| 
      
 132 
     | 
    
         
            +
                    expect(subject).to have_received(:log_failure).with(any_args)
         
     | 
| 
      
 133 
     | 
    
         
            +
                  end
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                  it "does not log headers" do
         
     | 
| 
      
 136 
     | 
    
         
            +
                    expect(subject).to have_received(:log_failure).with(anything, hash_not_including(:headers))
         
     | 
| 
      
 137 
     | 
    
         
            +
                  end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                  it "does not log the message body" do
         
     | 
| 
      
 140 
     | 
    
         
            +
                    expect(subject).to have_received(:log_failure).with(anything, hash_not_including(:body))
         
     | 
| 
      
 141 
     | 
    
         
            +
                  end
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                  context "with debug log level" do
         
     | 
| 
      
 144 
     | 
    
         
            +
                    before :all do
         
     | 
| 
      
 145 
     | 
    
         
            +
                      @current_log_level = LogStash::Logging::Logger.get_logging_context.get_root_logger.get_level.to_s.downcase
         
     | 
| 
      
 146 
     | 
    
         
            +
                      LogStash::Logging::Logger.configure_logging "debug"
         
     | 
| 
      
 147 
     | 
    
         
            +
                    end
         
     | 
| 
      
 148 
     | 
    
         
            +
                    after :all do
         
     | 
| 
      
 149 
     | 
    
         
            +
                      LogStash::Logging::Logger.configure_logging @current_log_level
         
     | 
| 
      
 150 
     | 
    
         
            +
                    end
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                    it "logs a failure" do
         
     | 
| 
      
 153 
     | 
    
         
            +
                      expect(subject).to have_received(:log_failure).with(any_args)
         
     | 
| 
      
 154 
     | 
    
         
            +
                    end
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
                    it "logs headers" do
         
     | 
| 
      
 157 
     | 
    
         
            +
                      expect(subject).to have_received(:log_failure).with(anything, hash_including(:headers))
         
     | 
| 
      
 158 
     | 
    
         
            +
                    end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                    it "logs the body" do
         
     | 
| 
      
 161 
     | 
    
         
            +
                      expect(subject).to have_received(:log_failure).with(anything, hash_including(:body))
         
     | 
| 
      
 162 
     | 
    
         
            +
                    end
         
     | 
| 
      
 163 
     | 
    
         
            +
                  end
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
                end
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
       115 
167 
     | 
    
         
             
                let(:verb_behavior_config) { {"url" => url, "http_method" => method, "pool_max" => 1} }
         
     | 
| 
       116 
168 
     | 
    
         
             
                subject { LogStash::Outputs::Http.new(verb_behavior_config) }
         
     | 
| 
       117 
169 
     | 
    
         | 
| 
         @@ -199,44 +251,96 @@ describe LogStash::Outputs::Http do 
     | 
|
| 
       199 
251 
     | 
    
         
             
                  end
         
     | 
| 
       200 
252 
     | 
    
         
             
                end
         
     | 
| 
       201 
253 
     | 
    
         | 
| 
       202 
     | 
    
         
            -
                context "on exception" do
         
     | 
| 
      
 254 
     | 
    
         
            +
                context "on retryable unknown exception" do
         
     | 
| 
       203 
255 
     | 
    
         
             
                  before :each do
         
     | 
| 
       204 
     | 
    
         
            -
                     
     | 
| 
      
 256 
     | 
    
         
            +
                    raised = false
         
     | 
| 
      
 257 
     | 
    
         
            +
                    original_method = subject.client.method(:send)
         
     | 
| 
      
 258 
     | 
    
         
            +
                    allow(subject).to receive(:send_event).and_call_original
         
     | 
| 
      
 259 
     | 
    
         
            +
                    expect(subject.client).to receive(:send) do |*args|
         
     | 
| 
      
 260 
     | 
    
         
            +
                      unless raised
         
     | 
| 
      
 261 
     | 
    
         
            +
                        raised = true
         
     | 
| 
      
 262 
     | 
    
         
            +
                        raise ::Manticore::UnknownException.new("Read timed out")
         
     | 
| 
      
 263 
     | 
    
         
            +
                      end
         
     | 
| 
      
 264 
     | 
    
         
            +
                      original_method.call(args)
         
     | 
| 
      
 265 
     | 
    
         
            +
                    end
         
     | 
| 
       205 
266 
     | 
    
         
             
                    subject.multi_receive([event])
         
     | 
| 
       206 
267 
     | 
    
         
             
                  end
         
     | 
| 
       207 
268 
     | 
    
         | 
| 
       208 
     | 
    
         
            -
                   
     | 
| 
       209 
     | 
    
         
            -
                    expect(subject).to have_received(:log_failure).with(anything, hash_not_including(:headers))
         
     | 
| 
       210 
     | 
    
         
            -
                  end
         
     | 
| 
      
 269 
     | 
    
         
            +
                  include_examples("failure log behaviour")
         
     | 
| 
       211 
270 
     | 
    
         | 
| 
       212 
     | 
    
         
            -
                  it " 
     | 
| 
       213 
     | 
    
         
            -
                    expect(subject).to have_received(: 
     | 
| 
      
 271 
     | 
    
         
            +
                  it "retries" do
         
     | 
| 
      
 272 
     | 
    
         
            +
                    expect(subject).to have_received(:send_event).exactly(2).times
         
     | 
| 
       214 
273 
     | 
    
         
             
                  end
         
     | 
| 
      
 274 
     | 
    
         
            +
                end
         
     | 
| 
       215 
275 
     | 
    
         | 
| 
       216 
     | 
    
         
            -
             
     | 
| 
       217 
     | 
    
         
            -
             
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
       219 
     | 
    
         
            -
             
     | 
| 
       220 
     | 
    
         
            -
                     
     | 
| 
       221 
     | 
    
         
            -
                     
     | 
| 
       222 
     | 
    
         
            -
                       
     | 
| 
      
 276 
     | 
    
         
            +
                context "on non-retryable unknown exception" do
         
     | 
| 
      
 277 
     | 
    
         
            +
                  before :each do
         
     | 
| 
      
 278 
     | 
    
         
            +
                    raised = false
         
     | 
| 
      
 279 
     | 
    
         
            +
                    original_method = subject.client.method(:send)
         
     | 
| 
      
 280 
     | 
    
         
            +
                    allow(subject).to receive(:send_event).and_call_original
         
     | 
| 
      
 281 
     | 
    
         
            +
                    expect(subject.client).to receive(:send) do |*args|
         
     | 
| 
      
 282 
     | 
    
         
            +
                      unless raised
         
     | 
| 
      
 283 
     | 
    
         
            +
                        raised = true
         
     | 
| 
      
 284 
     | 
    
         
            +
                        raise ::Manticore::UnknownException.new("broken")
         
     | 
| 
      
 285 
     | 
    
         
            +
                      end
         
     | 
| 
      
 286 
     | 
    
         
            +
                      original_method.call(args)
         
     | 
| 
       223 
287 
     | 
    
         
             
                    end
         
     | 
| 
      
 288 
     | 
    
         
            +
                    subject.multi_receive([event])
         
     | 
| 
      
 289 
     | 
    
         
            +
                  end
         
     | 
| 
       224 
290 
     | 
    
         | 
| 
       225 
     | 
    
         
            -
             
     | 
| 
       226 
     | 
    
         
            -
                      expect(subject).to have_received(:log_failure).with(any_args)
         
     | 
| 
       227 
     | 
    
         
            -
                    end
         
     | 
| 
      
 291 
     | 
    
         
            +
                  include_examples("failure log behaviour")
         
     | 
| 
       228 
292 
     | 
    
         | 
| 
       229 
     | 
    
         
            -
             
     | 
| 
       230 
     | 
    
         
            -
             
     | 
| 
      
 293 
     | 
    
         
            +
                  it "does not retry" do
         
     | 
| 
      
 294 
     | 
    
         
            +
                    expect(subject).to have_received(:send_event).exactly(1).times
         
     | 
| 
      
 295 
     | 
    
         
            +
                  end
         
     | 
| 
      
 296 
     | 
    
         
            +
                end
         
     | 
| 
      
 297 
     | 
    
         
            +
             
     | 
| 
      
 298 
     | 
    
         
            +
                context "on non-retryable exception" do
         
     | 
| 
      
 299 
     | 
    
         
            +
                  before :each do
         
     | 
| 
      
 300 
     | 
    
         
            +
                    raised = false
         
     | 
| 
      
 301 
     | 
    
         
            +
                    original_method = subject.client.method(:send)
         
     | 
| 
      
 302 
     | 
    
         
            +
                    allow(subject).to receive(:send_event).and_call_original
         
     | 
| 
      
 303 
     | 
    
         
            +
                    expect(subject.client).to receive(:send) do |*args|
         
     | 
| 
      
 304 
     | 
    
         
            +
                      unless raised
         
     | 
| 
      
 305 
     | 
    
         
            +
                        raised = true
         
     | 
| 
      
 306 
     | 
    
         
            +
                        raise RuntimeError.new("broken")
         
     | 
| 
      
 307 
     | 
    
         
            +
                      end
         
     | 
| 
      
 308 
     | 
    
         
            +
                      original_method.call(args)
         
     | 
| 
       231 
309 
     | 
    
         
             
                    end
         
     | 
| 
      
 310 
     | 
    
         
            +
                    subject.multi_receive([event])
         
     | 
| 
      
 311 
     | 
    
         
            +
                  end
         
     | 
| 
       232 
312 
     | 
    
         | 
| 
       233 
     | 
    
         
            -
             
     | 
| 
       234 
     | 
    
         
            -
             
     | 
| 
      
 313 
     | 
    
         
            +
                  include_examples("failure log behaviour")
         
     | 
| 
      
 314 
     | 
    
         
            +
             
     | 
| 
      
 315 
     | 
    
         
            +
                  it "does not retry" do
         
     | 
| 
      
 316 
     | 
    
         
            +
                    expect(subject).to have_received(:send_event).exactly(1).times
         
     | 
| 
      
 317 
     | 
    
         
            +
                  end
         
     | 
| 
      
 318 
     | 
    
         
            +
                end
         
     | 
| 
      
 319 
     | 
    
         
            +
             
     | 
| 
      
 320 
     | 
    
         
            +
                context "on retryable exception" do
         
     | 
| 
      
 321 
     | 
    
         
            +
                  before :each do
         
     | 
| 
      
 322 
     | 
    
         
            +
                    raised = false
         
     | 
| 
      
 323 
     | 
    
         
            +
                    original_method = subject.client.method(:send)
         
     | 
| 
      
 324 
     | 
    
         
            +
                    allow(subject).to receive(:send_event).and_call_original
         
     | 
| 
      
 325 
     | 
    
         
            +
                    expect(subject.client).to receive(:send) do |*args|
         
     | 
| 
      
 326 
     | 
    
         
            +
                      unless raised
         
     | 
| 
      
 327 
     | 
    
         
            +
                        raised = true
         
     | 
| 
      
 328 
     | 
    
         
            +
                        raise ::Manticore::Timeout.new("broken")
         
     | 
| 
      
 329 
     | 
    
         
            +
                      end
         
     | 
| 
      
 330 
     | 
    
         
            +
                      original_method.call(args)
         
     | 
| 
       235 
331 
     | 
    
         
             
                    end
         
     | 
| 
      
 332 
     | 
    
         
            +
                    subject.multi_receive([event])
         
     | 
| 
       236 
333 
     | 
    
         
             
                  end
         
     | 
| 
      
 334 
     | 
    
         
            +
             
     | 
| 
      
 335 
     | 
    
         
            +
                  it "retries" do
         
     | 
| 
      
 336 
     | 
    
         
            +
                    expect(subject).to have_received(:send_event).exactly(2).times
         
     | 
| 
      
 337 
     | 
    
         
            +
                  end
         
     | 
| 
      
 338 
     | 
    
         
            +
             
     | 
| 
      
 339 
     | 
    
         
            +
                  include_examples("failure log behaviour")
         
     | 
| 
       237 
340 
     | 
    
         
             
                end
         
     | 
| 
       238 
341 
     | 
    
         
             
              end
         
     | 
| 
       239 
342 
     | 
    
         | 
| 
      
 343 
     | 
    
         
            +
             
     | 
| 
       240 
344 
     | 
    
         
             
              LogStash::Outputs::Http::VALID_METHODS.each do |method|
         
     | 
| 
       241 
345 
     | 
    
         
             
                context "when using '#{method}'" do
         
     | 
| 
       242 
346 
     | 
    
         
             
                  include_examples("verb behavior", method)
         
     | 
| 
         @@ -397,4 +501,93 @@ describe LogStash::Outputs::Http do 
     | 
|
| 
       397 
501 
     | 
    
         
             
                  let(:base_config) { { "http_compression" => true } }
         
     | 
| 
       398 
502 
     | 
    
         
             
                end
         
     | 
| 
       399 
503 
     | 
    
         
             
              end
         
     | 
| 
      
 504 
     | 
    
         
            +
             
     | 
| 
      
 505 
     | 
    
         
            +
              describe "retryable error in termination" do
         
     | 
| 
      
 506 
     | 
    
         
            +
                let(:url) { "http://localhost:#{port-1}/invalid" }
         
     | 
| 
      
 507 
     | 
    
         
            +
                let(:events) { [event] }
         
     | 
| 
      
 508 
     | 
    
         
            +
                let(:config) { {"url" => url, "http_method" => "get", "pool_max" => 1} }
         
     | 
| 
      
 509 
     | 
    
         
            +
             
     | 
| 
      
 510 
     | 
    
         
            +
                subject { LogStash::Outputs::Http.new(config) }
         
     | 
| 
      
 511 
     | 
    
         
            +
             
     | 
| 
      
 512 
     | 
    
         
            +
                before do
         
     | 
| 
      
 513 
     | 
    
         
            +
                  subject.register
         
     | 
| 
      
 514 
     | 
    
         
            +
                  allow(subject).to receive(:pipeline_shutdown_requested?).and_return(true)
         
     | 
| 
      
 515 
     | 
    
         
            +
                end
         
     | 
| 
      
 516 
     | 
    
         
            +
             
     | 
| 
      
 517 
     | 
    
         
            +
                it "raise exception to exit indefinitely retry" do
         
     | 
| 
      
 518 
     | 
    
         
            +
                  expect { subject.multi_receive(events) }.to raise_error(LogStash::Outputs::Http::PluginInternalQueueLeftoverError)
         
     | 
| 
      
 519 
     | 
    
         
            +
                end
         
     | 
| 
      
 520 
     | 
    
         
            +
              end
         
     | 
| 
      
 521 
     | 
    
         
            +
            end
         
     | 
| 
      
 522 
     | 
    
         
            +
             
     | 
| 
      
 523 
     | 
    
         
            +
            describe LogStash::Outputs::Http do # different block as we're starting web server with TLS
         
     | 
| 
      
 524 
     | 
    
         
            +
             
     | 
| 
      
 525 
     | 
    
         
            +
              @@default_server_settings = TestApp.server_settings.dup
         
     | 
| 
      
 526 
     | 
    
         
            +
             
     | 
| 
      
 527 
     | 
    
         
            +
              before do
         
     | 
| 
      
 528 
     | 
    
         
            +
                cert, key = WEBrick::Utils.create_self_signed_cert 2048, [["CN", ssl_cert_host]], "Logstash testing"
         
     | 
| 
      
 529 
     | 
    
         
            +
                TestApp.server_settings = @@default_server_settings.merge({
         
     | 
| 
      
 530 
     | 
    
         
            +
                   :SSLEnable       => true,
         
     | 
| 
      
 531 
     | 
    
         
            +
                   :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
         
     | 
| 
      
 532 
     | 
    
         
            +
                   :SSLCertificate  => cert,
         
     | 
| 
      
 533 
     | 
    
         
            +
                   :SSLPrivateKey   => key
         
     | 
| 
      
 534 
     | 
    
         
            +
                })
         
     | 
| 
      
 535 
     | 
    
         
            +
             
     | 
| 
      
 536 
     | 
    
         
            +
                TestApp.last_request = nil
         
     | 
| 
      
 537 
     | 
    
         
            +
             
     | 
| 
      
 538 
     | 
    
         
            +
                @server = start_app_and_wait(TestApp)
         
     | 
| 
      
 539 
     | 
    
         
            +
              end
         
     | 
| 
      
 540 
     | 
    
         
            +
             
     | 
| 
      
 541 
     | 
    
         
            +
              after do
         
     | 
| 
      
 542 
     | 
    
         
            +
                @server.shutdown # WEBrick::HTTPServer
         
     | 
| 
      
 543 
     | 
    
         
            +
             
     | 
| 
      
 544 
     | 
    
         
            +
                TestApp.stop! rescue nil
         
     | 
| 
      
 545 
     | 
    
         
            +
                TestApp.server_settings = @@default_server_settings
         
     | 
| 
      
 546 
     | 
    
         
            +
              end
         
     | 
| 
      
 547 
     | 
    
         
            +
             
     | 
| 
      
 548 
     | 
    
         
            +
              let(:ssl_cert_host) { 'localhost' }
         
     | 
| 
      
 549 
     | 
    
         
            +
             
     | 
| 
      
 550 
     | 
    
         
            +
              let(:port) { PORT }
         
     | 
| 
      
 551 
     | 
    
         
            +
              let(:url) { "https://localhost:#{port}/good" }
         
     | 
| 
      
 552 
     | 
    
         
            +
              let(:method) { "post" }
         
     | 
| 
      
 553 
     | 
    
         
            +
             
     | 
| 
      
 554 
     | 
    
         
            +
              let(:config) { { "url" => url, "http_method" => method } }
         
     | 
| 
      
 555 
     | 
    
         
            +
             
     | 
| 
      
 556 
     | 
    
         
            +
              subject { LogStash::Outputs::Http.new(config) }
         
     | 
| 
      
 557 
     | 
    
         
            +
             
     | 
| 
      
 558 
     | 
    
         
            +
              before { subject.register }
         
     | 
| 
      
 559 
     | 
    
         
            +
              after  { subject.close }
         
     | 
| 
      
 560 
     | 
    
         
            +
             
     | 
| 
      
 561 
     | 
    
         
            +
              let(:last_request) { TestApp.last_request }
         
     | 
| 
      
 562 
     | 
    
         
            +
              let(:last_request_body) { last_request.body.read }
         
     | 
| 
      
 563 
     | 
    
         
            +
             
     | 
| 
      
 564 
     | 
    
         
            +
              let(:event) { LogStash::Event.new("message" => "hello!") }
         
     | 
| 
      
 565 
     | 
    
         
            +
             
     | 
| 
      
 566 
     | 
    
         
            +
              context 'with default (full) verification' do
         
     | 
| 
      
 567 
     | 
    
         
            +
             
     | 
| 
      
 568 
     | 
    
         
            +
                let(:config) { super() } # 'ssl_verification_mode' => 'full'
         
     | 
| 
      
 569 
     | 
    
         
            +
             
     | 
| 
      
 570 
     | 
    
         
            +
                it "does NOT process the request (due client protocol exception)" do
         
     | 
| 
      
 571 
     | 
    
         
            +
                  # Manticore's default verification does not accept self-signed certificates!
         
     | 
| 
      
 572 
     | 
    
         
            +
                  Thread.start do
         
     | 
| 
      
 573 
     | 
    
         
            +
                    subject.multi_receive [ event ]
         
     | 
| 
      
 574 
     | 
    
         
            +
                  end
         
     | 
| 
      
 575 
     | 
    
         
            +
                  sleep 1.5
         
     | 
| 
      
 576 
     | 
    
         
            +
             
     | 
| 
      
 577 
     | 
    
         
            +
                  expect(last_request).to be nil
         
     | 
| 
      
 578 
     | 
    
         
            +
                end
         
     | 
| 
      
 579 
     | 
    
         
            +
             
     | 
| 
      
 580 
     | 
    
         
            +
              end
         
     | 
| 
      
 581 
     | 
    
         
            +
             
     | 
| 
      
 582 
     | 
    
         
            +
              context 'with verification disabled' do
         
     | 
| 
      
 583 
     | 
    
         
            +
             
     | 
| 
      
 584 
     | 
    
         
            +
                let(:config) { super().merge 'ssl_verification_mode' => 'none' }
         
     | 
| 
      
 585 
     | 
    
         
            +
             
     | 
| 
      
 586 
     | 
    
         
            +
                it "should process the request" do
         
     | 
| 
      
 587 
     | 
    
         
            +
                  subject.multi_receive [ event ]
         
     | 
| 
      
 588 
     | 
    
         
            +
                  expect(last_request_body).to include '"message":"hello!"'
         
     | 
| 
      
 589 
     | 
    
         
            +
                end
         
     | 
| 
      
 590 
     | 
    
         
            +
             
     | 
| 
      
 591 
     | 
    
         
            +
              end
         
     | 
| 
      
 592 
     | 
    
         
            +
             
     | 
| 
       400 
593 
     | 
    
         
             
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: logstash-output-http
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 5. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 5.4.1
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Elastic
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date:  
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2022-03-04 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -35,7 +35,7 @@ dependencies: 
     | 
|
| 
       35 
35 
     | 
    
         
             
                requirements:
         
     | 
| 
       36 
36 
     | 
    
         
             
                - - ">="
         
     | 
| 
       37 
37 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       38 
     | 
    
         
            -
                    version:  
     | 
| 
      
 38 
     | 
    
         
            +
                    version: 7.1.0
         
     | 
| 
       39 
39 
     | 
    
         
             
                - - "<"
         
     | 
| 
       40 
40 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       41 
41 
     | 
    
         
             
                    version: 8.0.0
         
     | 
| 
         @@ -46,7 +46,7 @@ dependencies: 
     | 
|
| 
       46 
46 
     | 
    
         
             
                requirements:
         
     | 
| 
       47 
47 
     | 
    
         
             
                - - ">="
         
     | 
| 
       48 
48 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       49 
     | 
    
         
            -
                    version:  
     | 
| 
      
 49 
     | 
    
         
            +
                    version: 7.1.0
         
     | 
| 
       50 
50 
     | 
    
         
             
                - - "<"
         
     | 
| 
       51 
51 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       52 
52 
     | 
    
         
             
                    version: 8.0.0
         
     | 
| 
         @@ -132,8 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       132 
132 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       133 
133 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       134 
134 
     | 
    
         
             
            requirements: []
         
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
            rubygems_version: 2.6.13
         
     | 
| 
      
 135 
     | 
    
         
            +
            rubygems_version: 3.1.6
         
     | 
| 
       137 
136 
     | 
    
         
             
            signing_key:
         
     | 
| 
       138 
137 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       139 
138 
     | 
    
         
             
            summary: Sends events to a generic HTTP or HTTPS endpoint
         
     |