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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bde805c006e8d041591f271243d2e889e2134bc1
4
- data.tar.gz: ec416925025cf7c7686f3e21b525bafeaa773ce6
3
+ metadata.gz: 4831838669ac11e88040de6ef9efb47f6741bc50
4
+ data.tar.gz: 816051270873fd03f7550e08623e7705332b12b9
5
5
  SHA512:
6
- metadata.gz: 66f67e4665d52a746081b25fbf331884eaadcd45c2716cde98de3eccbc33262cce3fea3e581ea3b46699e89e51623f9afe27794f8a2d43c3d6cf7aed4752bd22
7
- data.tar.gz: 97bcbc0ec6607e3a34dfcc9d0a6d1e2730501a67f0d3133e9c2141f2967a17af2e4ea9d00f88b70b04a5ffcde954d9db99c7085bd3ebdb737c4dc42e644c78c8
6
+ metadata.gz: 05a4d18df5d3fcf9bd97b8b721919d54dcadaccf619be8848f0a31dfb2bb5702b0e6b088cc0f020687eee53b7b3a57840e71054a4d5e3f407b01e7505da0aa03
7
+ data.tar.gz: 4ea9e0a57fd46b7ef3fae84f860c0fa2445b2f5ccca041c43548339131c8f86b8d28ba154cb92133c304cfafe3f19f3560bbb13541eb9a78c75cb435d944f031
data/CHANGES.md CHANGED
@@ -1,11 +1,7 @@
1
- ## 0.8.14 (2015-08-19)
1
+ ## 0.9.0.pre (2015-07-22)
2
2
 
3
- * Backport request URI normalization fixes from master. (@ixti)
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 "mime-types", "~> 1.25", :platforms => [:jruby]
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", "~> 0.31.0"
27
+ gem "rubocop"
31
28
  gem "yardstick"
32
29
  gem "certificate_authority"
33
30
  end
34
31
 
35
32
  group :doc do
36
- gem "redcarpet"
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
@@ -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)
@@ -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
- def make_request(req, options)
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, opts)
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 opts.params && !opts.params.empty?
125
- uri.query = [uri.query, HTTP::URI.form_encode(opts.params)].compact.join("&")
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
@@ -14,9 +14,6 @@ module HTTP
14
14
  # Generic Timeout error
15
15
  class TimeoutError < Error; end
16
16
 
17
- # Generic Cache error
18
- class CacheError < Error; end
19
-
20
17
  # Header name is invalid
21
18
  class InvalidHeaderNameError < Error; end
22
19
  end
@@ -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 => :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 => {}
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
@@ -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 = normalize_uri 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.omit :fragment} HTTP/#{version}"
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
@@ -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
@@ -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
- socket.connect_nonblock
26
- rescue IO::WaitReadable
27
- if IO.select([socket], nil, nil, connect_timeout)
28
- retry
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
- socket.read_nonblock(size)
43
- rescue IO::WaitReadable
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
- socket.write_nonblock(data)
54
- rescue IO::WaitWritable
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
@@ -2,10 +2,10 @@ require "addressable/uri"
2
2
 
3
3
  module HTTP
4
4
  class URI < Addressable::URI
5
- # @private
5
+ # HTTP scheme
6
6
  HTTP_SCHEME = "http".freeze
7
7
 
8
- # @private
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
@@ -1,3 +1,3 @@
1
1
  module HTTP
2
- VERSION = "0.8.14".freeze
2
+ VERSION = "0.9.0.pre".freeze
3
3
  end
@@ -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 make_request(request, options)
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