http 1.0.4 → 2.0.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: 6a554e4ac3df247f5abcf5fc5af7707604576e23
4
- data.tar.gz: 04e6c88e86d14fbbfaa6af5db48ba28e83cf02ab
3
+ metadata.gz: 528cd808cd0cf04d196ac3459063496777a46736
4
+ data.tar.gz: a3a4cf179068d8f5c48bc803118075e5e71331d5
5
5
  SHA512:
6
- metadata.gz: 064656c4992d84ffe71bebe1cbcb83e1f32b8b33dc350a1d87e3fdc4893288697503bf36f0f27ea95cdbb4d0788aa3dd96cb69f9b3029fa4d99336d78aa12a45
7
- data.tar.gz: 920dfb6d29655e9147d22e6f8f0ccad6075c8c77c0cde3ee3bc4ad0d8dcc3120fb387f59909d60c3a142bf6c0744b0138a81c40e2bea9ef105e1583c229f9c3c
6
+ metadata.gz: 1774996540d80f6f08866f5bee7d632baa72a33bd31122485f15fdb97d695de7645c0f9131a5e52188ef4706005c96c74bcc175ee3b5182a9a7b7b4597f07274
7
+ data.tar.gz: 9cc27b2c73fee256c61409ce41069588e780c41df32d27662eea5c1d7de116e820c8843b3e08b670a84cfbb695b64d126c1f1b6e7b43de599cb84cad91f09d73
data/.travis.yml CHANGED
@@ -4,12 +4,11 @@ env:
4
4
  - JRUBY_OPTS="$JRUBY_OPTS --debug"
5
5
  language: ruby
6
6
  rvm:
7
- - 1.9.3
8
7
  - 2.0.0
9
8
  - 2.1
10
9
  - 2.2
11
10
  - 2.3.0
12
- - jruby
11
+ - jruby-9.0.5.0
13
12
  - jruby-head
14
13
  - ruby-head
15
14
  - rbx-2
