http 0.8.8 → 0.8.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +6 -0
- data/http.gemspec +1 -0
- data/lib/http/chainable.rb +5 -0
- data/lib/http/client.rb +3 -2
- data/lib/http/headers.rb +3 -0
- data/lib/http/options.rb +17 -14
- data/lib/http/options/cookies.rb +20 -0
- data/lib/http/response.rb +9 -1
- data/lib/http/response/body.rb +2 -2
- data/lib/http/version.rb +1 -1
- data/spec/lib/http/options/merge_spec.rb +2 -1
- data/spec/lib/http/response_spec.rb +32 -12
- data/spec/lib/http_spec.rb +14 -0
- data/spec/support/dummy_server/servlet.rb +6 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e43eef7590b892ac207ac122a1ac58e61a402ba
|
4
|
+
data.tar.gz: 622380eacbab0139f5c6d1420d0df6c8c190b6d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ccc0e229a0e15aa63c30d012213258a9802a04f1ec0a1dbea67d73b2647d7380b951151d7492b43b10730e6c3dd905f64bfda4621a706747e65a976a7b37cd1
|
7
|
+
data.tar.gz: 1e2af51ecfcb07a33f2b6d94b93bc313b9018e2799e6ccc3f3265e7e2c8fde80bf97f7ff6e8c8309d8e693a08e72ae21f15b1cdb4442adc43608daba11d947b4
|
data/CHANGES.md
CHANGED
data/http.gemspec
CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |gem|
|
|
25
25
|
|
26
26
|
gem.add_runtime_dependency "http_parser.rb", "~> 0.6.0"
|
27
27
|
gem.add_runtime_dependency "http-form_data", "~> 1.0.1"
|
28
|
+
gem.add_runtime_dependency "http-cookie", "~> 1.0"
|
28
29
|
gem.add_runtime_dependency "addressable", "~> 2.3"
|
29
30
|
|
30
31
|
gem.add_development_dependency "bundler", "~> 1.0"
|
data/lib/http/chainable.rb
CHANGED
@@ -187,6 +187,11 @@ module HTTP
|
|
187
187
|
# @see #headers
|
188
188
|
alias_method :with_headers, :headers
|
189
189
|
|
190
|
+
# Make a request with the given cookies
|
191
|
+
def cookies(cookies)
|
192
|
+
branch default_options.with_cookies(cookies)
|
193
|
+
end
|
194
|
+
|
190
195
|
# Accept the given MIME type(s)
|
191
196
|
# @param type
|
192
197
|
def accept(type)
|
data/lib/http/client.rb
CHANGED
@@ -5,6 +5,7 @@ require "uri"
|
|
5
5
|
|
6
6
|
require "http/form_data"
|
7
7
|
require "http/options"
|
8
|
+
require "http/headers"
|
8
9
|
require "http/connection"
|
9
10
|
require "http/redirector"
|
10
11
|
require "http/uri"
|
@@ -31,9 +32,9 @@ module HTTP
|
|
31
32
|
def request(verb, uri, opts = {})
|
32
33
|
opts = @default_options.merge(opts)
|
33
34
|
uri = make_request_uri(uri, opts)
|
34
|
-
headers = opts.headers
|
35
|
-
proxy = opts.proxy
|
35
|
+
headers = opts.headers.merge(Headers::SET_COOKIE => opts.cookies.values)
|
36
36
|
body = make_request_body(opts, headers)
|
37
|
+
proxy = opts.proxy
|
37
38
|
|
38
39
|
# Tell the server to keep the conn open
|
39
40
|
if default_options.persistent?
|
data/lib/http/headers.rb
CHANGED
data/lib/http/options.rb
CHANGED
@@ -42,23 +42,23 @@ module HTTP
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def initialize(options = {})
|
45
|
-
defaults = {
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
45
|
+
defaults = {
|
46
|
+
:response => :auto,
|
47
|
+
:proxy => {},
|
48
|
+
:timeout_class => self.class.default_timeout_class,
|
49
|
+
:timeout_options => {},
|
50
|
+
:socket_class => self.class.default_socket_class,
|
51
|
+
:ssl_socket_class => self.class.default_ssl_socket_class,
|
52
|
+
:ssl => {},
|
53
|
+
:cache => self.class.default_cache,
|
54
|
+
:keep_alive_timeout => 5,
|
55
|
+
:headers => {},
|
56
|
+
:cookies => {}
|
57
|
+
}
|
55
58
|
|
56
59
|
opts_w_defaults = defaults.merge(options)
|
57
60
|
opts_w_defaults[:headers] = HTTP::Headers.coerce(opts_w_defaults[:headers])
|
58
|
-
|
59
|
-
opts_w_defaults.each do |(opt_name, opt_val)|
|
60
|
-
self[opt_name] = opt_val
|
61
|
-
end
|
61
|
+
opts_w_defaults.each { |(k, v)| self[k] = v }
|
62
62
|
end
|
63
63
|
|
64
64
|
def_option :headers do |headers|
|
@@ -145,3 +145,6 @@ module HTTP
|
|
145
145
|
end
|
146
146
|
end
|
147
147
|
end
|
148
|
+
|
149
|
+
# require cookies options
|
150
|
+
require "http/options/cookies"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module HTTP
|
2
|
+
class Options
|
3
|
+
# Default path of cookies
|
4
|
+
DEFAULT_COOKIE_PATH = "/".freeze
|
5
|
+
|
6
|
+
def_option :cookies do |cookies|
|
7
|
+
cookies.each_with_object self.cookies.dup do |(k, v), jar|
|
8
|
+
cookie = case
|
9
|
+
when k.is_a?(Cookie) then k
|
10
|
+
when k.is_a?(Hash) then Cookie.new k
|
11
|
+
when v.is_a?(Hash) then Cookie.new(k.to_s, v)
|
12
|
+
else Cookie.new(k.to_s, v.to_s)
|
13
|
+
end
|
14
|
+
|
15
|
+
cookie.path ||= DEFAULT_COOKIE_PATH
|
16
|
+
jar[cookie.name] = cookie.set_cookie_value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/http/response.rb
CHANGED
@@ -5,6 +5,8 @@ require "http/content_type"
|
|
5
5
|
require "http/mime_type"
|
6
6
|
require "http/response/caching"
|
7
7
|
require "http/response/status"
|
8
|
+
require "http/uri"
|
9
|
+
require "http/cookie_jar"
|
8
10
|
require "time"
|
9
11
|
|
10
12
|
module HTTP
|
@@ -32,7 +34,7 @@ module HTTP
|
|
32
34
|
def initialize(status, version, headers, body, uri = nil) # rubocop:disable ParameterLists
|
33
35
|
@version = version
|
34
36
|
@body = body
|
35
|
-
@uri = uri
|
37
|
+
@uri = uri && HTTP::URI.parse(uri)
|
36
38
|
@status = HTTP::Response::Status.new status
|
37
39
|
@headers = HTTP::Headers.coerce(headers || {})
|
38
40
|
end
|
@@ -93,6 +95,12 @@ module HTTP
|
|
93
95
|
@charset ||= content_type.charset
|
94
96
|
end
|
95
97
|
|
98
|
+
def cookies
|
99
|
+
@cookies ||= headers.each_with_object CookieJar.new do |(k, v), jar|
|
100
|
+
jar.parse(v, uri) if k == Headers::SET_COOKIE
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
96
104
|
# Parse response body with corresponding MIME type adapter.
|
97
105
|
#
|
98
106
|
# @param [#to_s] as Parse as given MIME type
|
data/lib/http/response/body.rb
CHANGED
@@ -36,9 +36,9 @@ module HTTP
|
|
36
36
|
|
37
37
|
begin
|
38
38
|
@streaming = false
|
39
|
-
@contents = ""
|
39
|
+
@contents = "".force_encoding(Encoding::UTF_8)
|
40
40
|
while (chunk = @client.readpartial)
|
41
|
-
@contents << chunk
|
41
|
+
@contents << chunk.force_encoding(Encoding::ASCII_8BIT)
|
42
42
|
end
|
43
43
|
rescue
|
44
44
|
@contents = nil
|
data/lib/http/version.rb
CHANGED
@@ -55,6 +55,7 @@ RSpec.describe HTTP::Options, "merge" do
|
|
55
55
|
:socket_class => described_class.default_socket_class,
|
56
56
|
:ssl_socket_class => described_class.default_ssl_socket_class,
|
57
57
|
:ssl_context => nil,
|
58
|
-
:cache => described_class.default_cache
|
58
|
+
:cache => described_class.default_cache,
|
59
|
+
:cookies => {})
|
59
60
|
end
|
60
61
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
RSpec.describe HTTP::Response do
|
2
2
|
let(:body) { "Hello world!" }
|
3
|
-
|
3
|
+
let(:uri) { "http://example.com/" }
|
4
|
+
let(:headers) { {} }
|
5
|
+
subject(:response) { HTTP::Response.new 200, "1.1", headers, body, uri }
|
4
6
|
|
5
7
|
it "includes HTTP::Headers::Mixin" do
|
6
8
|
expect(described_class).to include HTTP::Headers::Mixin
|
@@ -9,15 +11,15 @@ RSpec.describe HTTP::Response do
|
|
9
11
|
describe "to_a" do
|
10
12
|
let(:body) { "Hello world" }
|
11
13
|
let(:content_type) { "text/plain" }
|
12
|
-
|
14
|
+
let(:headers) { {"Content-Type" => content_type} }
|
13
15
|
|
14
16
|
it "returns a Rack-like array" do
|
15
|
-
expect(subject.to_a).to eq([200,
|
17
|
+
expect(subject.to_a).to eq([200, headers, body])
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
19
21
|
describe "mime_type" do
|
20
|
-
subject {
|
22
|
+
subject { response.mime_type }
|
21
23
|
|
22
24
|
context "without Content-Type header" do
|
23
25
|
let(:headers) { {} }
|
@@ -36,7 +38,7 @@ RSpec.describe HTTP::Response do
|
|
36
38
|
end
|
37
39
|
|
38
40
|
describe "charset" do
|
39
|
-
subject {
|
41
|
+
subject { response.charset }
|
40
42
|
|
41
43
|
context "without Content-Type header" do
|
42
44
|
let(:headers) { {} }
|
@@ -57,7 +59,6 @@ RSpec.describe HTTP::Response do
|
|
57
59
|
describe "#parse" do
|
58
60
|
let(:headers) { {"Content-Type" => content_type} }
|
59
61
|
let(:body) { '{"foo":"bar"}' }
|
60
|
-
let(:response) { HTTP::Response.new 200, "1.1", headers, body }
|
61
62
|
|
62
63
|
context "with known content type" do
|
63
64
|
let(:content_type) { "application/json" }
|
@@ -86,8 +87,7 @@ RSpec.describe HTTP::Response do
|
|
86
87
|
end
|
87
88
|
|
88
89
|
describe "#flush" do
|
89
|
-
let(:body)
|
90
|
-
let(:response) { HTTP::Response.new 200, "1.1", {}, body }
|
90
|
+
let(:body) { double :to_s => "" }
|
91
91
|
|
92
92
|
it "returns response self-reference" do
|
93
93
|
expect(response.flush).to be response
|
@@ -100,11 +100,10 @@ RSpec.describe HTTP::Response do
|
|
100
100
|
end
|
101
101
|
|
102
102
|
describe "#inspect" do
|
103
|
-
|
104
|
-
|
105
|
-
body = double :to_s => "foobar"
|
106
|
-
response = HTTP::Response.new(200, "1.1", headers, body)
|
103
|
+
let(:headers) { {:content_type => "text/plain"} }
|
104
|
+
let(:body) { double :to_s => "foobar" }
|
107
105
|
|
106
|
+
it "returns human-friendly response representation" do
|
108
107
|
expect(response.inspect).
|
109
108
|
to eq '#<HTTP::Response/1.1 200 OK {"Content-Type"=>"text/plain"}>'
|
110
109
|
end
|
@@ -114,4 +113,25 @@ RSpec.describe HTTP::Response do
|
|
114
113
|
subject { response.caching }
|
115
114
|
it { is_expected.to be_a HTTP::Response::Caching }
|
116
115
|
end
|
116
|
+
|
117
|
+
describe "#cookies" do
|
118
|
+
let(:cookies) { ["a=1", "b=2; domain=example.com", "c=3; domain=bad.org"] }
|
119
|
+
let(:headers) { {"Set-Cookie" => cookies} }
|
120
|
+
|
121
|
+
subject(:jar) { response.cookies }
|
122
|
+
|
123
|
+
it { is_expected.to be_an HTTP::CookieJar }
|
124
|
+
|
125
|
+
it "contains cookies without domain restriction" do
|
126
|
+
expect(jar.count { |c| "a" == c.name }).to eq 1
|
127
|
+
end
|
128
|
+
|
129
|
+
it "contains cookies limited to domain of request uri" do
|
130
|
+
expect(jar.count { |c| "b" == c.name }).to eq 1
|
131
|
+
end
|
132
|
+
|
133
|
+
it "does not contains cookies limited to non-requeted uri" do
|
134
|
+
expect(jar.count { |c| "c" == c.name }).to eq 0
|
135
|
+
end
|
136
|
+
end
|
117
137
|
end
|
data/spec/lib/http_spec.rb
CHANGED
@@ -131,6 +131,20 @@ RSpec.describe HTTP do
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
+
context "loading binary data" do
|
135
|
+
it "is encoded as bytes" do
|
136
|
+
response = HTTP.get "#{dummy.endpoint}/bytes"
|
137
|
+
expect(response.to_s.encoding).to eq(Encoding::ASCII_8BIT)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context "loading text" do
|
142
|
+
it "is utf-8 encoded" do
|
143
|
+
response = HTTP.get dummy.endpoint
|
144
|
+
expect(response.to_s.encoding).to eq(Encoding::UTF_8)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
134
148
|
context "posting with an explicit body" do
|
135
149
|
it "is easy" do
|
136
150
|
response = HTTP.post "#{dummy.endpoint}/body", :body => "testing-body"
|
@@ -122,5 +122,11 @@ class DummyServer < WEBrick::HTTPServer
|
|
122
122
|
res.status = 200
|
123
123
|
res["Content-Type"] = "text/html"
|
124
124
|
end
|
125
|
+
|
126
|
+
get "/bytes" do |_req, res|
|
127
|
+
bytes = [80, 75, 3, 4, 20, 0, 0, 0, 8, 0, 123, 104, 169, 70, 99, 243, 243]
|
128
|
+
res["Content-Type"] = "application/octet-stream"
|
129
|
+
res.body = bytes.pack("c*")
|
130
|
+
end
|
125
131
|
end
|
126
132
|
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: 0.8.
|
4
|
+
version: 0.8.9
|
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: 2015-05-
|
14
|
+
date: 2015-05-11 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: http_parser.rb
|
@@ -41,6 +41,20 @@ dependencies:
|
|
41
41
|
- - "~>"
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: 1.0.1
|
44
|
+
- !ruby/object:Gem::Dependency
|
45
|
+
name: http-cookie
|
46
|
+
requirement: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - "~>"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '1.0'
|
51
|
+
type: :runtime
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - "~>"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '1.0'
|
44
58
|
- !ruby/object:Gem::Dependency
|
45
59
|
name: addressable
|
46
60
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,6 +121,7 @@ files:
|
|
107
121
|
- lib/http/mime_type/adapter.rb
|
108
122
|
- lib/http/mime_type/json.rb
|
109
123
|
- lib/http/options.rb
|
124
|
+
- lib/http/options/cookies.rb
|
110
125
|
- lib/http/redirector.rb
|
111
126
|
- lib/http/request.rb
|
112
127
|
- lib/http/request/caching.rb
|