http 0.8.14 → 0.9.0.pre
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 +3 -7
- data/Gemfile +3 -6
- data/README.md +12 -22
- data/lib/http/chainable.rb +0 -8
- data/lib/http/client.rb +9 -11
- data/lib/http/errors.rb +0 -3
- data/lib/http/options.rb +12 -27
- data/lib/http/request.rb +2 -21
- data/lib/http/response.rb +0 -6
- data/lib/http/timeout/null.rb +24 -1
- data/lib/http/timeout/per_operation.rb +8 -24
- data/lib/http/uri.rb +2 -7
- data/lib/http/version.rb +1 -1
- data/spec/lib/http/client_spec.rb +1 -31
- data/spec/lib/http/options/merge_spec.rb +0 -1
- data/spec/lib/http/request_spec.rb +2 -7
- data/spec/lib/http/response_spec.rb +0 -5
- data/spec/lib/http_spec.rb +0 -8
- data/spec/spec_helper.rb +5 -0
- data/spec/support/connection_reuse_shared.rb +2 -0
- data/spec/support/http_handling_shared.rb +7 -0
- metadata +36 -19
- data/lib/http/cache.rb +0 -146
- data/lib/http/cache/headers.rb +0 -100
- data/lib/http/cache/null_cache.rb +0 -13
- data/lib/http/request/caching.rb +0 -95
- data/lib/http/response/caching.rb +0 -143
- data/lib/http/response/io_body.rb +0 -63
- data/lib/http/response/string_body.rb +0 -53
- data/spec/lib/http/cache/headers_spec.rb +0 -77
- data/spec/lib/http/cache_spec.rb +0 -182
- data/spec/lib/http/request/caching_spec.rb +0 -133
- data/spec/lib/http/response/caching_spec.rb +0 -201
- data/spec/lib/http/response/io_body_spec.rb +0 -35
- data/spec/lib/http/response/string_body_spec.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4831838669ac11e88040de6ef9efb47f6741bc50
|
4
|
+
data.tar.gz: 816051270873fd03f7550e08623e7705332b12b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05a4d18df5d3fcf9bd97b8b721919d54dcadaccf619be8848f0a31dfb2bb5702b0e6b088cc0f020687eee53b7b3a57840e71054a4d5e3f407b01e7505da0aa03
|
7
|
+
data.tar.gz: 4ea9e0a57fd46b7ef3fae84f860c0fa2445b2f5ccca041c43548339131c8f86b8d28ba154cb92133c304cfafe3f19f3560bbb13541eb9a78c75cb435d944f031
|
data/CHANGES.md
CHANGED
@@ -1,11 +1,7 @@
|
|
1
|
-
## 0.
|
1
|
+
## 0.9.0.pre (2015-07-22)
|
2
2
|
|
3
|
-
*
|
4
|
-
|
5
|
-
|
6
|
-
## 0.8.13 (2015-08-14)
|
7
|
-
|
8
|
-
* Backport params special-chars escaping fix from `v0.9.1`. (@ixti)
|
3
|
+
* Support for caching removed. See #240. (@tarcieri)
|
4
|
+
* JRuby 9000 compatibility
|
9
5
|
|
10
6
|
|
11
7
|
## 0.8.12 (2015-05-26)
|
data/Gemfile
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
-
gem "jruby-openssl" if defined? JRUBY_VERSION
|
4
3
|
gem "rake"
|
5
4
|
|
6
5
|
gem "rack-cache", "~> 1.2"
|
@@ -23,17 +22,15 @@ group :test do
|
|
23
22
|
gem "coveralls"
|
24
23
|
gem "simplecov", ">= 0.9"
|
25
24
|
gem "json", ">= 1.8.1"
|
26
|
-
gem "
|
27
|
-
gem "rest-client", "~> 1.6.0", :platforms => [:jruby]
|
28
|
-
gem "rspec", "~> 3.2.0"
|
25
|
+
gem "rspec", "~> 3.0"
|
29
26
|
gem "rspec-its"
|
30
|
-
gem "rubocop"
|
27
|
+
gem "rubocop"
|
31
28
|
gem "yardstick"
|
32
29
|
gem "certificate_authority"
|
33
30
|
end
|
34
31
|
|
35
32
|
group :doc do
|
36
|
-
gem "
|
33
|
+
gem "kramdown"
|
37
34
|
gem "yard"
|
38
35
|
end
|
39
36
|
|
data/README.md
CHANGED
@@ -228,6 +228,18 @@ HTTP.accept(:json).get("https://github.com/httprb/http.rb/commit/HEAD")
|
|
228
228
|
This adds the appropriate Accept header for retrieving a JSON response for the
|
229
229
|
given resource.
|
230
230
|
|
231
|
+
### Reuse HTTP connection: HTTP Keep-Alive
|
232
|
+
|
233
|
+
If you have many successive requests against the same host, you better want to
|
234
|
+
reuse the same connection again and again:
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
contents = []
|
238
|
+
targets = %w(Hypertext_Transfer_Protocol Git GitHub Linux Hurd)
|
239
|
+
HTTP.persistent('http://en.wikipedia.org').do |http|
|
240
|
+
targets.each { |target| contents << http.get("/wiki/#{target}") }
|
241
|
+
end
|
242
|
+
```
|
231
243
|
|
232
244
|
### Celluloid::IO Support
|
233
245
|
|
@@ -253,28 +265,6 @@ There's a little more to it, but that's the core idea!
|
|
253
265
|
* [Full parallel HTTP fetcher example](https://github.com/httprb/http.rb/wiki/Parallel-requests-with-Celluloid%3A%3AIO)
|
254
266
|
* See also: [Celluloid::IO](https://github.com/celluloid/celluloid-io)
|
255
267
|
|
256
|
-
### Caching
|
257
|
-
|
258
|
-
http.rb provides caching of HTTP request (per
|
259
|
-
[RFC 7234](https://tools.ietf.org/html/rfc7234)) when configured to do
|
260
|
-
so.
|
261
|
-
|
262
|
-
```ruby
|
263
|
-
require "http"
|
264
|
-
|
265
|
-
http = HTTP.cache(:metastore => "file:/var/cache/my-app-http/meta",
|
266
|
-
:entitystore => "file:/var/cache/my-app-http/entity")
|
267
|
-
|
268
|
-
http.get("http://example.com/") # makes request
|
269
|
-
http.get("http://example.com/") # skips making request and returns
|
270
|
-
# previously cached response
|
271
|
-
```
|
272
|
-
|
273
|
-
http.rb's caching is backed by
|
274
|
-
[rack-cache's excellent storage subsystem](http://rtomayko.github.io/rack-cache/storage.html). Any
|
275
|
-
storage URL supported by rack-cache is supported by http.rb's cache.
|
276
|
-
|
277
|
-
|
278
268
|
### Timeouts
|
279
269
|
|
280
270
|
By default, HTTP does not timeout on a request. You can enable per operation
|
data/lib/http/chainable.rb
CHANGED
@@ -170,14 +170,6 @@ module HTTP
|
|
170
170
|
# @see #follow
|
171
171
|
alias_method :with_follow, :follow
|
172
172
|
|
173
|
-
def cache(cache)
|
174
|
-
branch default_options.with_cache(cache)
|
175
|
-
end
|
176
|
-
|
177
|
-
# @deprecated will be removed in 1.0.0
|
178
|
-
# @see #cache
|
179
|
-
alias_method :with_cache, :cache
|
180
|
-
|
181
173
|
# Make a request with the given headers
|
182
174
|
# @param headers
|
183
175
|
def headers(headers)
|
data/lib/http/client.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
require "forwardable"
|
2
2
|
|
3
|
+
require "cgi"
|
4
|
+
require "uri"
|
5
|
+
|
3
6
|
require "http/form_data"
|
4
7
|
require "http/options"
|
5
8
|
require "http/headers"
|
@@ -42,19 +45,13 @@ module HTTP
|
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
45
|
-
# Perform a single (no follow) HTTP request
|
46
|
-
def perform(req, options)
|
47
|
-
options.cache.perform(req, options) do |r, opts|
|
48
|
-
make_request(r, opts)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
48
|
# @!method persistent?
|
53
49
|
# @see Options#persistent?
|
54
50
|
# @return [Boolean] whenever client is persistent
|
55
51
|
def_delegator :default_options, :persistent?
|
56
52
|
|
57
|
-
|
53
|
+
# Perform a single (no follow) HTTP request
|
54
|
+
def perform(req, options)
|
58
55
|
verify_connection!(req.uri)
|
59
56
|
|
60
57
|
@state = :dirty
|
@@ -112,7 +109,7 @@ module HTTP
|
|
112
109
|
#
|
113
110
|
# @param [#to_s] uri
|
114
111
|
# @return [URI]
|
115
|
-
def make_request_uri(uri,
|
112
|
+
def make_request_uri(uri, options)
|
116
113
|
uri = uri.to_s
|
117
114
|
|
118
115
|
if default_options.persistent? && uri !~ HTTP_OR_HTTPS_RE
|
@@ -121,8 +118,9 @@ module HTTP
|
|
121
118
|
|
122
119
|
uri = HTTP::URI.parse uri
|
123
120
|
|
124
|
-
if
|
125
|
-
|
121
|
+
if options.params && !options.params.empty?
|
122
|
+
params = CGI.parse(uri.query.to_s).merge(options.params || {})
|
123
|
+
uri.query = ::URI.encode_www_form params
|
126
124
|
end
|
127
125
|
|
128
126
|
# Some proxies (seen on WEBRick) fail if URL has
|
data/lib/http/errors.rb
CHANGED
data/lib/http/options.rb
CHANGED
@@ -1,21 +1,16 @@
|
|
1
1
|
require "http/headers"
|
2
2
|
require "openssl"
|
3
3
|
require "socket"
|
4
|
-
require "http/cache/null_cache"
|
5
4
|
require "http/uri"
|
6
5
|
|
7
6
|
module HTTP
|
8
7
|
class Options
|
9
8
|
@default_socket_class = TCPSocket
|
10
9
|
@default_ssl_socket_class = OpenSSL::SSL::SSLSocket
|
11
|
-
|
12
|
-
@default_timeout_class = HTTP::Timeout::Null
|
13
|
-
|
14
|
-
@default_cache = Http::Cache::NullCache.new
|
10
|
+
@default_timeout_class = HTTP::Timeout::Null
|
15
11
|
|
16
12
|
class << self
|
17
|
-
attr_accessor :default_socket_class, :default_ssl_socket_class
|
18
|
-
attr_accessor :default_cache, :default_timeout_class
|
13
|
+
attr_accessor :default_socket_class, :default_ssl_socket_class, :default_timeout_class
|
19
14
|
|
20
15
|
def new(options = {})
|
21
16
|
return options if options.is_a?(self)
|
@@ -43,17 +38,16 @@ module HTTP
|
|
43
38
|
|
44
39
|
def initialize(options = {})
|
45
40
|
defaults = {
|
46
|
-
:response
|
47
|
-
:proxy
|
48
|
-
:timeout_class
|
49
|
-
:timeout_options
|
50
|
-
:socket_class
|
51
|
-
:ssl_socket_class
|
52
|
-
:ssl
|
53
|
-
:
|
54
|
-
:
|
55
|
-
:
|
56
|
-
:cookies => {}
|
41
|
+
:response => :auto,
|
42
|
+
:proxy => {},
|
43
|
+
:timeout_class => self.class.default_timeout_class,
|
44
|
+
:timeout_options => {},
|
45
|
+
:socket_class => self.class.default_socket_class,
|
46
|
+
:ssl_socket_class => self.class.default_ssl_socket_class,
|
47
|
+
:ssl => {},
|
48
|
+
:keep_alive_timeout => 5,
|
49
|
+
:headers => {},
|
50
|
+
:cookies => {}
|
57
51
|
}
|
58
52
|
|
59
53
|
opts_w_defaults = defaults.merge(options)
|
@@ -97,15 +91,6 @@ module HTTP
|
|
97
91
|
!persistent.nil?
|
98
92
|
end
|
99
93
|
|
100
|
-
def_option :cache do |cache_or_cache_options|
|
101
|
-
if cache_or_cache_options.respond_to? :perform
|
102
|
-
cache_or_cache_options
|
103
|
-
else
|
104
|
-
require "http/cache"
|
105
|
-
HTTP::Cache.new(cache_or_cache_options)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
94
|
def [](option)
|
110
95
|
send(option) rescue nil
|
111
96
|
end
|
data/lib/http/request.rb
CHANGED
@@ -4,7 +4,6 @@ require "time"
|
|
4
4
|
|
5
5
|
require "http/errors"
|
6
6
|
require "http/headers"
|
7
|
-
require "http/request/caching"
|
8
7
|
require "http/request/writer"
|
9
8
|
require "http/version"
|
10
9
|
require "http/uri"
|
@@ -67,7 +66,7 @@ module HTTP
|
|
67
66
|
# :nodoc:
|
68
67
|
def initialize(verb, uri, headers = {}, proxy = {}, body = nil, version = "1.1") # rubocop:disable ParameterLists
|
69
68
|
@verb = verb.to_s.downcase.to_sym
|
70
|
-
@uri =
|
69
|
+
@uri = HTTP::URI.parse(uri).normalize
|
71
70
|
@scheme = @uri.scheme && @uri.scheme.to_s.downcase.to_sym
|
72
71
|
|
73
72
|
fail(UnsupportedMethodError, "unknown method: #{verb}") unless METHODS.include?(@verb)
|
@@ -124,7 +123,7 @@ module HTTP
|
|
124
123
|
# Compute HTTP request header for direct or proxy request
|
125
124
|
def headline
|
126
125
|
request_uri = using_proxy? ? uri : uri.omit(:scheme, :authority)
|
127
|
-
"#{verb.to_s.upcase} #{request_uri
|
126
|
+
"#{verb.to_s.upcase} #{request_uri} HTTP/#{version}"
|
128
127
|
end
|
129
128
|
|
130
129
|
# @deprecated Will be removed in 1.0.0
|
@@ -157,11 +156,6 @@ module HTTP
|
|
157
156
|
using_proxy? ? proxy[:proxy_port] : port
|
158
157
|
end
|
159
158
|
|
160
|
-
# @return [HTTP::Request::Caching]
|
161
|
-
def caching
|
162
|
-
Caching.new self
|
163
|
-
end
|
164
|
-
|
165
159
|
private
|
166
160
|
|
167
161
|
# @!attribute [r] host
|
@@ -178,18 +172,5 @@ module HTTP
|
|
178
172
|
def default_host_header_value
|
179
173
|
PORTS[@scheme] != port ? "#{host}:#{port}" : host
|
180
174
|
end
|
181
|
-
|
182
|
-
# @return [HTTP::URI] URI with all componentes but query being normalized.
|
183
|
-
def normalize_uri(uri)
|
184
|
-
uri = HTTP::URI.parse uri
|
185
|
-
|
186
|
-
HTTP::URI.new(
|
187
|
-
:scheme => uri.normalized_scheme,
|
188
|
-
:authority => uri.normalized_authority,
|
189
|
-
:path => uri.normalized_path,
|
190
|
-
:query => uri.query,
|
191
|
-
:fragment => uri.normalized_fragment
|
192
|
-
)
|
193
|
-
end
|
194
175
|
end
|
195
176
|
end
|
data/lib/http/response.rb
CHANGED
@@ -3,7 +3,6 @@ require "forwardable"
|
|
3
3
|
require "http/headers"
|
4
4
|
require "http/content_type"
|
5
5
|
require "http/mime_type"
|
6
|
-
require "http/response/caching"
|
7
6
|
require "http/response/status"
|
8
7
|
require "http/uri"
|
9
8
|
require "http/cookie_jar"
|
@@ -115,10 +114,5 @@ module HTTP
|
|
115
114
|
def inspect
|
116
115
|
"#<#{self.class}/#{@version} #{code} #{reason} #{headers.to_h.inspect}>"
|
117
116
|
end
|
118
|
-
|
119
|
-
# @return [HTTP::Response::Caching]
|
120
|
-
def caching
|
121
|
-
Caching.new self
|
122
|
-
end
|
123
117
|
end
|
124
118
|
end
|
data/lib/http/timeout/null.rb
CHANGED
@@ -45,8 +45,31 @@ module HTTP
|
|
45
45
|
def write(data)
|
46
46
|
@socket << data
|
47
47
|
end
|
48
|
-
|
49
48
|
alias_method :<<, :write
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# Retry reading
|
53
|
+
def rescue_readable
|
54
|
+
yield
|
55
|
+
rescue IO::WaitReadable
|
56
|
+
if IO.select([socket], nil, nil, read_timeout)
|
57
|
+
retry
|
58
|
+
else
|
59
|
+
raise TimeoutError, "Read timed out after #{read_timeout} seconds"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Retry writing
|
64
|
+
def rescue_writable
|
65
|
+
yield
|
66
|
+
rescue IO::WaitWritable
|
67
|
+
if IO.select(nil, [socket], nil, write_timeout)
|
68
|
+
retry
|
69
|
+
else
|
70
|
+
raise TimeoutError, "Write timed out after #{write_timeout} seconds"
|
71
|
+
end
|
72
|
+
end
|
50
73
|
end
|
51
74
|
end
|
52
75
|
end
|
@@ -22,40 +22,24 @@ module HTTP
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def connect_ssl
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
else
|
30
|
-
raise TimeoutError, "Connection timed out after #{connect_timeout} seconds"
|
31
|
-
end
|
32
|
-
rescue IO::WaitWritable
|
33
|
-
if IO.select(nil, [socket], nil, connect_timeout)
|
34
|
-
retry
|
35
|
-
else
|
36
|
-
raise TimeoutError, "Connection timed out after #{connect_timeout} seconds"
|
25
|
+
rescue_readable do
|
26
|
+
rescue_writable do
|
27
|
+
socket.connect_nonblock
|
28
|
+
end
|
37
29
|
end
|
38
30
|
end
|
39
31
|
|
40
32
|
# Read data from the socket
|
41
33
|
def readpartial(size)
|
42
|
-
|
43
|
-
|
44
|
-
if IO.select([socket], nil, nil, read_timeout)
|
45
|
-
retry
|
46
|
-
else
|
47
|
-
raise TimeoutError, "Read timed out after #{read_timeout} seconds"
|
34
|
+
rescue_readable do
|
35
|
+
socket.read_nonblock(size)
|
48
36
|
end
|
49
37
|
end
|
50
38
|
|
51
39
|
# Write data to the socket
|
52
40
|
def write(data)
|
53
|
-
|
54
|
-
|
55
|
-
if IO.select(nil, [socket], nil, write_timeout)
|
56
|
-
retry
|
57
|
-
else
|
58
|
-
raise TimeoutError, "Read timed out after #{write_timeout} seconds"
|
41
|
+
rescue_writable do
|
42
|
+
socket.write_nonblock(data)
|
59
43
|
end
|
60
44
|
end
|
61
45
|
end
|
data/lib/http/uri.rb
CHANGED
@@ -2,10 +2,10 @@ require "addressable/uri"
|
|
2
2
|
|
3
3
|
module HTTP
|
4
4
|
class URI < Addressable::URI
|
5
|
-
#
|
5
|
+
# HTTP scheme
|
6
6
|
HTTP_SCHEME = "http".freeze
|
7
7
|
|
8
|
-
#
|
8
|
+
# HTTPS scheme
|
9
9
|
HTTPS_SCHEME = "https".freeze
|
10
10
|
|
11
11
|
# @return [True] if URI is HTTP
|
@@ -19,10 +19,5 @@ module HTTP
|
|
19
19
|
def https?
|
20
20
|
HTTPS_SCHEME == scheme
|
21
21
|
end
|
22
|
-
|
23
|
-
# @return [String] human-readable representation of URI
|
24
|
-
def inspect
|
25
|
-
format("#<%s:%#0x URI:%s>", self.class, object_id, to_s)
|
26
|
-
end
|
27
22
|
end
|
28
23
|
end
|
data/lib/http/version.rb
CHANGED
@@ -4,13 +4,11 @@ require "support/http_handling_shared"
|
|
4
4
|
require "support/dummy_server"
|
5
5
|
require "support/ssl_helper"
|
6
6
|
|
7
|
-
require "http/cache"
|
8
|
-
|
9
7
|
RSpec.describe HTTP::Client do
|
10
8
|
run_server(:dummy) { DummyServer.new }
|
11
9
|
|
12
10
|
StubbedClient = Class.new(HTTP::Client) do
|
13
|
-
def
|
11
|
+
def perform(request, options)
|
14
12
|
stubs.fetch(request.uri) { super(request, options) }
|
15
13
|
end
|
16
14
|
|
@@ -97,26 +95,6 @@ RSpec.describe HTTP::Client do
|
|
97
95
|
end
|
98
96
|
end
|
99
97
|
|
100
|
-
describe "caching" do
|
101
|
-
let(:sn) { SecureRandom.urlsafe_base64(3) }
|
102
|
-
|
103
|
-
it "returns cached responses if they exist" do
|
104
|
-
cached_response = simple_response("cached").caching
|
105
|
-
StubbedClient.new(:cache =>
|
106
|
-
HTTP::Cache.new(:metastore => "heap:/", :entitystore => "heap:/")).
|
107
|
-
stub("http://example.com/#{sn}" => cached_response).
|
108
|
-
get("http://example.com/#{sn}")
|
109
|
-
|
110
|
-
# cache is now warm
|
111
|
-
|
112
|
-
client = StubbedClient.new(:cache => HTTP::Cache.new(:metastore => "heap:/", :entitystore => "heap:/")).
|
113
|
-
stub("http://example.com/#{sn}" => simple_response("OK"))
|
114
|
-
|
115
|
-
expect(client.get("http://example.com/#{sn}").body.to_s).
|
116
|
-
to eq cached_response.body.to_s
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
98
|
describe "parsing params" do
|
121
99
|
let(:client) { HTTP::Client.new }
|
122
100
|
before { allow(client).to receive :perform }
|
@@ -160,14 +138,6 @@ RSpec.describe HTTP::Client do
|
|
160
138
|
|
161
139
|
client.get("http://example.com/?a[]=b&a[]=c", :params => {:d => "e"})
|
162
140
|
end
|
163
|
-
|
164
|
-
it "properly encodes colons" do
|
165
|
-
expect(HTTP::Request).to receive(:new) do |_, uri|
|
166
|
-
expect(uri.query).to eq "t=1970-01-01T00%3A00%3A00Z"
|
167
|
-
end
|
168
|
-
|
169
|
-
client.get("http://example.com/", :params => {:t => "1970-01-01T00:00:00Z"})
|
170
|
-
end
|
171
141
|
end
|
172
142
|
|
173
143
|
describe "passing json" do
|