http 5.0.0 → 5.0.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/.github/workflows/ci.yml +2 -2
- data/CHANGES.md +81 -0
- data/Gemfile +1 -1
- data/LICENSE.txt +1 -1
- data/README.md +44 -80
- data/http.gemspec +2 -2
- data/lib/http/client.rb +8 -4
- data/lib/http/features/auto_inflate.rb +0 -2
- data/lib/http/request/writer.rb +6 -2
- data/lib/http/request.rb +15 -1
- data/lib/http/response/body.rb +6 -4
- data/lib/http/response/parser.rb +1 -1
- data/lib/http/response.rb +24 -6
- data/lib/http/timeout/global.rb +2 -4
- data/lib/http/version.rb +1 -1
- data/spec/lib/http/client_spec.rb +34 -0
- data/spec/lib/http/features/auto_inflate_spec.rb +0 -1
- data/spec/lib/http/features/instrumentation_spec.rb +0 -1
- data/spec/lib/http/features/logging_spec.rb +0 -1
- data/spec/lib/http/redirector_spec.rb +44 -0
- data/spec/lib/http/request/body_spec.rb +3 -3
- data/spec/lib/http/request/writer_spec.rb +12 -1
- data/spec/lib/http/response/body_spec.rb +5 -5
- data/spec/lib/http/response/parser_spec.rb +3 -3
- data/spec/lib/http/response_spec.rb +62 -10
- metadata +7 -7
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 92001458b2f36332dfd042ab8750595408d2be8e941ed52be9237e11c071fef7
         | 
| 4 | 
            +
              data.tar.gz: de00f9d0a8f59f3af1605f479e503269741c751b397d62d618c8866e58929140
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 63249cd08800a312ffba0ed4b9a508e3890b3088058956e5433c71a60957bfe9985070225855b926d78f5a64c3b587a122c52137788b54e10da65076b39f541f
         | 
| 7 | 
            +
              data.tar.gz: 89605690a8dd8ac3bf23447de8a75f90bc37a77d8ff0e85d84b0748daf2cf06b69011d8e19cc4b22067e479decdfc9d8ca46f7fc0495ec90c25a433e10c1eac8
         | 
    
        data/.github/workflows/ci.yml
    CHANGED
    
    
    
        data/CHANGES.md
    CHANGED
    
    | @@ -1,3 +1,65 @@ | |
| 1 | 
            +
            ## 5.0.4 (2021-10-07)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * [#698](https://github.com/httprb/http/pull/698)
         | 
| 4 | 
            +
              Fix `HTTP::Timeout::Global#connect_ssl`.
         | 
| 5 | 
            +
              ([@tarcieri])
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            ## 5.0.3 (2021-10-06)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            * [#695](https://github.com/httprb/http/pull/695)
         | 
| 10 | 
            +
              Revert DNS resolving feature.
         | 
