httpx 0.13.2 → 0.14.4
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/doc/release_notes/0_10_1.md +1 -1
 - data/doc/release_notes/0_13_0.md +2 -2
 - data/doc/release_notes/0_13_1.md +1 -1
 - data/doc/release_notes/0_14_0.md +79 -0
 - data/doc/release_notes/0_14_1.md +7 -0
 - data/doc/release_notes/0_14_2.md +6 -0
 - data/doc/release_notes/0_14_3.md +5 -0
 - data/doc/release_notes/0_14_4.md +5 -0
 - data/lib/httpx.rb +1 -2
 - data/lib/httpx/callbacks.rb +12 -3
 - data/lib/httpx/connection.rb +12 -9
 - data/lib/httpx/connection/http1.rb +40 -15
 - data/lib/httpx/connection/http2.rb +61 -15
 - data/lib/httpx/headers.rb +7 -3
 - data/lib/httpx/idna.rb +15 -0
 - data/lib/httpx/io/tcp.rb +1 -1
 - data/lib/httpx/options.rb +91 -56
 - data/lib/httpx/plugins/aws_sdk_authentication.rb +5 -2
 - data/lib/httpx/plugins/aws_sigv4.rb +4 -4
 - data/lib/httpx/plugins/basic_authentication.rb +8 -3
 - data/lib/httpx/plugins/compression.rb +8 -8
 - data/lib/httpx/plugins/compression/brotli.rb +4 -3
 - data/lib/httpx/plugins/compression/deflate.rb +4 -3
 - data/lib/httpx/plugins/compression/gzip.rb +2 -1
 - data/lib/httpx/plugins/cookies.rb +3 -7
 - data/lib/httpx/plugins/digest_authentication.rb +4 -4
 - data/lib/httpx/plugins/expect.rb +6 -6
 - data/lib/httpx/plugins/follow_redirects.rb +3 -3
 - data/lib/httpx/plugins/grpc.rb +247 -0
 - data/lib/httpx/plugins/grpc/call.rb +62 -0
 - data/lib/httpx/plugins/grpc/message.rb +85 -0
 - data/lib/httpx/plugins/multipart/part.rb +2 -2
 - data/lib/httpx/plugins/proxy.rb +3 -7
 - data/lib/httpx/plugins/proxy/http.rb +5 -4
 - data/lib/httpx/plugins/proxy/ssh.rb +3 -3
 - data/lib/httpx/plugins/rate_limiter.rb +1 -1
 - data/lib/httpx/plugins/retries.rb +13 -14
 - data/lib/httpx/plugins/stream.rb +96 -74
 - data/lib/httpx/plugins/upgrade.rb +4 -4
 - data/lib/httpx/request.rb +25 -2
 - data/lib/httpx/response.rb +4 -0
 - data/lib/httpx/session.rb +17 -7
 - data/lib/httpx/transcoder/chunker.rb +1 -1
 - data/lib/httpx/version.rb +1 -1
 - data/sig/callbacks.rbs +2 -0
 - data/sig/connection/http1.rbs +5 -1
 - data/sig/connection/http2.rbs +6 -2
 - data/sig/headers.rbs +2 -2
 - data/sig/options.rbs +9 -2
 - data/sig/plugins/aws_sdk_authentication.rbs +2 -0
 - data/sig/plugins/basic_authentication.rbs +2 -0
 - data/sig/plugins/compression.rbs +2 -2
 - data/sig/plugins/multipart.rbs +1 -1
 - data/sig/plugins/stream.rbs +17 -16
 - data/sig/request.rbs +7 -2
 - data/sig/response.rbs +1 -0
 - data/sig/session.rbs +4 -0
 - metadata +19 -7
 - data/lib/httpx/timeout.rb +0 -67
 - data/sig/timeout.rbs +0 -29
 
    
        data/lib/httpx/plugins/proxy.rb
    CHANGED
    
    | 
         @@ -67,13 +67,9 @@ module HTTPX 
     | 