data/CHANGES.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## master (unreleased)
2
+
3
+ * [#319](https://github.com/httprb/http/pull/319)
4
+ Drop Ruby 1.9.x support.
5
+ ([@ixti])
6
+
7
+
1
8
  ## 1.0.4 (2016-03-19)
2
9
 
3
10
  * [#320](https://github.com/httprb/http/pull/320)
data/Gemfile CHANGED
@@ -2,8 +2,6 @@ source "https://rubygems.org"
2
2
 
3
3
  gem "rake"
4
4
 
5
- gem "rack-cache", "~> 1.2"
6
-
7
5
  group :development do
8
6
  gem "celluloid-io"
9
7
  gem "guard"
data/README.md CHANGED
@@ -151,13 +151,11 @@ In practice you'll want to bind the HTTP::Response::Body to a local variable (e.
151
151
  This library aims to support and is [tested against][travis] the following Ruby
152
152
  versions:
153
153
 
154
- * Ruby 1.9.3
155
154
  * Ruby 2.0.0
156
155
  * Ruby 2.1.x
157
156
  * Ruby 2.2.x
158
157
  * Ruby 2.3.x
159
- * JRuby 1.7.x
160
- * JRuby 9000+
158
+ * JRuby 9.0.5.0
161
159
 
162
160
  If something doesn't work on one of these versions, it's a bug.
163
161
 
@@ -141,7 +141,7 @@ module HTTP
141
141
  return p_client unless block_given?
142
142
  yield p_client
143
143
  ensure
144
- p_client.close
144
+ p_client.close if p_client
145
145
  end
146
146
 
147
147
  # Make a request through an HTTP proxy
data/lib/http/client.rb CHANGED
@@ -161,8 +161,9 @@ module HTTP
161
161
  headers[Headers::CONTENT_LENGTH] ||= form.content_length
162
162
  form.to_s
163
163
  when opts.json
164
- headers[Headers::CONTENT_TYPE] ||= "application/json"
165
- MimeType[:json].encode opts.json
164
+ body = MimeType[:json].encode opts.json
165
+ headers[Headers::CONTENT_TYPE] ||= "application/json; charset=#{body.encoding.name}"
166
+ body
166
167
  end
167
168
  end
168
169
  end
@@ -37,8 +37,8 @@ module HTTP
37
37
  send_proxy_connect_request(req)
38
38
  start_tls(req, options)
39
39
  reset_timer
40
- rescue SocketError, SystemCallError => e
41
- raise ConnectionError, "failed to connect: #{e}"
40
+ rescue IOError, SocketError, SystemCallError => ex
41
+ raise ConnectionError, "failed to connect: #{ex}", ex.backtrace
42
42
  end
43
43
 
44
44
  # @see (HTTP::Response::Parser#status_code)
@@ -94,7 +94,7 @@ module HTTP
94
94
  def read_headers!
95
95
  loop do
96
96
  if read_more(BUFFER_SIZE) == :eof
97
- fail EOFError unless @parser.headers?
97
+ fail ConnectionError, "couldn't read response headers" unless @parser.headers?
98
98
  break
99
99
  elsif @parser.headers?
100
100
  break
@@ -102,8 +102,6 @@ module HTTP
102
102
  end
103
103
 
104
104
  set_keep_alive
105
- rescue IOError, Errno::ECONNRESET, Errno::EPIPE => e
106
- raise ConnectionError, "failed to read headers: #{e}"
107
105
  end
108
106
 
109
107
  # Callback for when we've reached the end of a response
@@ -213,6 +211,8 @@ module HTTP
213
211
  elsif value
214
212
  @parser << value
215
213
  end
214
+ rescue IOError, SocketError, SystemCallError => ex
215
+ raise ConnectionError, "error reading from socket: #{ex}", ex.backtrace
216
216
  end
217
217
  end
218
218
  end
@@ -1,4 +1,5 @@
1
1
  require "timeout"
2
+ require "io/wait"
2
3
 
3
4
  require "http/timeout/per_operation"
4
5
 
@@ -32,13 +33,13 @@ module HTTP
32
33
  reset_timer
33
34
 
34
35
  begin
35
- socket.connect_nonblock
36
+ @socket.connect_nonblock
36
37
  rescue IO::WaitReadable
37
- IO.select([socket], nil, nil, time_left)
38
+ IO.select([@socket], nil, nil, time_left)
38
39
  log_time
39
40
  retry
40
41
  rescue IO::WaitWritable
41
- IO.select(nil, [socket], nil, time_left)
42
+ IO.select(nil, [@socket], nil, time_left)
42
43
  log_time
43
44
  retry
44
45
  end
@@ -59,7 +60,6 @@ module HTTP
59
60
  private
60
61
 
61
62
  if RUBY_VERSION < "2.1.0"
62
-
63
63
  def read_nonblock(size)
64
64
  @socket.read_nonblock(size)
65
65
  end
@@ -67,9 +67,7 @@ module HTTP
67
67
  def write_nonblock(data)
68
68
  @socket.write_nonblock(data)
69
69
  end
70
-
71
70
  else
72
-
73
71
  def read_nonblock(size)
74
72
  @socket.read_nonblock(size, :exception => false)
75
73
  end
@@ -77,7 +75,6 @@ module HTTP
77
75
  def write_nonblock(data)
78
76
  @socket.write_nonblock(data, :exception => false)
79
77
  end
80
-
81
78
  end
82
79
 
83
80
  # Perform the given I/O operation with the given argument
@@ -106,13 +103,13 @@ module HTTP
106
103
 
107
104
  # Wait for a socket to become readable
108
105
  def wait_readable_or_timeout
109
- IO.select([@socket], nil, nil, time_left)
106
+ @socket.to_io.wait_readable(time_left)
110
107
  log_time
111
108
  end
112
109
 
113
110
  # Wait for a socket to become writable
114
111
  def wait_writable_or_timeout
115
- IO.select(nil, [@socket], nil, time_left)
112
+ @socket.to_io.wait_writable(time_left)
116
113
  log_time
117
114
  end
118
115
 
@@ -1,4 +1,5 @@
1
1
  require "forwardable"
2
+ require "io/wait"
2
3
 
3
4
  module HTTP
4
5
  module Timeout
@@ -56,7 +57,7 @@ module HTTP
56
57
  def rescue_readable
57
58
  yield
58
59
  rescue IO::WaitReadable
59
- retry if IO.select([socket], nil, nil, read_timeout)
60
+ retry if @socket.to_io.wait_readable(read_timeout)
60
61
  raise TimeoutError, "Read timed out after #{read_timeout} seconds"
61
62
  end
62
63
 
@@ -64,7 +65,7 @@ module HTTP
64
65
  def rescue_writable
65
66
  yield
66
67
  rescue IO::WaitWritable
67
- retry if IO.select(nil, [socket], nil, write_timeout)
68
+ retry if @socket.to_io.wait_writable(write_timeout)
68
69
  raise TimeoutError, "Write timed out after #{write_timeout} seconds"
69
70
  end
70
71
  end
@@ -29,7 +29,7 @@ module HTTP
29
29
  def connect_ssl
30
30
  rescue_readable do
31
31
  rescue_writable do
32
- socket.connect_nonblock
32
+ @socket.connect_nonblock
33
33
  end
34
34
  end
35
35
  end
@@ -39,7 +39,7 @@ module HTTP
39
39
  # Read data from the socket
40
40
  def readpartial(size)
41
41
  rescue_readable do
42
- socket.read_nonblock(size)
42
+ @socket.read_nonblock(size)
43
43
  end
44
44
  rescue EOFError
45
45
  :eof
@@ -48,7 +48,7 @@ module HTTP
48
48
  # Write data to the socket
49
49
  def write(data)
50
50
  rescue_writable do
51
- socket.write_nonblock(data)
51
+ @socket.write_nonblock(data)
52
52
  end
53
53
  rescue EOFError
54
54
  :eof
@@ -59,14 +59,14 @@ module HTTP
59
59
  # Read data from the socket
60
60
  def readpartial(size)
61
61
  loop do
62
- result = socket.read_nonblock(size, :exception => false)
62
+ result = @socket.read_nonblock(size, :exception => false)
63
63
  if result.nil?
64
64
  return :eof
65
65
  elsif result != :wait_readable
66
66
  return result
67
67
  end
68
68
 
69
- unless IO.select([socket], nil, nil, read_timeout)
69
+ unless IO.select([@socket], nil, nil, read_timeout)
70
70
  fail TimeoutError, "Read timed out after #{read_timeout} seconds"
71
71
  end
72
72
  end
@@ -75,16 +75,15 @@ module HTTP
75
75
  # Write data to the socket
76
76
  def write(data)
77
77
  loop do
78
- result = socket.write_nonblock(data, :exception => false)
78
+ result = @socket.write_nonblock(data, :exception => false)
79
79
  return result unless result == :wait_writable
80
80
 
81
- unless IO.select(nil, [socket], nil, write_timeout)
82
- fail TimeoutError, "Read timed out after #{write_timeout} seconds"
81
+ unless IO.select(nil, [@socket], nil, write_timeout)
82
+ fail TimeoutError, "Write timed out after #{write_timeout} seconds"
83
83
  end
84
84
  end
85
85
  end
86
86
  end
87
- # rubocop:enable Metrics/BlockNesting
88
87
  end
89
88
  end
90
89
  end
data/lib/http/uri.rb CHANGED
@@ -2,13 +2,103 @@
2
2
  require "addressable/uri"
3
3
 
4
4
  module HTTP
5
- class URI < Addressable::URI
5
+ class URI
6
+ extend Forwardable
7
+
8
+ def_delegators :@uri, :scheme, :normalized_scheme, :scheme=
9
+ def_delegators :@uri, :user, :normalized_user, :user=
10
+ def_delegators :@uri, :password, :normalized_password, :password=
11
+ def_delegators :@uri, :host, :normalized_host, :host=
12
+ def_delegators :@uri, :authority, :normalized_authority, :authority=
13
+ def_delegators :@uri, :origin, :origin=
14
+ def_delegators :@uri, :normalized_port, :port=
15
+ def_delegators :@uri, :path, :normalized_path, :path=
16
+ def_delegators :@uri, :query, :normalized_query, :query=
17
+ def_delegators :@uri, :request_uri, :request_uri=
18
+ def_delegators :@uri, :fragment, :normalized_fragment, :fragment=
19
+ def_delegators :@uri, :omit, :join, :normalize
20
+
6
21
  # @private
7
22
  HTTP_SCHEME = "http".freeze
8
23
 
9
24
  # @private
10
25
  HTTPS_SCHEME = "https".freeze
11
26
 
27
+ # Parse the given URI string, returning an HTTP::URI object
28
+ #
29
+ # @param [HTTP::URI, String, #to_str] :uri to parse
30
+ #
31
+ # @return [HTTP::URI] new URI instance
32
+ def self.parse(uri)
33
+ return uri if uri.is_a?(self)
34
+
35
+ new(Addressable::URI.parse(uri))
36
+ end
37
+
38
+ # Encodes key/value pairs as application/x-www-form-urlencoded
39
+ #
40
+ # @param [#to_hash, #to_ary] :form_values to encode
41
+ # @param [TrueClass, FalseClass] :sort should key/value pairs be sorted first?
42
+ #
43
+ # @return [String] encoded value
44
+ def self.form_encode(form_values, sort = false)
45
+ Addressable::URI.form_encode(form_values, sort)
46
+ end
47
+
48
+ # Creates an HTTP::URI instance from the given options
49
+ #
50
+ # @option [String, #to_str] :scheme URI scheme
51
+ # @option [String, #to_str] :user for basic authentication
52
+ # @option [String, #to_str] :password for basic authentication
53
+ # @option [String, #to_str] :host name component
54
+ # @option [String, #to_str] :port network port to connect to
55
+ # @option [String, #to_str] :path component to request
56
+ # @option [String, #to_str] :query component distinct from path
57
+ # @option [String, #to_str] :fragment component at the end of the URI
58
+ #
59
+ # @return [HTTP::URI] new URI instance
60
+ def initialize(options_or_uri = {})
61
+ case options_or_uri
62
+ when Hash
63
+ @uri = Addressable::URI.new(options_or_uri)
64
+ when Addressable::URI
65
+ @uri = options_or_uri
66
+ else fail TypeError, "expected Hash for options, got #{options_or_uri.class}"
67
+ end
68
+ end
69
+
70
+ # Are these URI objects equal? Normalizes both URIs prior to comparison
71
+ #
72
+ # @param [Object] :other URI to compare this one with
73
+ #
74
+ # @return [TrueClass, FalseClass] are the URIs equivalent (after normalization)?
75
+ def ==(other)
76
+ other.is_a?(URI) && normalize.to_s == other.normalize.to_s
77
+ end
78
+
79
+ # Are these URI objects equal? Does NOT normalizes both URIs prior to comparison
80
+ #
81
+ # @param [Object] :other URI to compare this one with
82
+ #
83
+ # @return [TrueClass, FalseClass] are the URIs equivalent?
84
+ def eql?(other)
85
+ other.is_a?(URI) && to_s == other.to_s
86
+ end
87
+
88
+ # Hash value based off the normalized form of a URI
89
+ #
90
+ # @return [Integer] A hash of the URI
91
+ def hash
92
+ @hash ||= to_s.hash * -1
93
+ end
94
+
95
+ # Port number, either as specified or the default if unspecified
96
+ #
97
+ # @return [Integer] port number
98
+ def port
99
+ @uri.port || @uri.default_port
100
+ end
101
+
12
102
  # @return [True] if URI is HTTP
13
103
  # @return [False] otherwise
14
104
  def http?
@@ -21,9 +111,17 @@ module HTTP
21
111
  HTTPS_SCHEME == scheme
22
112
  end
23
113
 
114
+ # Convert an HTTP::URI to a String
115
+ #
116
+ # @return [String] URI serialized as a String
117
+ def to_s
118
+ @uri.to_s
119
+ end
120
+ alias to_str to_s
121
+
24
122
  # @return [String] human-readable representation of URI
25
123
  def inspect
26
- format("#<%s:%#0x URI:%s>", self.class, object_id, to_s)
124
+ format("#<%s:0x%014x URI:%s>", self.class.name, object_id << 1, to_s)
27
125
  end
28
126
  end
29
127
  end
data/lib/http/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module HTTP
3
- VERSION = "1.0.4".freeze
3
+ VERSION = "2.0.0.pre".freeze
4
4
  end
@@ -0,0 +1,20 @@
1
+ RSpec.describe HTTP::URI do
2
+ let(:example_http_uri_string) { "http://example.com" }
3
+ let(:example_https_uri_string) { "https://example.com" }
4
+
5
+ subject(:http_uri) { described_class.parse(example_http_uri_string) }
6
+ subject(:https_uri) { described_class.parse(example_https_uri_string) }
7
+
8
+ it "knows URI schemes" do
9
+ expect(http_uri.scheme).to eq "http"
10
+ expect(https_uri.scheme).to eq "https"
11
+ end
12
+
13
+ it "sets default ports for HTTP URIs" do
14
+ expect(http_uri.port).to eq 80
15
+ end
16
+
17
+ it "sets default ports for HTTPS URIs" do
18
+ expect(https_uri.port).to eq 443
19
+ end
20
+ 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.4
4
+ version: 2.0.0.pre
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: 2016-03-19 00:00:00.000000000 Z
14
+ date: 2016-04-03 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: http_parser.rb
@@ -150,6 +150,7 @@ files:
150
150
  - spec/lib/http/response/body_spec.rb
151
151
  - spec/lib/http/response/status_spec.rb
152
152
  - spec/lib/http/response_spec.rb
153
+ - spec/lib/http/uri_spec.rb
153
154
  - spec/lib/http_spec.rb
154
155
  - spec/regression_specs.rb
155
156
  - spec/spec_helper.rb
@@ -177,9 +178,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
177
178
  version: '0'
178
179
  required_rubygems_version: !ruby/object:Gem::Requirement
179
180
  requirements:
180
- - - ">="
181
+ - - ">"
181
182
  - !ruby/object:Gem::Version
182
- version: '0'
183
+ version: 1.3.1
183
184
  requirements: []
184
185
  rubyforge_project:
185
186
  rubygems_version: 2.5.1
@@ -205,6 +206,7 @@ test_files:
205
206
  - spec/lib/http/response/body_spec.rb
206
207
  - spec/lib/http/response/status_spec.rb
207
208
  - spec/lib/http/response_spec.rb
209
+ - spec/lib/http/uri_spec.rb
208
210
  - spec/lib/http_spec.rb
209
211
  - spec/regression_specs.rb
210
212
  - spec/spec_helper.rb