| 11 | 
            +
              ([@PhilCoggins])
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            * [#694](https://github.com/httprb/http/pull/694)
         | 
| 14 | 
            +
              Fix cookies extraction.
         | 
| 15 | 
            +
              ([@flosacca])
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            ## 5.0.2 (2021-09-10)
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            * [#686](https://github.com/httprb/http/pull/686)
         | 
| 20 | 
            +
              Correctly reset the parser.
         | 
| 21 | 
            +
              ([@bryanp])
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            * [#684](https://github.com/httprb/http/pull/684)
         | 
| 24 | 
            +
              Don't set Content-Length for GET, HEAD, DELETE, or CONNECT requests without a BODY.
         | 
| 25 | 
            +
              ([@jyn514])
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            * [#679](https://github.com/httprb/http/pull/679)
         | 
| 28 | 
            +
              Use features on redirected requests.
         | 
| 29 | 
            +
              ([@nomis])
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            * [#678](https://github.com/schwern)
         | 
| 32 | 
            +
              Restore `HTTP::Response` `:uri` option for backwards compatibility.
         | 
| 33 | 
            +
              ([@schwern])
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            * [#676](https://github.com/httprb/http/pull/676)
         | 
| 36 | 
            +
              Update addressable because of CVE-2021-32740.
         | 
| 37 | 
            +
              ([@matheussilvasantos])
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            * [#653](https://github.com/httprb/http/pull/653)
         | 
| 40 | 
            +
              Avoid force encodings on frozen strings.
         | 
| 41 | 
            +
              ([@bvicenzo])
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            * [#638](https://github.com/httprb/http/pull/638)
         | 
| 44 | 
            +
              DNS failover handling.
         | 
| 45 | 
            +
              ([@midnight-wonderer])  
         | 
| 46 | 
            +
             | 
| 47 | 
            +
             | 
| 48 | 
            +
            ## 5.0.1 (2021-06-26)
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            * [#670](https://github.com/httprb/http/pull/670)
         | 
| 51 | 
            +
              Revert `Response#parse` behavior introduced in [#540].
         | 
| 52 | 
            +
              ([@DannyBen])
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            * [#669](https://github.com/httprb/http/pull/669)
         | 
| 55 | 
            +
              Prevent bodies from being resubmitted when following unsafe redirects.
         | 
| 56 | 
            +
              ([@odinhb])
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            * [#664](https://github.com/httprb/http/pull/664)
         | 
| 59 | 
            +
              Bump llhttp-ffi to 0.3.0.
         | 
| 60 | 
            +
              ([@bryanp])
         | 
| 61 | 
            +
             | 
| 62 | 
            +
             | 
| 1 63 | 
             
            ## 5.0.0 (2021-05-12)
         | 
| 2 64 |  | 
| 3 65 | 
             
            * [#656](https://github.com/httprb/http/pull/656)
         | 
| @@ -53,6 +115,12 @@ | |
| 53 115 | 
             
              Preserve header names casing.
         | 
| 54 116 | 
             
              ([@joshuaflanagan])
         | 
| 55 117 |  | 
| 118 | 
            +
            * [#540](https://github.com/httprb/http/pull/540)
         | 
| 119 | 
            +
              [#538](https://github.com/httprb/http/issues/538)
         | 
| 120 | 
            +
              **BREAKING CHANGE**
         | 
| 121 | 
            +
              Require explicit MIME type for Response#parse
         | 
| 122 | 
            +
              ([@ixti])
         | 
| 123 | 
            +
             | 
| 56 124 | 
             
            * [#532](https://github.com/httprb/http/pull/532)
         | 
| 57 125 | 
             
              Fix pipes support in request bodies.
         | 
| 58 126 | 
             
              ([@ixti])
         | 
| @@ -79,6 +147,9 @@ | |
| 79 147 | 
             
              Drop Ruby 2.3.x support.
         | 
| 80 148 | 
             
              ([@ixti])
         | 
| 81 149 |  | 
| 150 | 
            +
            * [3ed0c31](https://github.com/httprb/http/commit/3ed0c318eab6a8c390654cda17bf6df9e963c7d6)
         | 
| 151 | 
            +
              Drop Ruby 2.4.x support.
         | 
| 152 | 
            +
             | 
| 82 153 |  | 
| 83 154 | 
             
            ## 4.4.0 (2020-03-25)
         | 
| 84 155 |  | 
| @@ -887,3 +958,13 @@ end | |
| 887 958 | 
             
            [@semenyukdmitry]: https://github.com/semenyukdmitry
         | 
| 888 959 | 
             
            [@bryanp]: https://github.com/bryanp
         | 
| 889 960 | 
             
            [@meanphil]: https://github.com/meanphil
         | 
| 961 | 
            +
            [@odinhb]: https://github.com/odinhb
         | 
| 962 | 
            +
            [@DannyBen]: https://github.com/DannyBen
         | 
| 963 | 
            +
            [@jyn514]: https://github.com/jyn514
         | 
| 964 | 
            +
            [@bvicenzo]: https://github.com/bvicenzo
         | 
| 965 | 
            +
            [@nomis]: https://github.com/nomis
         | 
| 966 | 
            +
            [@midnight-wonderer]: https://github.com/midnight-wonderer
         | 
| 967 | 
            +
            [@schwern]: https://github.com/schwern
         | 
| 968 | 
            +
            [@matheussilvasantos]: https://github.com/matheussilvasantos
         | 
| 969 | 
            +
            [@PhilCoggins]: https://github.com/PhilCoggins
         | 
| 970 | 
            +
            [@flosacca]: https://github.com/flosacca
         | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/LICENSE.txt
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            Copyright (c) 2011- | 
| 1 | 
            +
            Copyright (c) 2011-2021 Tony Arcieri, Erik Michaels-Ober, Alexey V. Zapparov, Zachary Anker
         | 
| 2 2 |  | 
| 3 3 | 
             
            Permission is hereby granted, free of charge, to any person obtaining
         | 
| 4 4 | 
             
            a copy of this software and associated documentation files (the
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,16 +1,12 @@ | |
| 1 | 
            -
            # 
         | 
| 2 2 |  | 
| 3 | 
            -
            [![Gem Version] | 
| 4 | 
            -
            [![ | 
| 5 | 
            -
            [![ | 
| 6 | 
            -
            [![ | 
| 3 | 
            +
            [![Gem Version][gem-image]][gem-link]
         | 
| 4 | 
            +
            [![MIT licensed][license-image]][license-link]
         | 
| 5 | 
            +
            [![Build Status][build-image]][build-link]
         | 
| 6 | 
            +
            [![Code Climate][codeclimate-image]][codeclimate-link]
         | 
| 7 7 |  | 
| 8 8 | 
             
            [Documentation]
         | 
| 9 9 |  | 
| 10 | 
            -
            _NOTE: This is the 5.x **development** branch.  For the 4.x **stable** branch, please see:_
         | 
| 11 | 
            -
             | 
| 12 | 
            -
            https://github.com/httprb/http/tree/4-x-stable
         | 
| 13 | 
            -
             | 
| 14 10 | 
             
            ## About
         | 
| 15 11 |  | 
| 16 12 | 
             
            HTTP (The Gem! a.k.a. http.rb) is an easy-to-use client library for making requests
         | 
| @@ -21,63 +17,16 @@ Under the hood, http.rb uses the [llhttp] parser, a fast HTTP parsing native ext | |
| 21 17 | 
             
            This library isn't just yet another wrapper around `Net::HTTP`. It implements the HTTP
         | 
| 22 18 | 
             
            protocol natively and outsources the parsing to native extensions.
         | 
| 23 19 |  | 
| 24 | 
            -
             | 
| 25 | 
            -
            [llhttp]: https://llhttp.org/
         | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
            ## Another Ruby HTTP library? Why should I care?
         | 
| 29 | 
            -
             | 
| 30 | 
            -
            There are a lot of HTTP libraries to choose from in the Ruby ecosystem.
         | 
| 31 | 
            -
            So why would you choose this one?
         | 
| 20 | 
            +
            ### Why http.rb?
         | 
| 32 21 |  | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
            1. **Clean API**: http.rb offers an easy-to-use API that should be a
         | 
| 22 | 
            +
            - **Clean API**: http.rb offers an easy-to-use API that should be a
         | 
| 36 23 | 
             
               breath of fresh air after using something like Net::HTTP.
         | 
| 37 24 |  | 
| 38 | 
            -
             | 
| 25 | 
            +
            - **Maturity**: http.rb is one of the most mature Ruby HTTP clients, supporting
         | 
| 39 26 | 
             
               features like persistent connections and fine-grained timeouts.
         | 
| 40 27 |  | 
| 41 | 
            -
             | 
| 42 | 
            -
               http.rb achieves  | 
| 43 | 
            -
               implements the HTTP protocol in Ruby instead of C:
         | 
| 44 | 
            -
             | 
| 45 | 
            -
              | HTTP client              | Time   | Implementation        |
         | 
| 46 | 
            -
              |--------------------------|--------|-----------------------|
         | 
| 47 | 
            -
              | curb (persistent)        | 2.519  | libcurl wrapper       |
         | 
| 48 | 
            -
              | em-http-request          | 2.731  | EM + http_parser.rb   |
         | 
| 49 | 
            -
              | Typhoeus                 | 2.851  | libcurl wrapper       |
         | 
| 50 | 
            -
              | StreamlyFFI (persistent) | 2.853  | libcurl wrapper       |
         | 
| 51 | 
            -
              | http.rb (persistent)     | 2.970  | Ruby + http_parser.rb |
         | 
| 52 | 
            -
              | http.rb                  | 3.588  | Ruby + http_parser.rb |
         | 
| 53 | 
            -
              | HTTParty                 | 3.931  | Net::HTTP wrapper     |
         | 
| 54 | 
            -
              | Net::HTTP                | 3.959  | Pure Ruby             |
         | 
| 55 | 
            -
              | Net::HTTP (persistent)   | 4.043  | Pure Ruby             |
         | 
| 56 | 
            -
              | open-uri                 | 4.479  | Net::HTTP wrapper     |
         | 
| 57 | 
            -
              | Excon (persistent)       | 4.618  | Pure Ruby             |
         | 
| 58 | 
            -
              | Excon                    | 4.701  | Pure Ruby             |
         | 
| 59 | 
            -
              | RestClient               | 26.838 | Net::HTTP wrapper     |
         | 
| 60 | 
            -
             | 
| 61 | 
            -
            Benchmarks performed using excon's benchmarking tool
         | 
| 62 | 
            -
             | 
| 63 | 
            -
            DISCLAIMER: Most benchmarks you find in READMEs are crap,
         | 
| 64 | 
            -
            including this one. These are out-of-date. If you care about
         | 
| 65 | 
            -
            performance, benchmark for yourself for your own use cases!
         | 
| 66 | 
            -
             | 
| 67 | 
            -
            ## Help and Discussion
         | 
| 68 | 
            -
             | 
| 69 | 
            -
            If you need help or just want to talk about the http.rb,
         | 
| 70 | 
            -
            visit the http.rb Google Group:
         | 
| 71 | 
            -
             | 
| 72 | 
            -
            https://groups.google.com/forum/#!forum/httprb
         | 
| 73 | 
            -
             | 
| 74 | 
            -
            You can join by email by sending a message to:
         | 
| 75 | 
            -
             | 
| 76 | 
            -
            [httprb+subscribe@googlegroups.com](mailto:httprb+subscribe@googlegroups.com)
         | 
| 77 | 
            -
             | 
| 78 | 
            -
            If you believe you've found a bug, please report it at:
         | 
| 79 | 
            -
             | 
| 80 | 
            -
            https://github.com/httprb/http/issues
         | 
| 28 | 
            +
            - **Performance**: using native parsers and a clean, lightweight implementation,
         | 
| 29 | 
            +
               http.rb achieves high performance while implementing HTTP in Ruby instead of C.
         | 
| 81 30 |  | 
| 82 31 |  | 
| 83 32 | 
             
            ## Installation
         | 
| @@ -112,10 +61,9 @@ for more detailed documentation and usage notes. | |
| 112 61 |  | 
| 113 62 | 
             
            The following API documentation is also available:
         | 
| 114 63 |  | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 64 | 
            +
            - [YARD API documentation](https://www.rubydoc.info/github/httprb/http)
         | 
| 65 | 
            +
            - [Chainable module (all chainable methods)](https://www.rubydoc.info/github/httprb/http/HTTP/Chainable)
         | 
| 117 66 |  | 
| 118 | 
            -
            [documentation]: https://github.com/httprb/http/wiki
         | 
| 119 67 |  | 
| 120 68 | 
             
            ### Basic Usage
         | 
| 121 69 |  | 
| @@ -142,7 +90,7 @@ We can also obtain an `HTTP::Response::Body` object for this response: | |
| 142 90 | 
             
            ```
         | 
| 143 91 |  | 
| 144 92 | 
             
            The response body can be streamed with `HTTP::Response::Body#readpartial`.
         | 
| 145 | 
            -
            In practice, you'll want to bind the HTTP::Response::Body to a local variable
         | 
| 93 | 
            +
            In practice, you'll want to bind the `HTTP::Response::Body` to a local variable
         | 
| 146 94 | 
             
            and call `#readpartial` on it repeatedly until it returns `nil`:
         | 
| 147 95 |  | 
| 148 96 | 
             
            ```ruby
         | 
| @@ -159,13 +107,13 @@ and call `#readpartial` on it repeatedly until it returns `nil`: | |
| 159 107 |  | 
| 160 108 | 
             
            ## Supported Ruby Versions
         | 
| 161 109 |  | 
| 162 | 
            -
            This library aims to support and is [tested against][ | 
| 163 | 
            -
            versions:
         | 
| 110 | 
            +
            This library aims to support and is [tested against][build-link]
         | 
| 111 | 
            +
            the following Ruby  versions:
         | 
| 164 112 |  | 
| 165 | 
            -
             | 
| 166 | 
            -
             | 
| 167 | 
            -
             | 
| 168 | 
            -
             | 
| 113 | 
            +
            - Ruby 2.6
         | 
| 114 | 
            +
            - Ruby 2.7
         | 
| 115 | 
            +
            - Ruby 3.0
         | 
| 116 | 
            +
            - JRuby 9.2
         | 
| 169 117 |  | 
| 170 118 | 
             
            If something doesn't work on one of these versions, it's a bug.
         | 
| 171 119 |  | 
| @@ -180,20 +128,36 @@ patches in a timely fashion. If critical issues for a particular implementation | |
| 180 128 | 
             
            exist at the time of a major release, support for that Ruby version may be
         | 
| 181 129 | 
             
            dropped.
         | 
| 182 130 |  | 
| 183 | 
            -
            [travis]: http://travis-ci.org/httprb/http
         | 
| 184 | 
            -
             | 
| 185 131 |  | 
| 186 132 | 
             
            ## Contributing to http.rb
         | 
| 187 133 |  | 
| 188 | 
            -
             | 
| 189 | 
            -
             | 
| 190 | 
            -
             | 
| 191 | 
            -
             | 
| 192 | 
            -
             | 
| 193 | 
            -
             | 
| 134 | 
            +
            - Fork http.rb on GitHub
         | 
| 135 | 
            +
            - Make your changes
         | 
| 136 | 
            +
            - Ensure all tests pass (`bundle exec rake`)
         | 
| 137 | 
            +
            - Send a pull request
         | 
| 138 | 
            +
            - If we like them we'll merge them
         | 
| 139 | 
            +
            - If we've accepted a patch, feel free to ask for commit access!
         | 
| 194 140 |  | 
| 195 141 |  | 
| 196 142 | 
             
            ## Copyright
         | 
| 197 143 |  | 
| 198 | 
            -
            Copyright  | 
| 144 | 
            +
            Copyright © 2011-2021 Tony Arcieri, Alexey V. Zapparov, Erik Michaels-Ober, Zachary Anker.
         | 
| 199 145 | 
             
            See LICENSE.txt for further details.
         | 
| 146 | 
            +
             | 
| 147 | 
            +
             | 
| 148 | 
            +
            [//]: # (badges)
         | 
| 149 | 
            +
             | 
| 150 | 
            +
            [gem-image]: https://img.shields.io/gem/v/http?logo=ruby
         | 
| 151 | 
            +
            [gem-link]: https://rubygems.org/gems/http
         | 
| 152 | 
            +
            [license-image]: https://img.shields.io/badge/license-MIT-blue.svg
         | 
| 153 | 
            +
            [license-link]: https://github.com/httprb/http/blob/main/LICENSE.txt
         | 
| 154 | 
            +
            [build-image]: https://github.com/httprb/http/workflows/CI/badge.svg
         | 
| 155 | 
            +
            [build-link]: https://github.com/httprb/http/actions/workflows/ci.yml
         | 
| 156 | 
            +
            [codeclimate-image]: https://codeclimate.com/github/httprb/http.svg?branch=main
         | 
| 157 | 
            +
            [codeclimate-link]: https://codeclimate.com/github/httprb/http
         | 
| 158 | 
            +
             | 
| 159 | 
            +
            [//]: # (links)
         | 
| 160 | 
            +
             | 
| 161 | 
            +
            [documentation]: https://github.com/httprb/http/wiki
         | 
| 162 | 
            +
            [requests]: http://docs.python-requests.org/en/latest/
         | 
| 163 | 
            +
            [llhttp]: https://llhttp.org/
         | 
    
        data/http.gemspec
    CHANGED
    
    | @@ -27,10 +27,10 @@ Gem::Specification.new do |gem| | |
| 27 27 |  | 
| 28 28 | 
             
              gem.required_ruby_version = ">= 2.5"
         | 
| 29 29 |  | 
| 30 | 
            -
              gem.add_runtime_dependency "addressable",    "~> 2. | 
| 30 | 
            +
              gem.add_runtime_dependency "addressable",    "~> 2.8"
         | 
| 31 31 | 
             
              gem.add_runtime_dependency "http-cookie",    "~> 1.0"
         | 
| 32 32 | 
             
              gem.add_runtime_dependency "http-form_data", "~> 2.2"
         | 
| 33 | 
            -
              gem.add_runtime_dependency "llhttp-ffi",     "~> 0.0 | 
| 33 | 
            +
              gem.add_runtime_dependency "llhttp-ffi",     "~> 0.4.0"
         | 
| 34 34 |  | 
| 35 35 | 
             
              gem.add_development_dependency "bundler", "~> 2.0"
         | 
| 36 36 |  | 
    
        data/lib/http/client.rb
    CHANGED
    
    | @@ -32,7 +32,7 @@ module HTTP | |
| 32 32 | 
             
                  return res unless opts.follow
         | 
| 33 33 |  | 
| 34 34 | 
             
                  Redirector.new(opts.follow).perform(req, res) do |request|
         | 
| 35 | 
            -
                    perform(request, opts)
         | 
| 35 | 
            +
                    perform(wrap_request(request, opts), opts)
         | 
| 36 36 | 
             
                  end
         | 
| 37 37 | 
             
                end
         | 
| 38 38 |  | 
| @@ -52,9 +52,7 @@ module HTTP | |
| 52 52 | 
             
                    :body           => body
         | 
| 53 53 | 
             
                  )
         | 
| 54 54 |  | 
| 55 | 
            -
                   | 
| 56 | 
            -
                    feature.wrap_request(request)
         | 
| 57 | 
            -
                  end
         | 
| 55 | 
            +
                  wrap_request(req, opts)
         | 
| 58 56 | 
             
                end
         | 
| 59 57 |  | 
| 60 58 | 
             
                # @!method persistent?
         | 
| @@ -104,6 +102,12 @@ module HTTP | |
| 104 102 |  | 
| 105 103 | 
             
                private
         | 
| 106 104 |  | 
| 105 | 
            +
                def wrap_request(req, opts)
         | 
| 106 | 
            +
                  opts.features.inject(req) do |request, (_name, feature)|
         | 
| 107 | 
            +
                    feature.wrap_request(request)
         | 
| 108 | 
            +
                  end
         | 
| 109 | 
            +
                end
         | 
| 110 | 
            +
             | 
| 107 111 | 
             
                def build_response(req, options)
         | 
| 108 112 | 
             
                  Response.new(
         | 
| 109 113 | 
             
                    :status        => @connection.status_code,
         | 
    
        data/lib/http/request/writer.rb
    CHANGED
    
    | @@ -47,7 +47,11 @@ module HTTP | |
| 47 47 | 
             
                  # Adds the headers to the header array for the given request body we are working
         | 
| 48 48 | 
             
                  # with
         | 
| 49 49 | 
             
                  def add_body_type_headers
         | 
| 50 | 
            -
                    return if @headers[Headers::CONTENT_LENGTH] || chunked?
         | 
| 50 | 
            +
                    return if @headers[Headers::CONTENT_LENGTH] || chunked? || (
         | 
| 51 | 
            +
                      @body.source.nil? && %w[GET HEAD DELETE CONNECT].any? do |method|
         | 
| 52 | 
            +
                        @request_header[0].start_with?("#{method} ")
         | 
| 53 | 
            +
                      end
         | 
| 54 | 
            +
                    )
         | 
| 51 55 |  | 
| 52 56 | 
             
                    @request_header << "#{Headers::CONTENT_LENGTH}: #{@body.size}"
         | 
| 53 57 | 
             
                  end
         | 
| @@ -57,7 +61,7 @@ module HTTP | |
| 57 61 | 
             
                  def join_headers
         | 
| 58 62 | 
             
                    # join the headers array with crlfs, stick two on the end because
         | 
| 59 63 | 
             
                    # that ends the request header
         | 
| 60 | 
            -
                    @request_header.join(CRLF) + CRLF * 2
         | 
| 64 | 
            +
                    @request_header.join(CRLF) + (CRLF * 2)
         | 
| 61 65 | 
             
                  end
         | 
| 62 66 |  | 
| 63 67 | 
             
                  # Writes HTTP request data into the socket.
         | 
    
        data/lib/http/request.rb
    CHANGED
    
    | @@ -104,12 +104,26 @@ module HTTP | |
| 104 104 | 
             
                  headers = self.headers.dup
         | 
| 105 105 | 
             
                  headers.delete(Headers::HOST)
         | 
| 106 106 |  | 
| 107 | 
            +
                  new_body = body.source
         | 
| 108 | 
            +
                  if verb == :get
         | 
| 109 | 
            +
                    # request bodies should not always be resubmitted when following a redirect
         | 
| 110 | 
            +
                    # some servers will close the connection after receiving the request headers
         | 
| 111 | 
            +
                    # which may cause Errno::ECONNRESET: Connection reset by peer
         | 
| 112 | 
            +
                    # see https://github.com/httprb/http/issues/649
         | 
| 113 | 
            +
                    # new_body = Request::Body.new(nil)
         | 
| 114 | 
            +
                    new_body = nil
         | 
| 115 | 
            +
                    # the CONTENT_TYPE header causes problems if set on a get request w/ an empty body
         | 
| 116 | 
            +
                    # the server might assume that there should be content if it is set to multipart
         | 
| 117 | 
            +
                    # rack raises EmptyContentError if this happens
         | 
| 118 | 
            +
                    headers.delete(Headers::CONTENT_TYPE)
         | 
| 119 | 
            +
                  end
         | 
| 120 | 
            +
             | 
| 107 121 | 
             
                  self.class.new(
         | 
| 108 122 | 
             
                    :verb           => verb,
         | 
| 109 123 | 
             
                    :uri            => @uri.join(uri),
         | 
| 110 124 | 
             
                    :headers        => headers,
         | 
| 111 125 | 
             
                    :proxy          => proxy,
         | 
| 112 | 
            -
                    :body           =>  | 
| 126 | 
            +
                    :body           => new_body,
         | 
| 113 127 | 
             
                    :version        => version,
         | 
| 114 128 | 
             
                    :uri_normalizer => uri_normalizer
         | 
| 115 129 | 
             
                  )
         | 
    
        data/lib/http/response/body.rb
    CHANGED
    
    | @@ -27,7 +27,9 @@ module HTTP | |
| 27 27 | 
             
                  # (see HTTP::Client#readpartial)
         | 
| 28 28 | 
             
                  def readpartial(*args)
         | 
| 29 29 | 
             
                    stream!
         | 
| 30 | 
            -
                    @stream.readpartial(*args) | 
| 30 | 
            +
                    chunk = @stream.readpartial(*args)
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                    String.new(chunk, :encoding => @encoding) if chunk
         | 
| 31 33 | 
             
                  end
         | 
| 32 34 |  | 
| 33 35 | 
             
                  # Iterate over the body, allowing it to be enumerable
         | 
| @@ -45,11 +47,11 @@ module HTTP | |
| 45 47 |  | 
| 46 48 | 
             
                    begin
         | 
| 47 49 | 
             
                      @streaming  = false
         | 
| 48 | 
            -
                      @contents   = String.new("" | 
| 50 | 
            +
                      @contents   = String.new("", :encoding => @encoding)
         | 
| 49 51 |  | 
| 50 52 | 
             
                      while (chunk = @stream.readpartial)
         | 
| 51 | 
            -
                        @contents <<  | 
| 52 | 
            -
                        chunk | 
| 53 | 
            +
                        @contents << String.new(chunk, :encoding => @encoding)
         | 
| 54 | 
            +
                        chunk = nil # deallocate string
         | 
| 53 55 | 
             
                      end
         | 
| 54 56 | 
             
                    rescue
         | 
| 55 57 | 
             
                      @contents = nil
         | 
    
        data/lib/http/response/parser.rb
    CHANGED
    
    
    
        data/lib/http/response.rb
    CHANGED
    
    | @@ -40,10 +40,11 @@ module HTTP | |
| 40 40 | 
             
                # @option opts [HTTP::Connection] :connection
         | 
| 41 41 | 
             
                # @option opts [String] :encoding Encoding to use when reading body
         | 
| 42 42 | 
             
                # @option opts [String] :body
         | 
| 43 | 
            -
                # @option opts [HTTP::Request] request
         | 
| 43 | 
            +
                # @option opts [HTTP::Request] request The request this is in response to.
         | 
| 44 | 
            +
                # @option opts [String] :uri (DEPRECATED) used to populate a missing request
         | 
| 44 45 | 
             
                def initialize(opts)
         | 
| 45 46 | 
             
                  @version       = opts.fetch(:version)
         | 
| 46 | 
            -
                  @request       = opts | 
| 47 | 
            +
                  @request       = init_request(opts)
         | 
| 47 48 | 
             
                  @status        = HTTP::Response::Status.new(opts.fetch(:status))
         | 
| 48 49 | 
             
                  @headers       = HTTP::Headers.coerce(opts[:headers] || {})
         | 
| 49 50 | 
             
                  @proxy_headers = HTTP::Headers.coerce(opts[:proxy_headers] || {})
         | 
| @@ -137,8 +138,8 @@ module HTTP | |
| 137 138 | 
             
                def_delegator :content_type, :charset
         | 
| 138 139 |  | 
| 139 140 | 
             
                def cookies
         | 
| 140 | 
            -
                  @cookies ||= headers.each_with_object CookieJar.new do | | 
| 141 | 
            -
                    jar.parse(v, uri) | 
| 141 | 
            +
                  @cookies ||= headers.get(Headers::SET_COOKIE).each_with_object CookieJar.new do |v, jar|
         | 
| 142 | 
            +
                    jar.parse(v, uri)
         | 
| 142 143 | 
             
                  end
         | 
| 143 144 | 
             
                end
         | 
| 144 145 |  | 
| @@ -156,13 +157,30 @@ module HTTP | |
| 156 157 | 
             
                # @param type [#to_s] Parse as given MIME type.
         | 
| 157 158 | 
             
                # @raise (see MimeType.[])
         | 
| 158 159 | 
             
                # @return [Object]
         | 
| 159 | 
            -
                def parse(type)
         | 
| 160 | 
            -
                  MimeType[type].decode to_s
         | 
| 160 | 
            +
                def parse(type = nil)
         | 
| 161 | 
            +
                  MimeType[type || mime_type].decode to_s
         | 
| 161 162 | 
             
                end
         | 
| 162 163 |  | 
| 163 164 | 
             
                # Inspect a response
         | 
| 164 165 | 
             
                def inspect
         | 
| 165 166 | 
             
                  "#<#{self.class}/#{@version} #{code} #{reason} #{headers.to_h.inspect}>"
         | 
| 166 167 | 
             
                end
         | 
| 168 | 
            +
             | 
| 169 | 
            +
                private
         | 
| 170 | 
            +
             | 
| 171 | 
            +
                # Initialize an HTTP::Request from options.
         | 
| 172 | 
            +
                #
         | 
| 173 | 
            +
                # @return [HTTP::Request]
         | 
| 174 | 
            +
                def init_request(opts)
         | 
| 175 | 
            +
                  raise ArgumentError, ":uri is for backwards compatibilty and conflicts with :request" \
         | 
| 176 | 
            +
                    if opts[:request] && opts[:uri]
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                  # For backwards compatibilty
         | 
| 179 | 
            +
                  if opts[:uri]
         | 
| 180 | 
            +
                    HTTP::Request.new(:uri => opts[:uri], :verb => :get)
         | 
| 181 | 
            +
                  else
         | 
| 182 | 
            +
                    opts.fetch(:request)
         | 
| 183 | 
            +
                  end
         | 
| 184 | 
            +
                end
         | 
| 167 185 | 
             
              end
         | 
| 168 186 | 
             
            end
         | 
    
        data/lib/http/timeout/global.rb
    CHANGED
    
    | @@ -35,12 +35,10 @@ module HTTP | |
| 35 35 | 
             
                    begin
         | 
| 36 36 | 
             
                      @socket.connect_nonblock
         | 
| 37 37 | 
             
                    rescue IO::WaitReadable
         | 
| 38 | 
            -
                       | 
| 39 | 
            -
                      log_time
         | 
| 38 | 
            +
                      wait_readable_or_timeout
         | 
| 40 39 | 
             
                      retry
         | 
| 41 40 | 
             
                    rescue IO::WaitWritable
         | 
| 42 | 
            -
                       | 
| 43 | 
            -
                      log_time
         | 
| 41 | 
            +
                      wait_writable_or_timeout
         | 
| 44 42 | 
             
                      retry
         | 
| 45 43 | 
             
                    end
         | 
| 46 44 | 
             
                  end
         | 
    
        data/lib/http/version.rb
    CHANGED
    
    
| @@ -4,6 +4,7 @@ | |
| 4 4 | 
             
            require "support/http_handling_shared"
         | 
| 5 5 | 
             
            require "support/dummy_server"
         | 
| 6 6 | 
             
            require "support/ssl_helper"
         | 
| 7 | 
            +
            require "logger"
         | 
| 7 8 |  | 
| 8 9 | 
             
            RSpec.describe HTTP::Client do
         | 
| 9 10 | 
             
              run_server(:dummy) { DummyServer.new }
         | 
| @@ -115,6 +116,39 @@ RSpec.describe HTTP::Client do | |
| 115 116 | 
             
                end
         | 
| 116 117 | 
             
              end
         | 
| 117 118 |  | 
| 119 | 
            +
              describe "following redirects with logging" do
         | 
| 120 | 
            +
                let(:logger) do
         | 
| 121 | 
            +
                  logger           = Logger.new(logdev)
         | 
| 122 | 
            +
                  logger.formatter = ->(severity, _, _, message) { format("** %s **\n%s\n", severity, message) }
         | 
| 123 | 
            +
                  logger.level     = Logger::INFO
         | 
| 124 | 
            +
                  logger
         | 
| 125 | 
            +
                end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                let(:logdev) { StringIO.new }
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                it "logs all requests" do
         | 
| 130 | 
            +
                  client = StubbedClient.new(:follow => true, :features => { :logging => { :logger => logger } }).stub(
         | 
| 131 | 
            +
                    "http://example.com/"  => redirect_response("/1"),
         | 
| 132 | 
            +
                    "http://example.com/1" => redirect_response("/2"),
         | 
| 133 | 
            +
                    "http://example.com/2" => redirect_response("/3"),
         | 
| 134 | 
            +
                    "http://example.com/3" => simple_response("OK")
         | 
| 135 | 
            +
                  )
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                  expect { client.get("http://example.com/") }.not_to raise_error
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                  expect(logdev.string).to eq <<~OUTPUT
         | 
| 140 | 
            +
                    ** INFO **
         | 
| 141 | 
            +
                    > GET http://example.com/
         | 
| 142 | 
            +
                    ** INFO **
         | 
| 143 | 
            +
                    > GET http://example.com/1
         | 
| 144 | 
            +
                    ** INFO **
         | 
| 145 | 
            +
                    > GET http://example.com/2
         | 
| 146 | 
            +
                    ** INFO **
         | 
| 147 | 
            +
                    > GET http://example.com/3
         | 
| 148 | 
            +
                  OUTPUT
         | 
| 149 | 
            +
                end
         | 
| 150 | 
            +
              end
         | 
| 151 | 
            +
             | 
| 118 152 | 
             
              describe "parsing params" do
         | 
| 119 153 | 
             
                let(:client) { HTTP::Client.new }
         | 
| 120 154 | 
             
                before { allow(client).to receive :perform }
         | 
| @@ -74,7 +74,6 @@ RSpec.describe HTTP::Features::AutoInflate do | |
| 74 74 | 
             
                      :status     => 200,
         | 
| 75 75 | 
             
                      :headers    => {:content_encoding => "gzip"},
         | 
| 76 76 | 
             
                      :connection => connection,
         | 
| 77 | 
            -
                      :uri        => "https://example.com",
         | 
| 78 77 | 
             
                      :request    => HTTP::Request.new(:verb => :get, :uri => "https://example.com")
         | 
| 79 78 | 
             
                    )
         | 
| 80 79 | 
             
                  end
         | 
| @@ -396,5 +396,49 @@ RSpec.describe HTTP::Redirector do | |
| 396 396 | 
             
                    end
         | 
| 397 397 | 
             
                  end
         | 
| 398 398 | 
             
                end
         | 
| 399 | 
            +
             | 
| 400 | 
            +
                describe "changing verbs during redirects" do
         | 
| 401 | 
            +
                  let(:options) { {:strict => false} }
         | 
| 402 | 
            +
                  let(:post_body) { HTTP::Request::Body.new("i might be way longer in real life") }
         | 
| 403 | 
            +
                  let(:cookie) { "dont eat my cookies" }
         | 
| 404 | 
            +
             | 
| 405 | 
            +
                  def a_dangerous_request(verb)
         | 
| 406 | 
            +
                    HTTP::Request.new(
         | 
| 407 | 
            +
                      :verb => verb, :uri => "http://example.com",
         | 
| 408 | 
            +
                      :body => post_body, :headers => {
         | 
| 409 | 
            +
                        "Content-Type" => "meme",
         | 
| 410 | 
            +
                        "Cookie"       => cookie
         | 
| 411 | 
            +
                      }
         | 
| 412 | 
            +
                    )
         | 
| 413 | 
            +
                  end
         | 
| 414 | 
            +
             | 
| 415 | 
            +
                  def empty_body
         | 
| 416 | 
            +
                    HTTP::Request::Body.new(nil)
         | 
| 417 | 
            +
                  end
         | 
| 418 | 
            +
             | 
| 419 | 
            +
                  it "follows without body/content type if it has to change verb" do
         | 
| 420 | 
            +
                    req = a_dangerous_request(:post)
         | 
| 421 | 
            +
                    res = redirect_response 302, "http://example.com/1"
         | 
| 422 | 
            +
             | 
| 423 | 
            +
                    redirector.perform(req, res) do |prev_req, _|
         | 
| 424 | 
            +
                      expect(prev_req.body).to eq(empty_body)
         | 
| 425 | 
            +
                      expect(prev_req.headers["Cookie"]).to eq(cookie)
         | 
| 426 | 
            +
                      expect(prev_req.headers["Content-Type"]).to eq(nil)
         | 
| 427 | 
            +
                      simple_response 200
         | 
| 428 | 
            +
                    end
         | 
| 429 | 
            +
                  end
         | 
| 430 | 
            +
             | 
| 431 | 
            +
                  it "leaves body/content-type intact if it does not have to change verb" do
         | 
| 432 | 
            +
                    req = a_dangerous_request(:post)
         | 
| 433 | 
            +
                    res = redirect_response 307, "http://example.com/1"
         | 
| 434 | 
            +
             | 
| 435 | 
            +
                    redirector.perform(req, res) do |prev_req, _|
         | 
| 436 | 
            +
                      expect(prev_req.body).to eq(post_body)
         | 
| 437 | 
            +
                      expect(prev_req.headers["Cookie"]).to eq(cookie)
         | 
| 438 | 
            +
                      expect(prev_req.headers["Content-Type"]).to eq("meme")
         | 
| 439 | 
            +
                      simple_response 200
         | 
| 440 | 
            +
                    end
         | 
| 441 | 
            +
                  end
         | 
| 442 | 
            +
                end
         | 
| 399 443 | 
             
              end
         | 
| 400 444 | 
             
            end
         | 
| @@ -118,10 +118,10 @@ RSpec.describe HTTP::Request::Body do | |
| 118 118 | 
             
                end
         | 
| 119 119 |  | 
| 120 120 | 
             
                context "when body is a non-Enumerable IO" do
         | 
| 121 | 
            -
                  let(:body) { FakeIO.new("a" * 16 * 1024 + "b" * 10 * 1024) }
         | 
| 121 | 
            +
                  let(:body) { FakeIO.new(("a" * 16 * 1024) + ("b" * 10 * 1024)) }
         | 
| 122 122 |  | 
| 123 123 | 
             
                  it "yields chunks of content" do
         | 
| 124 | 
            -
                    expect(chunks.inject("", :+)).to eq "a" * 16 * 1024 + "b" * 10 * 1024
         | 
| 124 | 
            +
                    expect(chunks.inject("", :+)).to eq ("a" * 16 * 1024) + ("b" * 10 * 1024)
         | 
| 125 125 | 
             
                  end
         | 
| 126 126 | 
             
                end
         | 
| 127 127 |  | 
| @@ -148,7 +148,7 @@ RSpec.describe HTTP::Request::Body do | |
| 148 148 | 
             
                end
         | 
| 149 149 |  | 
| 150 150 | 
             
                context "when body is an Enumerable IO" do
         | 
| 151 | 
            -
                  let(:data) { "a" * 16 * 1024 + "b" * 10 * 1024 }
         | 
| 151 | 
            +
                  let(:data) { ("a" * 16 * 1024) + ("b" * 10 * 1024) }
         | 
| 152 152 | 
             
                  let(:body) { StringIO.new data }
         | 
| 153 153 |  | 
| 154 154 | 
             
                  it "yields chunks of content" do
         | 
| @@ -47,9 +47,20 @@ RSpec.describe HTTP::Request::Writer do | |
| 47 47 | 
             
                  end
         | 
| 48 48 | 
             
                end
         | 
| 49 49 |  | 
| 50 | 
            -
                context "when body is  | 
| 50 | 
            +
                context "when body is not set" do
         | 
| 51 51 | 
             
                  let(:body) { HTTP::Request::Body.new(nil) }
         | 
| 52 52 |  | 
| 53 | 
            +
                  it "doesn't write anything to the socket and doesn't set Content-Length" do
         | 
| 54 | 
            +
                    writer.stream
         | 
| 55 | 
            +
                    expect(io.string).to eq [
         | 
| 56 | 
            +
                      "#{headerstart}\r\n\r\n"
         | 
| 57 | 
            +
                    ].join
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                context "when body is empty" do
         | 
| 62 | 
            +
                  let(:body) { HTTP::Request::Body.new("") }
         | 
| 63 | 
            +
             | 
| 53 64 | 
             
                  it "doesn't write anything to the socket and sets Content-Length" do
         | 
| 54 65 | 
             
                    writer.stream
         | 
| 55 66 | 
             
                    expect(io.string).to eq [
         | 
| @@ -2,7 +2,7 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            RSpec.describe HTTP::Response::Body do
         | 
| 4 4 | 
             
              let(:connection) { double(:sequence_id => 0) }
         | 
| 5 | 
            -
              let(:chunks)     { [ | 
| 5 | 
            +
              let(:chunks)     { ["Hello, ", "World!"] }
         | 
| 6 6 |  | 
| 7 7 | 
             
              before do
         | 
| 8 8 | 
             
                allow(connection).to receive(:readpartial) { chunks.shift }
         | 
| @@ -16,7 +16,7 @@ RSpec.describe HTTP::Response::Body do | |
| 16 16 | 
             
              end
         | 
| 17 17 |  | 
| 18 18 | 
             
              context "when body empty" do
         | 
| 19 | 
            -
                let(:chunks) { [ | 
| 19 | 
            +
                let(:chunks) { [""] }
         | 
| 20 20 |  | 
| 21 21 | 
             
                it "returns responds to empty? with true" do
         | 
| 22 22 | 
             
                  expect(subject).to be_empty
         | 
| @@ -45,12 +45,12 @@ RSpec.describe HTTP::Response::Body do | |
| 45 45 | 
             
                it "returns content in specified encoding" do
         | 
| 46 46 | 
             
                  body = described_class.new(connection)
         | 
| 47 47 | 
             
                  expect(connection).to receive(:readpartial).
         | 
| 48 | 
            -
                    and_return(String.new("content" | 
| 48 | 
            +
                    and_return(String.new("content", :encoding => Encoding::UTF_8))
         | 
| 49 49 | 
             
                  expect(body.readpartial.encoding).to eq Encoding::BINARY
         | 
| 50 50 |  | 
| 51 51 | 
             
                  body = described_class.new(connection, :encoding => Encoding::UTF_8)
         | 
| 52 52 | 
             
                  expect(connection).to receive(:readpartial).
         | 
| 53 | 
            -
                    and_return(String.new("content" | 
| 53 | 
            +
                    and_return(String.new("content", :encoding => Encoding::BINARY))
         | 
| 54 54 | 
             
                  expect(body.readpartial.encoding).to eq Encoding::UTF_8
         | 
| 55 55 | 
             
                end
         | 
| 56 56 | 
             
              end
         | 
| @@ -59,7 +59,7 @@ RSpec.describe HTTP::Response::Body do | |
| 59 59 | 
             
                let(:chunks) do
         | 
| 60 60 | 
             
                  body = Zlib::Deflate.deflate("Hi, HTTP here ☺")
         | 
| 61 61 | 
             
                  len  = body.length
         | 
| 62 | 
            -
                  [ | 
| 62 | 
            +
                  [body[0, len / 2], body[(len / 2)..-1]]
         | 
| 63 63 | 
             
                end
         | 
| 64 64 | 
             
                subject(:body) do
         | 
| 65 65 | 
             
                  inflater = HTTP::Response::Inflater.new(connection)
         | 
| @@ -46,9 +46,9 @@ RSpec.describe HTTP::Response::Parser do | |
| 46 46 | 
             
              context "when got 100 Continue response" do
         | 
| 47 47 | 
             
                let :raw_response do
         | 
| 48 48 | 
             
                  "HTTP/1.1 100 Continue\r\n\r\n" \
         | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 49 | 
            +
                    "HTTP/1.1 200 OK\r\n" \
         | 
| 50 | 
            +
                    "Content-Length: 12\r\n\r\n" \
         | 
| 51 | 
            +
                    "Hello World!"
         | 
| 52 52 | 
             
                end
         | 
| 53 53 |  | 
| 54 54 | 
             
                context "when response is feeded in one part" do
         | 
| @@ -4,6 +4,7 @@ RSpec.describe HTTP::Response do | |
| 4 4 | 
             
              let(:body)          { "Hello world!" }
         | 
| 5 5 | 
             
              let(:uri)           { "http://example.com/" }
         | 
| 6 6 | 
             
              let(:headers)       { {} }
         | 
| 7 | 
            +
              let(:request)       { HTTP::Request.new(:verb => :get, :uri => uri) }
         | 
| 7 8 |  | 
| 8 9 | 
             
              subject(:response) do
         | 
| 9 10 | 
             
                HTTP::Response.new(
         | 
| @@ -11,8 +12,7 @@ RSpec.describe HTTP::Response do | |
| 11 12 | 
             
                  :version => "1.1",
         | 
| 12 13 | 
             
                  :headers => headers,
         | 
| 13 14 | 
             
                  :body    => body,
         | 
| 14 | 
            -
                  : | 
| 15 | 
            -
                  :request => HTTP::Request.new(:verb => :get, :uri => "http://example.com")
         | 
| 15 | 
            +
                  :request => request
         | 
| 16 16 | 
             
                )
         | 
| 17 17 | 
             
              end
         | 
| 18 18 |  | 
| @@ -87,19 +87,32 @@ RSpec.describe HTTP::Response do | |
| 87 87 | 
             
              end
         | 
| 88 88 |  | 
| 89 89 | 
             
              describe "#parse" do
         | 
| 90 | 
            -
                let(:headers)   { {"Content-Type" =>  | 
| 90 | 
            +
                let(:headers)   { {"Content-Type" => content_type} }
         | 
| 91 91 | 
             
                let(:body)      { '{"foo":"bar"}' }
         | 
| 92 92 |  | 
| 93 | 
            -
                 | 
| 94 | 
            -
                   | 
| 93 | 
            +
                context "with known content type" do
         | 
| 94 | 
            +
                  let(:content_type) { "application/json" }
         | 
| 95 | 
            +
                  it "returns parsed body" do
         | 
| 96 | 
            +
                    expect(response.parse).to eq "foo" => "bar"
         | 
| 97 | 
            +
                  end
         | 
| 95 98 | 
             
                end
         | 
| 96 99 |  | 
| 97 | 
            -
                 | 
| 98 | 
            -
                   | 
| 100 | 
            +
                context "with unknown content type" do
         | 
| 101 | 
            +
                  let(:content_type) { "application/deadbeef" }
         | 
| 102 | 
            +
                  it "raises HTTP::Error" do
         | 
| 103 | 
            +
                    expect { response.parse }.to raise_error HTTP::Error
         | 
| 104 | 
            +
                  end
         | 
| 99 105 | 
             
                end
         | 
| 100 106 |  | 
| 101 | 
            -
                 | 
| 102 | 
            -
                   | 
| 107 | 
            +
                context "with explicitly given mime type" do
         | 
| 108 | 
            +
                  let(:content_type) { "application/deadbeef" }
         | 
| 109 | 
            +
                  it "ignores mime_type of response" do
         | 
| 110 | 
            +
                    expect(response.parse("application/json")).to eq "foo" => "bar"
         | 
| 111 | 
            +
                  end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                  it "supports mime type aliases" do
         | 
| 114 | 
            +
                    expect(response.parse(:json)).to eq "foo" => "bar"
         | 
| 115 | 
            +
                  end
         | 
| 103 116 | 
             
                end
         | 
| 104 117 | 
             
              end
         | 
| 105 118 |  | 
| @@ -154,7 +167,7 @@ RSpec.describe HTTP::Response do | |
| 154 167 | 
             
                    :version    => "1.1",
         | 
| 155 168 | 
             
                    :status     => 200,
         | 
| 156 169 | 
             
                    :connection => connection,
         | 
| 157 | 
            -
                    :request    =>  | 
| 170 | 
            +
                    :request    => request
         | 
| 158 171 | 
             
                  )
         | 
| 159 172 | 
             
                end
         | 
| 160 173 |  | 
| @@ -171,4 +184,43 @@ RSpec.describe HTTP::Response do | |
| 171 184 | 
             
                end
         | 
| 172 185 | 
             
                it { is_expected.not_to be_chunked }
         | 
| 173 186 | 
             
              end
         | 
| 187 | 
            +
             | 
| 188 | 
            +
              describe "backwards compatibilty with :uri" do
         | 
| 189 | 
            +
                context "with no :verb" do
         | 
| 190 | 
            +
                  subject(:response) do
         | 
| 191 | 
            +
                    HTTP::Response.new(
         | 
| 192 | 
            +
                      :status  => 200,
         | 
| 193 | 
            +
                      :version => "1.1",
         | 
| 194 | 
            +
                      :headers => headers,
         | 
| 195 | 
            +
                      :body    => body,
         | 
| 196 | 
            +
                      :uri     => uri
         | 
| 197 | 
            +
                    )
         | 
| 198 | 
            +
                  end
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                  it "defaults the uri to :uri" do
         | 
| 201 | 
            +
                    expect(response.request.uri.to_s).to eq uri
         | 
| 202 | 
            +
                  end
         | 
| 203 | 
            +
             | 
| 204 | 
            +
                  it "defaults to the verb to :get" do
         | 
| 205 | 
            +
                    expect(response.request.verb).to eq :get
         | 
| 206 | 
            +
                  end
         | 
| 207 | 
            +
                end
         | 
| 208 | 
            +
             | 
| 209 | 
            +
                context "with both a :request and :uri" do
         | 
| 210 | 
            +
                  subject(:response) do
         | 
| 211 | 
            +
                    HTTP::Response.new(
         | 
| 212 | 
            +
                      :status  => 200,
         | 
| 213 | 
            +
                      :version => "1.1",
         | 
| 214 | 
            +
                      :headers => headers,
         | 
| 215 | 
            +
                      :body    => body,
         | 
| 216 | 
            +
                      :uri     => uri,
         | 
| 217 | 
            +
                      :request => request
         | 
| 218 | 
            +
                    )
         | 
| 219 | 
            +
                  end
         | 
| 220 | 
            +
             | 
| 221 | 
            +
                  it "raises ArgumentError" do
         | 
| 222 | 
            +
                    expect { response }.to raise_error(ArgumentError)
         | 
| 223 | 
            +
                  end
         | 
| 224 | 
            +
                end
         | 
| 225 | 
            +
              end
         | 
| 174 226 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: http
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 5.0. | 
| 4 | 
            +
              version: 5.0.4
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Tony Arcieri
         | 
| @@ -11,7 +11,7 @@ authors: | |
| 11 11 | 
             
            autorequire:
         | 
| 12 12 | 
             
            bindir: bin
         | 
| 13 13 | 
             
            cert_chain: []
         | 
| 14 | 
            -
            date: 2021- | 
| 14 | 
            +
            date: 2021-10-07 00:00:00.000000000 Z
         | 
| 15 15 | 
             
            dependencies:
         | 
| 16 16 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 17 17 | 
             
              name: addressable
         | 
| @@ -19,14 +19,14 @@ dependencies: | |
| 19 19 | 
             
                requirements:
         | 
| 20 20 | 
             
                - - "~>"
         | 
| 21 21 | 
             
                  - !ruby/object:Gem::Version
         | 
| 22 | 
            -
                    version: '2. | 
| 22 | 
            +
                    version: '2.8'
         | 
| 23 23 | 
             
              type: :runtime
         | 
| 24 24 | 
             
              prerelease: false
         | 
| 25 25 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 26 26 | 
             
                requirements:
         | 
| 27 27 | 
             
                - - "~>"
         | 
| 28 28 | 
             
                  - !ruby/object:Gem::Version
         | 
| 29 | 
            -
                    version: '2. | 
| 29 | 
            +
                    version: '2.8'
         | 
| 30 30 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 31 31 | 
             
              name: http-cookie
         | 
| 32 32 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -61,14 +61,14 @@ dependencies: | |
| 61 61 | 
             
                requirements:
         | 
| 62 62 | 
             
                - - "~>"
         | 
| 63 63 | 
             
                  - !ruby/object:Gem::Version
         | 
| 64 | 
            -
                    version: 0.0 | 
| 64 | 
            +
                    version: 0.4.0
         | 
| 65 65 | 
             
              type: :runtime
         | 
| 66 66 | 
             
              prerelease: false
         | 
| 67 67 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 68 68 | 
             
                requirements:
         | 
| 69 69 | 
             
                - - "~>"
         | 
| 70 70 | 
             
                  - !ruby/object:Gem::Version
         | 
| 71 | 
            -
                    version: 0.0 | 
| 71 | 
            +
                    version: 0.4.0
         | 
| 72 72 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 73 73 | 
             
              name: bundler
         | 
| 74 74 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -191,7 +191,7 @@ metadata: | |
| 191 191 | 
             
              source_code_uri: https://github.com/httprb/http
         | 
| 192 192 | 
             
              wiki_uri: https://github.com/httprb/http/wiki
         | 
| 193 193 | 
             
              bug_tracker_uri: https://github.com/httprb/http/issues
         | 
| 194 | 
            -
              changelog_uri: https://github.com/httprb/http/blob/v5.0. | 
| 194 | 
            +
              changelog_uri: https://github.com/httprb/http/blob/v5.0.4/CHANGES.md
         | 
| 195 195 | 
             
            post_install_message:
         | 
| 196 196 | 
             
            rdoc_options: []
         | 
| 197 197 | 
             
            require_paths:
         |