http 3.0.0 → 3.1.0
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/CHANGES.md +24 -0
- data/README.md +4 -3
- data/http.gemspec +2 -2
- data/lib/http/client.rb +1 -1
- data/lib/http/connection.rb +5 -3
- data/lib/http/request.rb +1 -1
- data/lib/http/request/body.rb +24 -22
- data/lib/http/response/body.rb +1 -0
- data/lib/http/response/parser.rb +11 -3
- data/lib/http/uri.rb +1 -0
- data/lib/http/version.rb +1 -1
- data/spec/lib/http/client_spec.rb +8 -0
- data/spec/lib/http/connection_spec.rb +63 -0
- data/spec/lib/http/request/body_spec.rb +6 -0
- data/spec/lib/http_spec.rb +6 -0
- metadata +10 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42fd5a5fec6c2e6448908c9578bf27175a291933
|
4
|
+
data.tar.gz: 03a31ca5372bf0e9e2c5dcae9a8e06d9a7e38c56
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abc5ea24f0d2eb18022994003ab416bfddaa8976fc58bb41169eac32431b70838255d9956d710581da1ec844e0c85243d7fa937c0603122a8d61211b47bc80ae
|
7
|
+
data.tar.gz: 4b25eb0dac0ad59a5688ec5298253975c8ff186dde6d181cb8276e8e2aeafe235305f3c1717bc8c4171a551bf965215c4e0f05cda30dc79cd1bd03f6a3aa204f
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
## 3.1.0 (2018-04-22)
|
2
|
+
|
3
|
+
This version backports some of the fixes and improvements made to development
|
4
|
+
version of the HTTP gem:
|
5
|
+
|
6
|
+
* Fix for `#readpartial` to respect max length argument.
|
7
|
+
([@janko-m], [@marshall-lee])
|
8
|
+
|
9
|
+
* Fix for `HTTP::Request#headline` to allow two leading slashes in path.
|
10
|
+
([@scarfacedeb])
|
11
|
+
|
12
|
+
* Fix query string building for string with newlines.
|
13
|
+
([@mikegee])
|
14
|
+
|
15
|
+
* Deallocate temporary strings in `Response::Body#to_s`.
|
16
|
+
([@janko-m])
|
17
|
+
|
18
|
+
* Add `Request::Body#source`.
|
19
|
+
([@janko-m])
|
20
|
+
|
21
|
+
|
1
22
|
## 3.0.0 (2017-10-01)
|
2
23
|
|
3
24
|
* Drop support of Ruby `2.0` and Ruby `2.1`.
|
@@ -618,3 +639,6 @@ end
|
|
618
639
|
[@janko-m]: https://github.com/janko-m
|
619
640
|
[@Bonias]: https://github.com/Bonias
|
620
641
|
[@HoneyryderChuck]: https://github.com/HoneyryderChuck
|
642
|
+
[@marshall-lee]: https://github.com/marshall-lee
|
643
|
+
[@scarfacedeb]: https://github.com/scarfacedeb
|
644
|
+
[@mikegee]: https://github.com/mikegee
|
data/README.md
CHANGED
@@ -6,9 +6,10 @@
|
|
6
6
|
[](https://coveralls.io/r/httprb/http)
|
7
7
|
[](https://github.com/httprb/http/blob/master/LICENSE.txt)
|
8
8
|
|
9
|
-
_NOTE: This is the 3.x **
|
9
|
+
_NOTE: This is the 3.x **stable** branch. For the 4.x **development** branch, please see:_
|
10
|
+
|
11
|
+
https://github.com/httprb/http/
|
10
12
|
|
11
|
-
https://github.com/httprb/http/tree/2-x-stable
|
12
13
|
|
13
14
|
## About
|
14
15
|
|
@@ -193,5 +194,5 @@ dropped.
|
|
193
194
|
|
194
195
|
## Copyright
|
195
196
|
|
196
|
-
Copyright (c) 2011-
|
197
|
+
Copyright (c) 2011-2018 Tony Arcieri, Alexey V. Zapparov, Erik Michaels-Ober, Zachary Anker.
|
197
198
|
See LICENSE.txt for further details.
|
data/http.gemspec
CHANGED
@@ -25,10 +25,10 @@ Gem::Specification.new do |gem|
|
|
25
25
|
gem.require_paths = ["lib"]
|
26
26
|
gem.version = HTTP::VERSION
|
27
27
|
|
28
|
-
gem.required_ruby_version = ">= 2.
|
28
|
+
gem.required_ruby_version = ">= 2.2"
|
29
29
|
|
30
30
|
gem.add_runtime_dependency "http_parser.rb", "~> 0.6.0"
|
31
|
-
gem.add_runtime_dependency "http-form_data", "
|
31
|
+
gem.add_runtime_dependency "http-form_data", "~> 2.0"
|
32
32
|
gem.add_runtime_dependency "http-cookie", "~> 1.0"
|
33
33
|
gem.add_runtime_dependency "addressable", "~> 2.3"
|
34
34
|
|
data/lib/http/client.rb
CHANGED
@@ -123,7 +123,7 @@ module HTTP
|
|
123
123
|
uri = HTTP::URI.parse uri
|
124
124
|
|
125
125
|
if opts.params && !opts.params.empty?
|
126
|
-
uri.
|
126
|
+
uri.query_values = uri.query_values(Array).to_a.concat(opts.params.to_a)
|
127
127
|
end
|
128
128
|
|
129
129
|
# Some proxies (seen on WEBRick) fail if URL has
|
data/lib/http/connection.rb
CHANGED
@@ -7,7 +7,7 @@ require "http/response/parser"
|
|
7
7
|
|
8
8
|
module HTTP
|
9
9
|
# A connection to the HTTP server
|
10
|
-
class Connection
|
10
|
+
class Connection # rubocop: disable Metrics/ClassLength
|
11
11
|
extend Forwardable
|
12
12
|
|
13
13
|
# Allowed values for CONNECTION header
|
@@ -85,9 +85,11 @@ module HTTP
|
|
85
85
|
def readpartial(size = BUFFER_SIZE)
|
86
86
|
return unless @pending_response
|
87
87
|
|
88
|
-
|
89
|
-
chunk
|
88
|
+
chunk = @parser.read(size)
|
89
|
+
return chunk if chunk
|
90
90
|
|
91
|
+
finished = (read_more(size) == :eof) || @parser.finished?
|
92
|
+
chunk = @parser.read(size)
|
91
93
|
finish_response if finished
|
92
94
|
|
93
95
|
chunk.to_s
|
data/lib/http/request.rb
CHANGED
data/lib/http/request/body.rb
CHANGED
@@ -3,25 +3,27 @@
|
|
3
3
|
module HTTP
|
4
4
|
class Request
|
5
5
|
class Body
|
6
|
-
|
7
|
-
@body = body
|
6
|
+
attr_reader :source
|
8
7
|
|
9
|
-
|
8
|
+
def initialize(source)
|
9
|
+
@source = source
|
10
|
+
|
11
|
+
validate_source_type!
|
10
12
|
end
|
11
13
|
|
12
14
|
# Returns size which should be used for the "Content-Length" header.
|
13
15
|
#
|
14
16
|
# @return [Integer]
|
15
17
|
def size
|
16
|
-
if @
|
17
|
-
@
|
18
|
-
elsif @
|
19
|
-
raise RequestError, "IO object must respond to #size" unless @
|
20
|
-
@
|
21
|
-
elsif @
|
18
|
+
if @source.is_a?(String)
|
19
|
+
@source.bytesize
|
20
|
+
elsif @source.respond_to?(:read)
|
21
|
+
raise RequestError, "IO object must respond to #size" unless @source.respond_to?(:size)
|
22
|
+
@source.size
|
23
|
+
elsif @source.nil?
|
22
24
|
0
|
23
25
|
else
|
24
|
-
raise RequestError, "cannot determine size of body: #{@
|
26
|
+
raise RequestError, "cannot determine size of body: #{@source.inspect}"
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
@@ -29,24 +31,24 @@ module HTTP
|
|
29
31
|
#
|
30
32
|
# @yieldparam [String]
|
31
33
|
def each(&block)
|
32
|
-
if @
|
33
|
-
yield @
|
34
|
-
elsif @
|
35
|
-
IO.copy_stream(@
|
36
|
-
elsif @
|
37
|
-
@
|
34
|
+
if @source.is_a?(String)
|
35
|
+
yield @source
|
36
|
+
elsif @source.respond_to?(:read)
|
37
|
+
IO.copy_stream(@source, ProcIO.new(block))
|
38
|
+
elsif @source.is_a?(Enumerable)
|
39
|
+
@source.each(&block)
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
41
43
|
private
|
42
44
|
|
43
|
-
def
|
44
|
-
return if @
|
45
|
-
return if @
|
46
|
-
return if @
|
47
|
-
return if @
|
45
|
+
def validate_source_type!
|
46
|
+
return if @source.is_a?(String)
|
47
|
+
return if @source.respond_to?(:read)
|
48
|
+
return if @source.is_a?(Enumerable)
|
49
|
+
return if @source.nil?
|
48
50
|
|
49
|
-
raise RequestError, "body of wrong type: #{@
|
51
|
+
raise RequestError, "body of wrong type: #{@source.class}"
|
50
52
|
end
|
51
53
|
|
52
54
|
# This class provides a "writable IO" wrapper around a proc object, with
|
data/lib/http/response/body.rb
CHANGED
data/lib/http/response/parser.rb
CHANGED
@@ -43,9 +43,17 @@ module HTTP
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
def
|
47
|
-
|
48
|
-
|
46
|
+
def read(size)
|
47
|
+
return if @chunk.nil?
|
48
|
+
|
49
|
+
if @chunk.bytesize <= size
|
50
|
+
chunk = @chunk
|
51
|
+
@chunk = nil
|
52
|
+
else
|
53
|
+
chunk = @chunk.byteslice(0, size)
|
54
|
+
@chunk[0, size] = ""
|
55
|
+
end
|
56
|
+
|
49
57
|
chunk
|
50
58
|
end
|
51
59
|
|
data/lib/http/uri.rb
CHANGED
@@ -15,6 +15,7 @@ module HTTP
|
|
15
15
|
def_delegators :@uri, :normalized_port, :port=
|
16
16
|
def_delegators :@uri, :path, :normalized_path, :path=
|
17
17
|
def_delegators :@uri, :query, :normalized_query, :query=
|
18
|
+
def_delegators :@uri, :query_values, :query_values=
|
18
19
|
def_delegators :@uri, :request_uri, :request_uri=
|
19
20
|
def_delegators :@uri, :fragment, :normalized_fragment, :fragment=
|
20
21
|
def_delegators :@uri, :omit, :join, :normalize
|
data/lib/http/version.rb
CHANGED
@@ -156,6 +156,14 @@ RSpec.describe HTTP::Client do
|
|
156
156
|
|
157
157
|
client.get("http://example.com/", :params => {:t => "1970-01-01T00:00:00Z"})
|
158
158
|
end
|
159
|
+
|
160
|
+
it 'does not convert newlines into \r\n before encoding string values' do
|
161
|
+
expect(HTTP::Request).to receive(:new) do |opts|
|
162
|
+
expect(opts[:uri].query).to eq "foo=bar%0Abaz"
|
163
|
+
end
|
164
|
+
|
165
|
+
client.get("http://example.com/", :params => {:foo => "bar\nbaz"})
|
166
|
+
end
|
159
167
|
end
|
160
168
|
|
161
169
|
describe "passing multipart form data" do
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe HTTP::Connection do
|
4
|
+
let(:req) do
|
5
|
+
HTTP::Request.new(
|
6
|
+
:verb => :get,
|
7
|
+
:uri => "http://example.com/",
|
8
|
+
:headers => {}
|
9
|
+
)
|
10
|
+
end
|
11
|
+
let(:socket) { double(:connect => nil) }
|
12
|
+
let(:timeout_class) { double(:new => socket) }
|
13
|
+
let(:opts) { HTTP::Options.new(:timeout_class => timeout_class) }
|
14
|
+
let(:connection) { HTTP::Connection.new(req, opts) }
|
15
|
+
|
16
|
+
describe "#read_headers!" do
|
17
|
+
before do
|
18
|
+
connection.instance_variable_set(:@pending_response, true)
|
19
|
+
expect(socket).to receive(:readpartial) do
|
20
|
+
<<-RESPONSE.gsub(/^\s*\| */, "").gsub(/\n/, "\r\n")
|
21
|
+
| HTTP/1.1 200 OK
|
22
|
+
| Content-Type: text
|
23
|
+
|
|
24
|
+
RESPONSE
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "reads data in parts" do
|
29
|
+
connection.read_headers!
|
30
|
+
expect(connection.headers).to eq("Content-Type" => "text")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#readpartial" do
|
35
|
+
before do
|
36
|
+
connection.instance_variable_set(:@pending_response, true)
|
37
|
+
expect(socket).to receive(:readpartial) do
|
38
|
+
<<-RESPONSE.gsub(/^\s*\| */, "").gsub(/\n/, "\r\n")
|
39
|
+
| HTTP/1.1 200 OK
|
40
|
+
| Content-Type: text
|
41
|
+
|
|
42
|
+
RESPONSE
|
43
|
+
end
|
44
|
+
expect(socket).to receive(:readpartial) { "1" }
|
45
|
+
expect(socket).to receive(:readpartial) { "23" }
|
46
|
+
expect(socket).to receive(:readpartial) { "456" }
|
47
|
+
expect(socket).to receive(:readpartial) { "78" }
|
48
|
+
expect(socket).to receive(:readpartial) { "9" }
|
49
|
+
expect(socket).to receive(:readpartial) { "0" }
|
50
|
+
expect(socket).to receive(:readpartial) { :eof }
|
51
|
+
expect(socket).to receive(:closed?) { true }
|
52
|
+
end
|
53
|
+
|
54
|
+
it "reads data in parts" do
|
55
|
+
connection.read_headers!
|
56
|
+
buffer = String.new
|
57
|
+
while (s = connection.readpartial(3))
|
58
|
+
buffer << s
|
59
|
+
end
|
60
|
+
expect(buffer).to eq "1234567890"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/spec/lib/http_spec.rb
CHANGED
@@ -41,6 +41,12 @@ RSpec.describe HTTP do
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
context "with two leading slashes in path" do
|
45
|
+
it "is allowed" do
|
46
|
+
expect { HTTP.get "#{dummy.endpoint}//" }.not_to raise_error
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
44
50
|
context "with headers" do
|
45
51
|
it "is easy" do
|
46
52
|
response = HTTP.accept("application/json").get dummy.endpoint
|
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: 3.
|
4
|
+
version: 3.1.0
|
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:
|
14
|
+
date: 2018-04-22 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: http_parser.rb
|
@@ -31,22 +31,16 @@ dependencies:
|
|
31
31
|
name: http-form_data
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
requirements:
|
34
|
-
- - "
|
35
|
-
- !ruby/object:Gem::Version
|
36
|
-
version: 2.0.0.pre.pre2
|
37
|
-
- - "<"
|
34
|
+
- - "~>"
|
38
35
|
- !ruby/object:Gem::Version
|
39
|
-
version: '
|
36
|
+
version: '2.0'
|
40
37
|
type: :runtime
|
41
38
|
prerelease: false
|
42
39
|
version_requirements: !ruby/object:Gem::Requirement
|
43
40
|
requirements:
|
44
|
-
- - "
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: 2.0.0.pre.pre2
|
47
|
-
- - "<"
|
41
|
+
- - "~>"
|
48
42
|
- !ruby/object:Gem::Version
|
49
|
-
version: '
|
43
|
+
version: '2.0'
|
50
44
|
- !ruby/object:Gem::Dependency
|
51
45
|
name: http-cookie
|
52
46
|
requirement: !ruby/object:Gem::Requirement
|
@@ -145,6 +139,7 @@ files:
|
|
145
139
|
- lib/http/version.rb
|
146
140
|
- logo.png
|
147
141
|
- spec/lib/http/client_spec.rb
|
142
|
+
- spec/lib/http/connection_spec.rb
|
148
143
|
- spec/lib/http/content_type_spec.rb
|
149
144
|
- spec/lib/http/features/auto_deflate_spec.rb
|
150
145
|
- spec/lib/http/features/auto_inflate_spec.rb
|
@@ -192,7 +187,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
192
187
|
requirements:
|
193
188
|
- - ">="
|
194
189
|
- !ruby/object:Gem::Version
|
195
|
-
version: '2.
|
190
|
+
version: '2.2'
|
196
191
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
197
192
|
requirements:
|
198
193
|
- - ">="
|
@@ -200,12 +195,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
200
195
|
version: '0'
|
201
196
|
requirements: []
|
202
197
|
rubyforge_project:
|
203
|
-
rubygems_version: 2.
|
198
|
+
rubygems_version: 2.5.2.3
|
204
199
|
signing_key:
|
205
200
|
specification_version: 4
|
206
201
|
summary: HTTP should be easy
|
207
202
|
test_files:
|
208
203
|
- spec/lib/http/client_spec.rb
|
204
|
+
- spec/lib/http/connection_spec.rb
|
209
205
|
- spec/lib/http/content_type_spec.rb
|
210
206
|
- spec/lib/http/features/auto_deflate_spec.rb
|
211
207
|
- spec/lib/http/features/auto_inflate_spec.rb
|