http 1.0.4 → 2.0.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: 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