http 1.0.1 → 1.0.2

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: b2e1c7f1cbe78f39dff1f5194cd2fa58b9ffe5b4
4
- data.tar.gz: 60ba195836aed0fb9a78c29ac67406d725e576d2
3
+ metadata.gz: 8fa5394fed30d8eebd829ba4c79f6ac28b47fc16
4
+ data.tar.gz: d3654335bb11728650548423d57cb402eb3d5080
5
5
  SHA512:
6
- metadata.gz: a2dc702c28b433e98d710e7330ca9379c3fb182dbee771b03a14c73710cbe3134a5f49177802bdd3696f3586531495ba194738954c7037801c4a31b924638204
7
- data.tar.gz: 2354deaba38c163740dee33693564b18398fe0a3b3ebcfc18a93b717b11f78bba6d40d4055e7a670d040b135814ed2c98fca84cf9934e5a96527b21a9bd65389
6
+ metadata.gz: 429071438fa4126402282e1d1258180626f3c181192fbc9a03517920af1284d76574d3802863fdd6ac57d42bf1ad79606932c06faee21856c89572861a98b4a9
7
+ data.tar.gz: b8db2ca9014d5fc387736f0c5efaba5287fc506ef8ab0ff2433bfe9dc996254e2d7c2fabf078df449962ddefd378a2d1a4a0ae7c1eab7bccfe7e31bac8810186
data/.travis.yml CHANGED
@@ -1,4 +1,3 @@
1
- sudo: false
2
1
  bundler_args: --without development doc
3
2
  env:
4
3
  global:
