http 0.8.14 → 0.9.0.pre

Sign up to get free protection for your applications and to get access to all the features.
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