|
| 
       67 
67 
     | 
    
         | 
| 
       68 
68 
     | 
    
         
             
                    def extra_options(options)
         
     | 
| 
       69 
69 
     | 
    
         
             
                      Class.new(options.class) do
         
     | 
| 
       70 
     | 
    
         
            -
                        def_option(:proxy) 
     | 
| 
       71 
     | 
    
         
            -
                           
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
                          else
         
     | 
| 
       74 
     | 
    
         
            -
                            Hash[pr]
         
     | 
| 
       75 
     | 
    
         
            -
                          end
         
     | 
| 
       76 
     | 
    
         
            -
                        end
         
     | 
| 
      
 70 
     | 
    
         
            +
                        def_option(:proxy, <<-OUT)
         
     | 
| 
      
 71 
     | 
    
         
            +
                          value.is_a?(#{Parameters}) ? value : Hash[value]
         
     | 
| 
      
 72 
     | 
    
         
            +
                        OUT
         
     | 
| 
       77 
73 
     | 
    
         
             
                      end.new(options)
         
     | 
| 
       78 
74 
     | 
    
         
             
                    end
         
     | 
| 
       79 
75 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -82,11 +82,12 @@ module HTTPX 
     | 
|
| 
       82 
82 
     | 
    
         
             
                      end
         
     | 
| 
       83 
83 
     | 
    
         | 
| 
       84 
84 
     | 
    
         
             
                      def set_protocol_headers(request)
         
     | 
| 
       85 
     | 
    
         
            -
                        super
         
     | 
| 
      
 85 
     | 
    
         
            +
                        extra_headers = super
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
       86 
87 
     | 
    
         
             
                        proxy_params = @options.proxy
         
     | 
| 
       87 
     | 
    
         
            -
                         
     | 
| 
       88 
     | 
    
         
            -
                         
     | 
| 
       89 
     | 
    
         
            -
                         
     | 
| 
      
 88 
     | 
    
         
            +
                        extra_headers["proxy-authorization"] = "Basic #{proxy_params.token_authentication}" if proxy_params.authenticated?
         
     | 
| 
      
 89 
     | 
    
         
            +
                        extra_headers["proxy-connection"] = extra_headers.delete("connection") if extra_headers.key?("connection")
         
     | 
| 
      
 90 
     | 
    
         
            +
                        extra_headers
         
     | 
| 
       90 
91 
     | 
    
         
             
                      end
         
     | 
| 
       91 
92 
     | 
    
         
             
                    end
         
     | 
| 
       92 
93 
     | 
    
         | 
| 
         @@ -25,31 +25,30 @@ module HTTPX 
     | 
|
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
                  def self.extra_options(options)
         
     | 
| 
       27 
27 
     | 
    
         
             
                    Class.new(options.class) do
         
     | 
| 
       28 
     | 
    
         
            -
                       
     | 
| 
       29 
     | 
    
         
            -
                      def_option(:retry_after) do |num|
         
     | 
| 
      
 28 
     | 
    
         
            +
                      def_option(:retry_after, <<-OUT)
         
     | 
| 
       30 
29 
     | 
    
         
             
                        # return early if callable
         
     | 
| 
       31 
     | 
    
         
            -
                        unless  
     | 
| 
       32 
     | 
    
         
            -
                           
     | 
| 
       33 
     | 
    
         
            -
                          raise Error, ":retry_after must be positive" unless  
     | 
| 
      
 30 
     | 
    
         
            +
                        unless value.respond_to?(:call)
         
     | 
| 
      
 31 
     | 
    
         
            +
                          value = Integer(value)
         
     | 
| 
      
 32 
     | 
    
         
            +
                          raise Error, ":retry_after must be positive" unless value.positive?
         
     | 
| 
       34 
33 
     | 
    
         
             
                        end
         
     | 
| 
       35 
34 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
                         
     | 
| 
       37 
     | 
    
         
            -
                       
     | 
| 
      
 35 
     | 
    
         
            +
                        value
         
     | 
| 
      
 36 
     | 
    
         
            +
                      OUT
         
     | 
| 
       38 
37 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
                      def_option(:max_retries) 
     | 
| 
       40 
     | 
    
         
            -
                        num = Integer( 
     | 
| 
      
 38 
     | 
    
         
            +
                      def_option(:max_retries, <<-OUT)
         
     | 
| 
      
 39 
     | 
    
         
            +
                        num = Integer(value)
         
     | 
| 
       41 
40 
     | 
    
         
             
                        raise Error, ":max_retries must be positive" unless num.positive?
         
     | 
| 
       42 
41 
     | 
    
         | 
| 
       43 
42 
     | 
    
         
             
                        num
         
     | 
| 
       44 
     | 
    
         
            -
                       
     | 
| 
      
 43 
     | 
    
         
            +
                      OUT
         
     | 
| 
       45 
44 
     | 
    
         | 
| 
       46 
45 
     | 
    
         
             
                      def_option(:retry_change_requests)
         
     | 
| 
       47 
46 
     | 
    
         | 
| 
       48 
     | 
    
         
            -
                      def_option(:retry_on) 
     | 
| 
       49 
     | 
    
         
            -
                        raise ":retry_on must be called with the response" unless  
     | 
| 
      
 47 
     | 
    
         
            +
                      def_option(:retry_on, <<-OUT)
         
     | 
| 
      
 48 
     | 
    
         
            +
                        raise ":retry_on must be called with the response" unless value.respond_to?(:call)
         
     | 
| 
       50 
49 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
                         
     | 
| 
       52 
     | 
    
         
            -
                       
     | 
| 
      
 50 
     | 
    
         
            +
                        value
         
     | 
| 
      
 51 
     | 
    
         
            +
                      OUT
         
     | 
| 
       53 
52 
     | 
    
         
             
                    end.new(options).merge(max_retries: MAX_RETRIES)
         
     | 
| 
       54 
53 
     | 
    
         
             
                  end
         
     | 
| 
       55 
54 
     | 
    
         | 
    
        data/lib/httpx/plugins/stream.rb
    CHANGED
    
    | 
         @@ -1,6 +1,93 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module HTTPX
         
     | 
| 
      
 4 
     | 
    
         
            +
              class StreamResponse
         
     | 
| 
      
 5 
     | 
    
         
            +
                def initialize(request, session, connections)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @request = request
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @session = session
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @connections = connections
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @options = @request.options
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def each(&block)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  return enum_for(__method__) unless block_given?
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  raise Error, "response already streamed" if @response
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  @request.stream = self
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 20 
     | 
    
         
            +
                    @on_chunk = block
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    if @request.response
         
     | 
| 
      
 23 
     | 
    
         
            +
                      # if we've already started collecting the payload, yield it first
         
     | 
| 
      
 24 
     | 
    
         
            +
                      # before proceeding
         
     | 
| 
      
 25 
     | 
    
         
            +
                      body = @request.response.body
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                      body.each do |chunk|
         
     | 
| 
      
 28 
     | 
    
         
            +
                        on_chunk(chunk)
         
     | 
| 
      
 29 
     | 
    
         
            +
                      end
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                    response.raise_for_status
         
     | 
| 
      
 33 
     | 
    
         
            +
                    response.close
         
     | 
| 
      
 34 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 35 
     | 
    
         
            +
                    @on_chunk = nil
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                def each_line
         
     | 
| 
      
 40 
     | 
    
         
            +
                  return enum_for(__method__) unless block_given?
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  line = +""
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  each do |chunk|
         
     | 
| 
      
 45 
     | 
    
         
            +
                    line << chunk
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                    while (idx = line.index("\n"))
         
     | 
| 
      
 48 
     | 
    
         
            +
                      yield line.byteslice(0..idx - 1)
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                      line = line.byteslice(idx + 1..-1)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    end
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                # This is a ghost method. It's to be used ONLY internally, when processing streams
         
     | 
| 
      
 56 
     | 
    
         
            +
                def on_chunk(chunk)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  raise NoMethodError unless @on_chunk
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  @on_chunk.call(chunk)
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
      
 63 
     | 
    
         
            +
                def inspect
         
     | 
| 
      
 64 
     | 
    
         
            +
                  "#<StreamResponse:#{object_id}>"
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
                # :nocov:
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                def to_s
         
     | 
| 
      
 69 
     | 
    
         
            +
                  response.to_s
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                private
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                def response
         
     | 
| 
      
 75 
     | 
    
         
            +
                  @session.__send__(:receive_requests, [@request], @connections, @options) until @request.response
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  @request.response
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                def respond_to_missing?(meth, *args)
         
     | 
| 
      
 81 
     | 
    
         
            +
                  response.respond_to?(meth, *args) || super
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                def method_missing(meth, *args, &block)
         
     | 
| 
      
 85 
     | 
    
         
            +
                  return super unless response.respond_to?(meth)
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                  response.__send__(meth, *args, &block)
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
              end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
       4 
91 
     | 
    
         
             
              module Plugins
         
     | 
| 
       5 
92 
     | 
    
         
             
                #
         
     | 
| 
       6 
93 
     | 
    
         
             
                # This plugin adds support for stream response (text/event-stream).
         
     | 
| 
         @@ -15,10 +102,13 @@ module HTTPX 
     | 
|
| 
       15 
102 
     | 
    
         
             
                      return super(*args, **options) unless stream
         
     | 
| 
       16 
103 
     | 
    
         | 
| 
       17 
104 
     | 
    
         
             
                      requests = args.first.is_a?(Request) ? args : build_requests(*args, options)
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
105 
     | 
    
         
             
                      raise Error, "only 1 response at a time is supported for streaming requests" unless requests.size == 1
         
     | 
| 
       20 
106 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
                       
     | 
| 
      
 107 
     | 
    
         
            +
                      request = requests.first
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                      connections = _send_requests(requests, request.options)
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                      StreamResponse.new(request, self, connections)
         
     | 
| 
       22 
112 
     | 
    
         
             
                    end
         
     | 
| 
       23 
113 
     | 
    
         
             
                  end
         
     | 
| 
       24 
114 
     | 
    
         | 
| 
         @@ -53,78 +143,10 @@ module HTTPX 
     | 
|
| 
       53 
143 
     | 
    
         
             
                    end
         
     | 
| 
       54 
144 
     | 
    
         
             
                  end
         
     | 
| 
       55 
145 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
                   
     | 
| 
       57 
     | 
    
         
            -
                     
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
                      @options = @request.options
         
     | 
| 
       61 
     | 
    
         
            -
                    end
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                    def each(&block)
         
     | 
| 
       64 
     | 
    
         
            -
                      return enum_for(__method__) unless block_given?
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                      raise Error, "response already streamed" if @response
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
                      @request.stream = self
         
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
                      begin
         
     | 
| 
       71 
     | 
    
         
            -
                        @on_chunk = block
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
                        response.raise_for_status
         
     | 
| 
       74 
     | 
    
         
            -
                        response.close
         
     | 
| 
       75 
     | 
    
         
            -
                      ensure
         
     | 
| 
       76 
     | 
    
         
            -
                        @on_chunk = nil
         
     | 
| 
       77 
     | 
    
         
            -
                      end
         
     | 
| 
       78 
     | 
    
         
            -
                    end
         
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
                    def each_line
         
     | 
| 
       81 
     | 
    
         
            -
                      return enum_for(__method__) unless block_given?
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
                      line = +""
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                      each do |chunk|
         
     | 
| 
       86 
     | 
    
         
            -
                        line << chunk
         
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
                        while (idx = line.index("\n"))
         
     | 
| 
       89 
     | 
    
         
            -
                          yield line.byteslice(0..idx - 1)
         
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
                          line = line.byteslice(idx + 1..-1)
         
     | 
| 
       92 
     | 
    
         
            -
                        end
         
     | 
| 
       93 
     | 
    
         
            -
                      end
         
     | 
| 
       94 
     | 
    
         
            -
                    end
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
                    # This is a ghost method. It's to be used ONLY internally, when processing streams
         
     | 
| 
       97 
     | 
    
         
            -
                    def on_chunk(chunk)
         
     | 
| 
       98 
     | 
    
         
            -
                      raise NoMethodError unless @on_chunk
         
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
                      @on_chunk.call(chunk)
         
     | 
| 
       101 
     | 
    
         
            -
                    end
         
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
                    # :nocov:
         
     | 
| 
       104 
     | 
    
         
            -
                    def inspect
         
     | 
| 
       105 
     | 
    
         
            -
                      "#<StreamResponse:#{object_id}>"
         
     | 
| 
       106 
     | 
    
         
            -
                    end
         
     | 
| 
       107 
     | 
    
         
            -
                    # :nocov:
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
                    def to_s
         
     | 
| 
       110 
     | 
    
         
            -
                      response.to_s
         
     | 
| 
       111 
     | 
    
         
            -
                    end
         
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
                    private
         
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
                    def response
         
     | 
| 
       116 
     | 
    
         
            -
                      @response ||= @session.__send__(:send_requests, @request, @options).first
         
     | 
| 
       117 
     | 
    
         
            -
                    end
         
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
                    def respond_to_missing?(*args)
         
     | 
| 
       120 
     | 
    
         
            -
                      @options.response_class.respond_to?(*args) || super
         
     | 
| 
       121 
     | 
    
         
            -
                    end
         
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
                    def method_missing(meth, *args, &block)
         
     | 
| 
       124 
     | 
    
         
            -
                      return super unless @options.response_class.public_method_defined?(meth)
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
                      response.__send__(meth, *args, &block)
         
     | 
| 
       127 
     | 
    
         
            -
                    end
         
     | 
| 
      
 146 
     | 
    
         
            +
                  def self.const_missing(const_name)
         
     | 
| 
      
 147 
     | 
    
         
            +
                    super unless const_name == :StreamResponse
         
     | 
| 
      
 148 
     | 
    
         
            +
                    warn "DEPRECATION WARNING: the class #{self}::StreamResponse is deprecated. Use HTTPX::StreamResponse instead."
         
     | 
| 
      
 149 
     | 
    
         
            +
                    HTTPX::StreamResponse
         
     | 
| 
       128 
150 
     | 
    
         
             
                  end
         
     | 
| 
       129 
151 
     | 
    
         
             
                end
         
     | 
| 
       130 
152 
     | 
    
         
             
                register_plugin :stream, Stream
         
     | 
| 
         @@ -20,11 +20,11 @@ module HTTPX 
     | 
|
| 
       20 
20 
     | 
    
         
             
                      end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
                      Class.new(options.class) do
         
     | 
| 
       23 
     | 
    
         
            -
                        def_option(:upgrade_handlers) 
     | 
| 
       24 
     | 
    
         
            -
                          raise Error, ":upgrade_handlers must be a registry" unless  
     | 
| 
      
 23 
     | 
    
         
            +
                        def_option(:upgrade_handlers, <<-OUT)
         
     | 
| 
      
 24 
     | 
    
         
            +
                          raise Error, ":upgrade_handlers must be a registry" unless value.respond_to?(:registry)
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
                           
     | 
| 
       27 
     | 
    
         
            -
                         
     | 
| 
      
 26 
     | 
    
         
            +
                          value
         
     | 
| 
      
 27 
     | 
    
         
            +
                        OUT
         
     | 
| 
       28 
28 
     | 
    
         
             
                      end.new(options).merge(upgrade_handlers: upgrade_handlers)
         
     | 
| 
       29 
29 
     | 
    
         
             
                    end
         
     | 
| 
       30 
30 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/httpx/request.rb
    CHANGED
    
    | 
         @@ -35,14 +35,22 @@ module HTTPX 
     | 
|
| 
       35 
35 
     | 
    
         | 
| 
       36 
36 
     | 
    
         
             
                attr_reader :verb, :uri, :headers, :body, :state, :options, :response
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
      
 38 
     | 
    
         
            +
                # Exception raised during enumerable body writes
         
     | 
| 
      
 39 
     | 
    
         
            +
                attr_reader :drain_error
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
       38 
41 
     | 
    
         
             
                def_delegator :@body, :empty?
         
     | 
| 
       39 
42 
     | 
    
         | 
| 
       40 
43 
     | 
    
         
             
                def_delegator :@body, :chunk!
         
     | 
| 
       41 
44 
     | 
    
         | 
| 
       42 
45 
     | 
    
         
             
                def initialize(verb, uri, options = {})
         
     | 
| 
       43 
46 
     | 
    
         
             
                  @verb    = verb.to_s.downcase.to_sym
         
     | 
| 
       44 
     | 
    
         
            -
                  @uri     = Utils.uri(uri)
         
     | 
| 
       45 
47 
     | 
    
         
             
                  @options = Options.new(options)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  @uri     = Utils.uri(uri)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  if @uri.relative?
         
     | 
| 
      
 50 
     | 
    
         
            +
                    raise(Error, "invalid URI: #{@uri}") unless @options.origin
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                    @uri = @options.origin.merge(@uri)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
       46 
54 
     | 
    
         | 
| 
       47 
55 
     | 
    
         
             
                  raise(Error, "unknown method: #{verb}") unless METHODS.include?(@verb)
         
     | 
| 
       48 
56 
     | 
    
         | 
| 
         @@ -54,6 +62,14 @@ module HTTPX 
     | 
|
| 
       54 
62 
     | 
    
         
             
                  @state = :idle
         
     | 
| 
       55 
63 
     | 
    
         
             
                end
         
     | 
| 
       56 
64 
     | 
    
         | 
| 
      
 65 
     | 
    
         
            +
                def trailers?
         
     | 
| 
      
 66 
     | 
    
         
            +
                  defined?(@trailers)
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                def trailers
         
     | 
| 
      
 70 
     | 
    
         
            +
                  @trailers ||= @options.headers_class.new
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
       57 
73 
     | 
    
         
             
                def interests
         
     | 
| 
       58 
74 
     | 
    
         
             
                  return :r if @state == :done || @state == :expect
         
     | 
| 
       59 
75 
     | 
    
         | 
| 
         @@ -124,6 +140,9 @@ module HTTPX 
     | 
|
| 
       124 
140 
     | 
    
         
             
                  chunk.dup
         
     | 
| 
       125 
141 
     | 
    
         
             
                rescue StopIteration
         
     | 
| 
       126 
142 
     | 
    
         
             
                  nil
         
     | 
| 
      
 143 
     | 
    
         
            +
                rescue StandardError => e
         
     | 
| 
      
 144 
     | 
    
         
            +
                  @drain_error = e
         
     | 
| 
      
 145 
     | 
    
         
            +
                  nil
         
     | 
| 
       127 
146 
     | 
    
         
             
                end
         
     | 
| 
       128 
147 
     | 
    
         | 
| 
       129 
148 
     | 
    
         
             
                # :nocov:
         
     | 
| 
         @@ -200,7 +219,9 @@ module HTTPX 
     | 
|
| 
       200 
219 
     | 
    
         
             
                  end
         
     | 
| 
       201 
220 
     | 
    
         | 
| 
       202 
221 
     | 
    
         
             
                  def unbounded_body?
         
     | 
| 
       203 
     | 
    
         
            -
                     
     | 
| 
      
 222 
     | 
    
         
            +
                    return @unbounded_body if defined?(@unbounded_body)
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
                    @unbounded_body = (chunked? || @body.bytesize == Float::INFINITY)
         
     | 
| 
       204 
225 
     | 
    
         
             
                  end
         
     | 
| 
       205 
226 
     | 
    
         | 
| 
       206 
227 
     | 
    
         
             
                  def chunked?
         
     | 
| 
         @@ -253,6 +274,8 @@ module HTTPX 
     | 
|
| 
       253 
274 
     | 
    
         
             
                        nextstate = :expect
         
     | 
| 
       254 
275 
     | 
    
         
             
                      end
         
     | 
| 
       255 
276 
     | 
    
         
             
                    end
         
     | 
| 
      
 277 
     | 
    
         
            +
                  when :trailers
         
     | 
| 
      
 278 
     | 
    
         
            +
                    return unless @state == :body
         
     | 
| 
       256 
279 
     | 
    
         
             
                  when :done
         
     | 
| 
       257 
280 
     | 
    
         
             
                    return if @state == :expect
         
     | 
| 
       258 
281 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/httpx/response.rb
    CHANGED
    
    
    
        data/lib/httpx/session.rb
    CHANGED
    
    | 
         @@ -77,7 +77,7 @@ module HTTPX 
     | 
|
| 
       77 
77 
     | 
    
         
             
                end
         
     | 
| 
       78 
78 
     | 
    
         | 
| 
       79 
79 
     | 
    
         
             
                def set_connection_callbacks(connection, connections, options)
         
     | 
| 
       80 
     | 
    
         
            -
                  connection. 
     | 
| 
      
 80 
     | 
    
         
            +
                  connection.only(:misdirected) do |misdirected_request|
         
     | 
| 
       81 
81 
     | 
    
         
             
                    other_connection = connection.create_idle(ssl: { alpn_protocols: %w[http/1.1] })
         
     | 
| 
       82 
82 
     | 
    
         
             
                    other_connection.merge(connection)
         
     | 
| 
       83 
83 
     | 
    
         
             
                    catch(:coalesced) do
         
     | 
| 
         @@ -88,11 +88,11 @@ module HTTPX 
     | 
|
| 
       88 
88 
     | 
    
         
             
                    misdirected_request.transition(:idle)
         
     | 
| 
       89 
89 
     | 
    
         
             
                    other_connection.send(misdirected_request)
         
     | 
| 
       90 
90 
     | 
    
         
             
                  end
         
     | 
| 
       91 
     | 
    
         
            -
                  connection. 
     | 
| 
      
 91 
     | 
    
         
            +
                  connection.only(:altsvc) do |alt_origin, origin, alt_params|
         
     | 
| 
       92 
92 
     | 
    
         
             
                    other_connection = build_altsvc_connection(connection, connections, alt_origin, origin, alt_params, options)
         
     | 
| 
       93 
93 
     | 
    
         
             
                    connections << other_connection if other_connection
         
     | 
| 
       94 
94 
     | 
    
         
             
                  end
         
     | 
| 
       95 
     | 
    
         
            -
                  connection. 
     | 
| 
      
 95 
     | 
    
         
            +
                  connection.only(:exhausted) do
         
     | 
| 
       96 
96 
     | 
    
         
             
                    other_connection = connection.create_idle
         
     | 
| 
       97 
97 
     | 
    
         
             
                    other_connection.merge(connection)
         
     | 
| 
       98 
98 
     | 
    
         
             
                    catch(:coalesced) do
         
     | 
| 
         @@ -175,12 +175,18 @@ module HTTPX 
     | 
|
| 
       175 
175 
     | 
    
         
             
                end
         
     | 
| 
       176 
176 
     | 
    
         | 
| 
       177 
177 
     | 
    
         
             
                def send_requests(*requests, options)
         
     | 
| 
       178 
     | 
    
         
            -
                  connections = []
         
     | 
| 
       179 
178 
     | 
    
         
             
                  request_options = @options.merge(options)
         
     | 
| 
       180 
179 
     | 
    
         | 
| 
      
 180 
     | 
    
         
            +
                  connections = _send_requests(requests, request_options)
         
     | 
| 
      
 181 
     | 
    
         
            +
                  receive_requests(requests, connections, request_options)
         
     | 
| 
      
 182 
     | 
    
         
            +
                end
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
                def _send_requests(requests, options)
         
     | 
| 
      
 185 
     | 
    
         
            +
                  connections = []
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
       181 
187 
     | 
    
         
             
                  requests.each do |request|
         
     | 
| 
       182 
188 
     | 
    
         
             
                    error = catch(:resolve_error) do
         
     | 
| 
       183 
     | 
    
         
            -
                      connection = find_connection(request, connections,  
     | 
| 
      
 189 
     | 
    
         
            +
                      connection = find_connection(request, connections, options)
         
     | 
| 
       184 
190 
     | 
    
         
             
                      connection.send(request)
         
     | 
| 
       185 
191 
     | 
    
         
             
                    end
         
     | 
| 
       186 
192 
     | 
    
         
             
                    next unless error.is_a?(ResolveError)
         
     | 
| 
         @@ -188,13 +194,17 @@ module HTTPX 
     | 
|
| 
       188 
194 
     | 
    
         
             
                    request.emit(:response, ErrorResponse.new(request, error, options))
         
     | 
| 
       189 
195 
     | 
    
         
             
                  end
         
     | 
| 
       190 
196 
     | 
    
         | 
| 
      
 197 
     | 
    
         
            +
                  connections
         
     | 
| 
      
 198 
     | 
    
         
            +
                end
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
                def receive_requests(requests, connections, options)
         
     | 
| 
       191 
201 
     | 
    
         
             
                  responses = []
         
     | 
| 
       192 
202 
     | 
    
         | 
| 
       193 
203 
     | 
    
         
             
                  begin
         
     | 
| 
       194 
204 
     | 
    
         
             
                    # guarantee ordered responses
         
     | 
| 
       195 
205 
     | 
    
         
             
                    loop do
         
     | 
| 
       196 
206 
     | 
    
         
             
                      request = requests.first
         
     | 
| 
       197 
     | 
    
         
            -
                      pool.next_tick until (response = fetch_response(request, connections,  
     | 
| 
      
 207 
     | 
    
         
            +
                      pool.next_tick until (response = fetch_response(request, connections, options))
         
     | 
| 
       198 
208 
     | 
    
         | 
| 
       199 
209 
     | 
    
         
             
                      responses << response
         
     | 
| 
       200 
210 
     | 
    
         
             
                      requests.shift
         
     | 
| 
         @@ -208,7 +218,7 @@ module HTTPX 
     | 
|
| 
       208 
218 
     | 
    
         
             
                      # opportunity to traverse the requests, hence we're returning only a fraction of the errors
         
     | 
| 
       209 
219 
     | 
    
         
             
                      # we were supposed to. This effectively fetches the existing responses and return them.
         
     | 
| 
       210 
220 
     | 
    
         
             
                      while (request = requests.shift)
         
     | 
| 
       211 
     | 
    
         
            -
                        responses << fetch_response(request, connections,  
     | 
| 
      
 221 
     | 
    
         
            +
                        responses << fetch_response(request, connections, options)
         
     | 
| 
       212 
222 
     | 
    
         
             
                      end
         
     | 
| 
       213 
223 
     | 
    
         
             
                      break
         
     | 
| 
       214 
224 
     | 
    
         
             
                    end
         
     |