data/CHANGES.md CHANGED
@@ -1,9 +1,17 @@
1
+ ## 1.0.2 (2016-01-15)
2
+
3
+ * [#295](https://github.com/httprb/http/pull/295):
4
+ Fix redirect following when used with persistent mode.
5
+ ([@ixti])
6
+
7
+
1
8
  ## 1.0.1 (2015-12-27)
2
9
 
3
10
  * [#283](https://github.com/httprb/http/pull/283):
4
11
  Use io/wait on supported platforms.
5
12
  ([@tarcieri])
6
13
 
14
+
7
15
  ## 1.0.0 (2015-12-25)
8
16
 
9
17
  * [#265](https://github.com/httprb/http/pull/265/):
@@ -20,11 +28,11 @@
20
28
  - HTTP::Response#status_code (use #status or #code)
21
29
  - HTTP::Response::Status#symbolize (use #to_sym)
22
30
 
23
- * [#269](https://github.com/httprb/http/pull/273/):
31
+ * [#269](https://github.com/httprb/http/pull/269/):
24
32
  Close connection in case of error during request.
25
33
  ([@ixti])
26
34
 
27
- * [#271](https://github.com/httprb/http/pull/273/):
35
+ * [#271](https://github.com/httprb/http/pull/271/):
28
36
  High-level exception wrappers for low-level I/O errors.
29
37
  ([@ixti])
30
38
 
@@ -32,7 +40,7 @@
32
40
  Add encoding option.
33
41
  ([@connorhd])
34
42
 
35
- * [#275](https://github.com/httprb/http/pull/273/):
43
+ * [#275](https://github.com/httprb/http/pull/275/):
36
44
  Support for disabling Nagle's algorithm with `HTTP.nodelay`.
37
45
  ([@nerdrew])
38
46
 
@@ -53,9 +61,10 @@
53
61
  Remove legacy 'Http' constant alias to 'HTTP'.
54
62
  ([@tarcieri])
55
63
 
64
+
56
65
  ## 0.9.8 (2015-09-29)
57
66
 
58
- * [#260](https://github.com/httprb/http/pull/258):
67
+ * [#260](https://github.com/httprb/http/pull/260):
59
68
  Fixed global timeout persisting time left across requests when reusing connections.
60
69
  ([@zanker])
61
70
 
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011-2015 Tony Arcieri, Erik Michaels-Ober, Alexey V. Zapparov, Zachary Anker
1
+ Copyright (c) 2011-2016 Tony Arcieri, Erik Michaels-Ober, Alexey V. Zapparov, Zachary Anker
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # ![http.rb](https://raw.github.com/httprb/http.rb/master/logo.png)
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/http.svg)](http://rubygems.org/gems/http)
4
- [![Build Status](https://secure.travis-ci.org/httprb/http.svg?branch=master)](http://travis-ci.org/httprb/http)
3
+ [![Gem Version](https://badge.fury.io/rb/http.svg)](https://rubygems.org/gems/http)
4
+ [![Build Status](https://secure.travis-ci.org/httprb/http.svg?branch=master)](https://travis-ci.org/httprb/http)
5
5
  [![Code Climate](https://codeclimate.com/github/httprb/http.svg?branch=master)](https://codeclimate.com/github/httprb/http)
6
6
  [![Coverage Status](https://coveralls.io/repos/httprb/http/badge.svg?branch=master)](https://coveralls.io/r/httprb/http)
7
7
  [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/httprb/http/blob/master/LICENSE.txt)
@@ -73,7 +73,7 @@ You can join by email by sending a message to:
73
73
 
74
74
  If you believe you've found a bug, please report it at:
75
75
 
76
- https://github.com/httprb/http.rb/issues
76
+ https://github.com/httprb/http/issues
77
77
 
78
78
 
79
79
  ## Installation
@@ -268,19 +268,59 @@ HTTP.accept(:json).get("https://github.com/httprb/http/commit/HEAD")
268
268
  This adds the appropriate Accept header for retrieving a JSON response for the
269
269
  given resource.
270
270
 
271
+
271
272
  ### Reuse HTTP connection: HTTP Keep-Alive
272
273
 
273
- If you have many successive requests against the same host, you better want to
274
- reuse the same connection again and again:
274
+ If you need to make many successive requests against the same host,
275
+ you can create client with persistent connection to the host:
275
276
 
276
- ```ruby
277
- contents = []
278
- targets = %w(Hypertext_Transfer_Protocol Git GitHub Linux Hurd)
279
- HTTP.persistent('http://en.wikipedia.org') do |http|
280
- targets.each { |target| contents << http.get("/wiki/#{target}") }
277
+ ``` ruby
278
+ begin
279
+ # create HTTP client with persistent connection to api.icndb.com:
280
+ http = HTTP.persistent "http://api.icndb.com"
281
+
282
+ # issue multiple requests using same connection:
283
+ jokes = 100.times.map { http.get("/jokes/random").to_s }
284
+ ensure
285
+ # close underlying connection when you don't need it anymore
286
+ http.close if http
287
+ end
288
+
289
+ ```
290
+
291
+ If the optional code block is given, it will be passed the client with
292
+ persistent connection to the host as an argument and `client.close` will be
293
+ automatically called when the block terminates.
294
+ The value of the block will be returned:
295
+
296
+ ``` ruby
297
+ jokes = HTTP.persistent "http://api.icndb.com" do |http|
298
+ 100.times.map { http.get("/jokes/random").to_s }
281
299
  end
282
300
  ```
283
301
 
302
+ ##### NOTICE
303
+
304
+ You must consume response before sending next request via persistent connection.
305
+ That means you need to call `#to_s`, `#parse` or `#flush` on response object.
306
+ In the example above we used `http.get("/jokes/random").to_s` to get response
307
+ bodies. That works perfectly fine, because `#to_s` reads off the response.
308
+
309
+ Sometimes you don't need response body, or need whole response object to
310
+ access it's status, headers etc instead. You can either call `#to_s` to
311
+ make sure response was flushed and then use response object itself, or use
312
+ `#flush` (syntax sugar for `#tap(&:to_s)` that will do that for you:
313
+
314
+
315
+ ``` ruby
316
+ contents = HTTP.persistent "http://en.wikipedia.org" do |http|
317
+ %w(Hypertext_Transfer_Protocol Git GitHub Linux Hurd).map do
318
+ http.get("/wiki/#{target}").flush
319
+ end
320
+ end
321
+ ```
322
+
323
+
284
324
  ### Timeouts
285
325
 
286
326
  By default, HTTP does not timeout on a request. You can enable per operation
@@ -352,5 +392,5 @@ dropped.
352
392
 
353
393
  ## Copyright
354
394
 
355
- Copyright (c) 2011-2015 Tony Arcieri, Erik Michaels-Ober, Alexey V. Zapparov, Zachary Anker.
395
+ Copyright (c) 2011-2016 Tony Arcieri, Erik Michaels-Ober, Alexey V. Zapparov, Zachary Anker.
356
396
  See LICENSE.txt for further details.
@@ -54,6 +54,8 @@ module HTTP
54
54
  fail TooManyRedirectsError if too_many_hops?
55
55
  fail EndlessRedirectError if endless_loop?
56
56
 
57
+ @response.flush
58
+
57
59
  @request = redirect_to @response.headers[Headers::LOCATION]
58
60
  @response = yield @request
59
61
  end
@@ -68,6 +68,10 @@ module HTTP
68
68
  def send_request
69
69
  headers = join_headers
70
70
 
71
+ # It's important to send the request in a single write call when
72
+ # possible in order to play nicely with Nagle's algorithm. Making
73
+ # two writes in a row triggers a pathological case where Nagle is
74
+ # expecting a third write that never happens.
71
75
  case @body
72
76
  when NilClass
73
77
  write(headers)
@@ -77,8 +81,7 @@ module HTTP
77
81
  write(headers)
78
82
 
79
83
  @body.each do |chunk|
80
- write(chunk.bytesize.to_s(16) << CRLF)
81
- write(chunk << CRLF)
84
+ write(chunk.bytesize.to_s(16) << CRLF << chunk << CRLF)
82
85
  end
83
86
 
84
87
  write(CHUNKED_END)
data/lib/http/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module HTTP
2
- VERSION = "1.0.1".freeze
2
+ VERSION = "1.0.2".freeze
3
3
  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: 1.0.1
4
+ version: 1.0.2
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-12-27 00:00:00.000000000 Z
14
+ date: 2016-01-15 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: http_parser.rb
@@ -155,7 +155,6 @@ files:
155
155
  - spec/spec_helper.rb
156
156
  - spec/support/black_hole.rb
157
157
  - spec/support/capture_warning.rb
158
- - spec/support/connection_reuse_shared.rb
159
158
  - spec/support/dummy_server.rb
160
159
  - spec/support/dummy_server/servlet.rb
161
160
  - spec/support/http_handling_shared.rb
@@ -183,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
182
  version: '0'
184
183
  requirements: []
185
184
  rubyforge_project:
186
- rubygems_version: 2.4.8
185
+ rubygems_version: 2.2.5
187
186
  signing_key:
188
187
  specification_version: 4
189
188
  summary: HTTP should be easy
@@ -211,7 +210,6 @@ test_files:
211
210
  - spec/spec_helper.rb
212
211
  - spec/support/black_hole.rb
213
212
  - spec/support/capture_warning.rb
214
- - spec/support/connection_reuse_shared.rb
215
213
  - spec/support/dummy_server.rb
216
214
  - spec/support/dummy_server/servlet.rb
217
215
  - spec/support/http_handling_shared.rb
@@ -1,95 +0,0 @@
1
- RSpec.shared_context "handles shared connections" do
2
- describe "connection reuse" do
3
- let(:sockets_used) do
4
- [
5
- client.get("#{server.endpoint}/socket/1").body.to_s,
6
- client.get("#{server.endpoint}/socket/2").body.to_s
7
- ]
8
- end
9
-
10
- context "when enabled" do
11
- let(:reuse_conn) { server.endpoint }
12
-
13
- context "without a host" do
14
- it "infers host from persistent config" do
15
- expect(client.get("/").body.to_s).to eq("<!doctype html>")
16
- end
17
- end
18
-
19
- it "re-uses the socket" do
20
- expect(sockets_used).to_not include("")
21
- expect(sockets_used.uniq.length).to eq(1)
22
- end
23
-
24
- context "when trying to read a stale body" do
25
- it "errors" do
26
- client.get("#{server.endpoint}/not-found")
27
- expect { client.get(server.endpoint) }.to raise_error(HTTP::StateError, /Tried to send a request/)
28
- end
29
- end
30
-
31
- context "when reading a cached body" do
32
- it "succeeds" do
33
- first_res = client.get(server.endpoint)
34
- first_res.body.to_s
35
-
36
- second_res = client.get(server.endpoint)
37
-
38
- expect(first_res.body.to_s).to eq("<!doctype html>")
39
- expect(second_res.body.to_s).to eq("<!doctype html>")
40
- end
41
- end
42
-
43
- context "with a socket issue" do
44
- it "transparently reopens" do
45
- skip "flaky environment" if flaky_env?
46
-
47
- first_socket = client.get("#{server.endpoint}/socket").body.to_s
48
- expect(first_socket).to_not eq("")
49
-
50
- # Kill off the sockets we used
51
- # rubocop:disable Style/RescueModifier
52
- DummyServer::Servlet.sockets.each do |socket|
53
- socket.close rescue nil
54
- end
55
- DummyServer::Servlet.sockets.clear
56
- # rubocop:enable Style/RescueModifier
57
-
58
- # Should error because we tried to use a bad socket
59
- expect { client.get("#{server.endpoint}/socket").body.to_s }.to raise_error HTTP::ConnectionError
60
-
61
- # Should succeed since we create a new socket
62
- second_socket = client.get("#{server.endpoint}/socket").body.to_s
63
- expect(second_socket).to_not eq(first_socket)
64
- end
65
- end
66
-
67
- context "with a Keep-Alive timeout of 0" do
68
- let(:keep_alive_timeout) { 0 }
69
-
70
- it "automatically opens a new socket" do
71
- first_socket = client.get("#{server.endpoint}/socket/1").body.to_s
72
- sleep 0.1
73
- second_socket = client.get("#{server.endpoint}/socket/2").body.to_s
74
-
75
- expect(first_socket).to_not eq(second_socket)
76
- end
77
- end
78
-
79
- context "with a change in host" do
80
- it "errors" do
81
- expect { client.get("https://invalid.com/socket") }.to raise_error(/Persistence is enabled/i)
82
- end
83
- end
84
- end
85
-
86
- context "when disabled" do
87
- let(:reuse_conn) { nil }
88
-
89
- it "opens new sockets" do
90
- expect(sockets_used).to_not include("")
91
- expect(sockets_used.uniq.length).to eq(2)
92
- end
93
- end
94
- end
95
- end