http 1.0.1 → 1.0.2

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: 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