http 2.0.0.pre → 2.0.0

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: 528cd808cd0cf04d196ac3459063496777a46736
4
- data.tar.gz: a3a4cf179068d8f5c48bc803118075e5e71331d5
3
+ metadata.gz: 8ae83a6df13ab671375cfdd322ba65d1a15b8a43
4
+ data.tar.gz: 4e107db57baa353e23fb25d805a3a0a6f17d1310
5
5
  SHA512:
6
- metadata.gz: 1774996540d80f6f08866f5bee7d632baa72a33bd31122485f15fdb97d695de7645c0f9131a5e52188ef4706005c96c74bcc175ee3b5182a9a7b7b4597f07274
7
- data.tar.gz: 9cc27b2c73fee256c61409ce41069588e780c41df32d27662eea5c1d7de116e820c8843b3e08b670a84cfbb695b64d126c1f1b6e7b43de599cb84cad91f09d73
6
+ metadata.gz: fdc5e4ea2f1e56a213246c34b40320584a1e092d07fcb03f99dd9f11d260b81e40be26483640a997c57d601b4882c753ca367152bd7cca9ad5b0498cb1b6681b
7
+ data.tar.gz: e421f13bb1522ec92bd2eca7efd73a713036daba084416cdc86d69d681d72d8f050738fe9b664d101a186afb028dd0d46eea475c029587a17d3dc3dfa619ac21
@@ -1,8 +1,12 @@
1
+ language: ruby
2
+ sudo: false
3
+
1
4
  bundler_args: --without development doc
5
+
2
6
  env:
3
7
  global:
4
8
  - JRUBY_OPTS="$JRUBY_OPTS --debug"
5
- language: ruby
9
+
6
10
  rvm:
7
11
  - 2.0.0
8
12
  - 2.1
@@ -12,10 +16,14 @@ rvm:
12
16
  - jruby-head
13
17
  - ruby-head
14
18
  - rbx-2
19
+
15
20
  matrix:
16
21
  allow_failures:
17
22
  - rvm: jruby-head
18
23
  - rvm: ruby-head
19
24
  - rvm: rbx-2
20
25
  fast_finish: true
21
- sudo: false
26
+
27
+ branches:
28
+ only:
29
+ - master
data/CHANGES.md CHANGED
@@ -1,4 +1,17 @@
1
- ## master (unreleased)
1
+ ## 2.0.0 (2016-04-23)
2
+
3
+ * [#333](https://github.com/httprb/http/pull/333)
4
+ Fix HTTPS request headline when sent via proxy.
5
+ ([@Connorhd])
6
+
7
+ * [#331](https://github.com/httprb/http/pull/331)
8
+ Add `#informational?`, `#success?`, `#redirect?`, `#client_error?` and
9
+ `#server_error?` helpers to `Response::Status`.
10
+ ([@mwitek])
11
+
12
+ * [#330](https://github.com/httprb/http/pull/330)
13
+ Support custom CONNECT headers (request/response) during HTTPS proxy requests.
14
+ ([@smudge])
2
15
 
3
16
  * [#319](https://github.com/httprb/http/pull/319)
4
17
  Drop Ruby 1.9.x support.
@@ -501,3 +514,5 @@ end
501
514
  [@jwinter]: https://github.com/jwinter
502
515
  [@nerdrew]: https://github.com/nerdrew
503
516
  [@kylekyle]: https://github.com/kylekyle
517
+ [@smudge]: https://github.com/smudge
518
+ [@mwitek]: https://github.com/mwitek
data/Gemfile CHANGED
@@ -20,11 +20,11 @@ group :test do
20
20
  gem "coveralls"
21
21
  gem "simplecov", ">= 0.9"
22
22
  gem "json", ">= 1.8.1"
23
- gem "rubocop", "= 0.36.0"
23
+ gem "rubocop", "= 0.39.0"
24
24
  gem "rspec", "~> 3.0"
25
25
  gem "rspec-its"
26
26
  gem "yardstick"
27
- gem "certificate_authority"
27
+ gem "certificate_authority", :require => false
28
28
  end
29
29
 
30
30
  group :doc do
@@ -93,7 +93,7 @@ module HTTP
93
93
  when :null then HTTP::Timeout::Null
94
94
  when :global then HTTP::Timeout::Global
95
95
  when :per_operation then HTTP::Timeout::PerOperation
96
- else fail ArgumentError, "Unsupported Timeout class: #{klass}"
96
+ else raise ArgumentError, "Unsupported Timeout class: #{klass}"
97
97
  end
98
98
 
99
99
  [:read, :write, :connect].each do |k|
@@ -153,8 +153,10 @@ module HTTP
153
153
  proxy_hash[:proxy_port] = proxy[1] if proxy[1].is_a?(Integer)
154
154
  proxy_hash[:proxy_username] = proxy[2] if proxy[2].is_a?(String)
155
155
  proxy_hash[:proxy_password] = proxy[3] if proxy[3].is_a?(String)
156
+ proxy_hash[:proxy_headers] = proxy[2] if proxy[2].is_a?(Hash)
157
+ proxy_hash[:proxy_headers] = proxy[4] if proxy[4].is_a?(Hash)
156
158
 
157
- fail(RequestError, "invalid HTTP proxy: #{proxy_hash}") unless [2, 4].include?(proxy_hash.keys.size)
159
+ raise(RequestError, "invalid HTTP proxy: #{proxy_hash}") unless (2..5).cover?(proxy_hash.keys.size)
158
160
 
159
161
  branch default_options.with_proxy(proxy_hash)
160
162
  end
@@ -68,12 +68,13 @@ module HTTP
68
68
  end
69
69
 
70
70
  res = Response.new(
71
- :status => @connection.status_code,
72
- :version => @connection.http_version,
73
- :headers => @connection.headers,
74
- :connection => @connection,
75
- :encoding => options.encoding,
76
- :uri => req.uri
71
+ :status => @connection.status_code,
72
+ :version => @connection.http_version,
73
+ :headers => @connection.headers,
74
+ :proxy_headers => @connection.proxy_response_headers,
75
+ :connection => @connection,
76
+ :encoding => options.encoding,
77
+ :uri => req.uri
77
78
  )
78
79
 
79
80
  @connection.finish_response if req.verb == :head
@@ -96,7 +97,7 @@ module HTTP
96
97
  # Verify our request isn't going to be made against another URI
97
98
  def verify_connection!(uri)
98
99
  if default_options.persistent? && uri.origin != default_options.persistent
99
- fail StateError, "Persistence is enabled for #{default_options.persistent}, but we got #{uri.origin}"
100
+ raise StateError, "Persistence is enabled for #{default_options.persistent}, but we got #{uri.origin}"
100
101
  # We re-create the connection object because we want to let prior requests
101
102
  # lazily load the body as long as possible, and this mimics prior functionality.
102
103
  elsif @connection && (!@connection.keep_alive? || @connection.expired?)
@@ -19,6 +19,9 @@ module HTTP
19
19
  # HTTP/1.1
20
20
  HTTP_1_1 = "1.1".freeze
21
21
 
22
+ # Returned after HTTP CONNECT (via proxy)
23
+ attr_reader :proxy_response_headers
24
+
22
25
  # @param [HTTP::Request] req
23
26
  # @param [HTTP::Options] options
24
27
  # @raise [HTTP::ConnectionError] when failed to connect
@@ -60,11 +63,8 @@ module HTTP
60
63
  # @param [Request] req Request to send to the server
61
64
  # @return [nil]
62
65
  def send_request(req)
63
- if @pending_response
64
- fail StateError, "Tried to send a request while one is pending already. Make sure you read off the body."
65
- elsif @pending_request
66
- fail StateError, "Tried to send a request while a response is pending. Make sure you've fully read the body from the request."
67
- end
66
+ raise StateError, "Tried to send a request while one is pending already. Make sure you read off the body." if @pending_response
67
+ raise StateError, "Tried to send a request while a response is pending. Make sure you read off the body." if @pending_request
68
68
 
69
69
  @pending_request = true
70
70
 
@@ -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 ConnectionError, "couldn't read response headers" unless @parser.headers?
97
+ raise ConnectionError, "couldn't read response headers" unless @parser.headers?
98
98
  break
99
99
  elsif @parser.headers?
100
100
  break
@@ -167,6 +167,7 @@ module HTTP
167
167
  @pending_response = true
168
168
 
169
169
  read_headers!
170
+ @proxy_response_headers = @parser.headers
170
171
 
171
172
  if @parser.status_code != 200
172
173
  @failed_proxy_connect = true
@@ -171,7 +171,7 @@ module HTTP
171
171
  when object.respond_to?(:to_hash) then object.to_hash
172
172
  when object.respond_to?(:to_h) then object.to_h
173
173
  when object.respond_to?(:to_a) then object.to_a
174
- else fail Error, "Can't coerce #{object.inspect} to Headers"
174
+ else raise Error, "Can't coerce #{object.inspect} to Headers"
175
175
  end
176
176
  end
177
177
 
@@ -197,7 +197,7 @@ module HTTP
197
197
 
198
198
  return normalized if normalized =~ COMPLIANT_NAME_RE
199
199
 
200
- fail InvalidHeaderNameError, "Invalid HTTP header field name: #{name.inspect}"
200
+ raise InvalidHeaderNameError, "Invalid HTTP header field name: #{name.inspect}"
201
201
  end
202
202
  end
203
203
  end
@@ -33,7 +33,7 @@ module HTTP
33
33
  # @raise [Error] if no adapter found
34
34
  # @return [Class]
35
35
  def [](type)
36
- adapters[normalize type] || fail(Error, "Unknown MIME type: #{type}")
36
+ adapters[normalize type] || raise(Error, "Unknown MIME type: #{type}")
37
37
  end
38
38
 
39
39
  # Register a shortcut for MIME type
@@ -135,7 +135,7 @@ module HTTP
135
135
  private
136
136
 
137
137
  def argument_error!(message)
138
- fail(Error, message, caller[1..-1])
138
+ raise(Error, message, caller[1..-1])
139
139
  end
140
140
  end
141
141
  end
@@ -51,8 +51,8 @@ module HTTP
51
51
  while REDIRECT_CODES.include? @response.status.code
52
52
  @visited << "#{@request.verb} #{@request.uri}"
53
53
 
54
- fail TooManyRedirectsError if too_many_hops?
55
- fail EndlessRedirectError if endless_loop?
54
+ raise TooManyRedirectsError if too_many_hops?
55
+ raise EndlessRedirectError if endless_loop?
56
56
 
57
57
  @response.flush
58
58
 
@@ -80,13 +80,13 @@ module HTTP
80
80
  # Redirect policy for follow
81
81
  # @return [Request]
82
82
  def redirect_to(uri)
83
- fail StateError, "no Location header in redirect" unless uri
83
+ raise StateError, "no Location header in redirect" unless uri
84
84
 
85
85
  verb = @request.verb
86
86
  code = @response.status.code
87
87
 
88
88
  if UNSAFE_VERBS.include?(verb) && STRICT_SENSITIVE_CODES.include?(code)
89
- fail StateError, "can't follow #{@response.status} redirect" if @strict
89
+ raise StateError, "can't follow #{@response.status} redirect" if @strict
90
90
  verb = :get
91
91
  end
92
92
 
@@ -77,8 +77,8 @@ module HTTP
77
77
  @uri = normalize_uri(opts.fetch(:uri))
78
78
  @scheme = @uri.scheme.to_s.downcase.to_sym if @uri.scheme
79
79
 
80
- fail(UnsupportedMethodError, "unknown method: #{verb}") unless METHODS.include?(@verb)
81
- fail(UnsupportedSchemeError, "unknown scheme: #{scheme}") unless SCHEMES.include?(@scheme)
80
+ raise(UnsupportedMethodError, "unknown method: #{verb}") unless METHODS.include?(@verb)
81
+ raise(UnsupportedSchemeError, "unknown scheme: #{scheme}") unless SCHEMES.include?(@scheme)
82
82
 
83
83
  @proxy = opts[:proxy] || {}
84
84
  @body = opts[:body]
@@ -106,7 +106,7 @@ module HTTP
106
106
 
107
107
  # Stream the request to a socket
108
108
  def stream(socket)
109
- include_proxy_authorization_header if using_authenticated_proxy? && !@uri.https?
109
+ include_proxy_headers if using_proxy? && !@uri.https?
110
110
  Request::Writer.new(socket, body, headers, headline).stream
111
111
  end
112
112
 
@@ -117,7 +117,12 @@ module HTTP
117
117
 
118
118
  # Is this request using an authenticated proxy?
119
119
  def using_authenticated_proxy?
120
- proxy && proxy.keys.size == 4
120
+ proxy && proxy.keys.size >= 4
121
+ end
122
+
123
+ def include_proxy_headers
124
+ headers.merge!(proxy[:proxy_headers]) if proxy.key?(:proxy_headers)
125
+ include_proxy_authorization_header if using_authenticated_proxy?
121
126
  end
122
127
 
123
128
  # Compute and add the Proxy-Authorization header
@@ -137,7 +142,7 @@ module HTTP
137
142
 
138
143
  # Compute HTTP request header for direct or proxy request
139
144
  def headline
140
- request_uri = using_proxy? ? uri : uri.omit(:scheme, :authority)
145
+ request_uri = (using_proxy? && !uri.https?) ? uri : uri.omit(:scheme, :authority)
141
146
  "#{verb.to_s.upcase} #{request_uri.omit :fragment} HTTP/#{version}"
142
147
  end
143
148
 
@@ -154,7 +159,7 @@ module HTTP
154
159
  )
155
160
 
156
161
  connect_headers[Headers::PROXY_AUTHORIZATION] = proxy_authorization_header if using_authenticated_proxy?
157
-
162
+ connect_headers.merge!(proxy[:proxy_headers]) if proxy.key?(:proxy_headers)
158
163
  connect_headers
159
164
  end
160
165
 
@@ -54,7 +54,7 @@ module HTTP
54
54
  if @body.is_a?(String) && !@headers[Headers::CONTENT_LENGTH]
55
55
  @request_header << "#{Headers::CONTENT_LENGTH}: #{@body.bytesize}"
56
56
  elsif @body.is_a?(Enumerable) && CHUNKED != @headers[Headers::TRANSFER_ENCODING]
57
- fail(RequestError, "invalid transfer encoding")
57
+ raise(RequestError, "invalid transfer encoding")
58
58
  end
59
59
  end
60
60
 
@@ -86,7 +86,7 @@ module HTTP
86
86
  end
87
87
 
88
88
  write(CHUNKED_END)
89
- else fail TypeError, "invalid body type: #{@body.class}"
89
+ else raise TypeError, "invalid body type: #{@body.class}"
90
90
  end
91
91
  end
92
92
 
@@ -102,7 +102,7 @@ module HTTP
102
102
 
103
103
  def validate_body_type!
104
104
  return if VALID_BODY_TYPES.any? { |type| @body.is_a? type }
105
- fail RequestError, "body of wrong type: #{@body.class}"
105
+ raise RequestError, "body of wrong type: #{@body.class}"
106
106
  end
107
107
  end
108
108
  end
@@ -23,20 +23,25 @@ module HTTP
23
23
  # @return [URI, nil]
24
24
  attr_reader :uri
25
25
 
26
+ # @return [Hash]
27
+ attr_reader :proxy_headers
28
+
26
29
  # Inits a new instance
27
30
  #
28
31
  # @option opts [Integer] :status Status code
29
32
  # @option opts [String] :version HTTP version
30
33
  # @option opts [Hash] :headers
34
+ # @option opts [Hash] :proxy_headers
31
35
  # @option opts [HTTP::Connection] :connection
32
36
  # @option opts [String] :encoding Encoding to use when reading body
33
37
  # @option opts [String] :body
34
38
  # @option opts [String] :uri
35
39
  def initialize(opts)
36
- @version = opts.fetch(:version)
37
- @uri = HTTP::URI.parse(opts.fetch(:uri)) if opts.include? :uri
38
- @status = HTTP::Response::Status.new(opts.fetch(:status))
39
- @headers = HTTP::Headers.coerce(opts[:headers] || {})
40
+ @version = opts.fetch(:version)
41
+ @uri = HTTP::URI.parse(opts.fetch(:uri)) if opts.include? :uri
42
+ @status = HTTP::Response::Status.new(opts.fetch(:status))
43
+ @headers = HTTP::Headers.coerce(opts[:headers] || {})
44
+ @proxy_headers = HTTP::Headers.coerce(opts[:proxy_headers] || {})
40
45
 
41
46
  if opts.include?(:connection)
42
47
  connection = opts.fetch(:connection)
@@ -33,7 +33,7 @@ module HTTP
33
33
  def to_s
34
34
  return @contents if @contents
35
35
 
36
- fail StateError, "body is being streamed" unless @streaming.nil?
36
+ raise StateError, "body is being streamed" unless @streaming.nil?
37
37
 
38
38
  # see issue 312
39
39
  begin
@@ -59,7 +59,7 @@ module HTTP
59
59
 
60
60
  # Assert that the body is actively being streamed
61
61
  def stream!
62
- fail StateError, "body has already been consumed" if @streaming == false
62
+ raise StateError, "body has already been consumed" if @streaming == false
63
63
  @streaming = true
64
64
  end
65
65
 
@@ -26,7 +26,7 @@ module HTTP
26
26
 
27
27
  return new code if code
28
28
 
29
- fail Error, "Can't coerce #{object.class}(#{object}) to #{self}"
29
+ raise Error, "Can't coerce #{object.class}(#{object}) to #{self}"
30
30
  end
31
31
  alias [] coerce
32
32
 
@@ -83,6 +83,36 @@ module HTTP
83
83
  "#{code} #{reason}".strip
84
84
  end
85
85
 
86
+ # Check if status code is informational (1XX)
87
+ # @return [Boolean]
88
+ def informational?
89
+ 100 <= code && code < 200
90
+ end
91
+
92
+ # Check if status code is successful (2XX)
93
+ # @return [Boolean]
94
+ def success?
95
+ 200 <= code && code < 300
96
+ end
97
+
98
+ # Check if status code is redirection (3XX)
99
+ # @return [Boolean]
100
+ def redirect?
101
+ 300 <= code && code < 400
102
+ end
103
+
104
+ # Check if status code is client error (4XX)
105
+ # @return [Boolean]
106
+ def client_error?
107
+ 400 <= code && code < 500
108
+ end
109
+
110
+ # Check if status code is server error (5XX)
111
+ # @return [Boolean]
112
+ def server_error?
113
+ 500 <= code && code < 600
114
+ end
115
+
86
116
  # Symbolized {#reason}
87
117
  #
88
118
  # @return [nil] unless code is well-known (see REASONS)
@@ -108,7 +138,7 @@ module HTTP
108
138
  end
109
139
 
110
140
  def __setobj__(obj)
111
- fail TypeError, "Expected #{obj.inspect} to respond to #to_i" unless obj.respond_to? :to_i
141
+ raise TypeError, "Expected #{obj.inspect} to respond to #to_i" unless obj.respond_to? :to_i
112
142
  @code = obj.to_i
113
143
  end
114
144
 
@@ -122,7 +122,7 @@ module HTTP
122
122
  def log_time
123
123
  @time_left -= (Time.now - @started)
124
124
  if time_left <= 0
125
- fail TimeoutError, "Timed out after using the allocated #{total_timeout} seconds"
125
+ raise TimeoutError, "Timed out after using the allocated #{total_timeout} seconds"
126
126
  end
127
127
 
128
128
  reset_timer
@@ -60,14 +60,12 @@ module HTTP
60
60
  def readpartial(size)
61
61
  loop do
62
62
  result = @socket.read_nonblock(size, :exception => false)
63
- if result.nil?
64
- return :eof
65
- elsif result != :wait_readable
66
- return result
67
- end
63
+
64
+ return :eof if result.nil?
65
+ return result if result != :wait_readable
68
66
 
69
67
  unless IO.select([@socket], nil, nil, read_timeout)
70
- fail TimeoutError, "Read timed out after #{read_timeout} seconds"
68
+ raise TimeoutError, "Read timed out after #{read_timeout} seconds"
71
69
  end
72
70
  end
73
71
  end
@@ -79,7 +77,7 @@ module HTTP
79
77
  return result unless result == :wait_writable
80
78
 
81
79
  unless IO.select(nil, [@socket], nil, write_timeout)
82
- fail TimeoutError, "Write timed out after #{write_timeout} seconds"
80
+ raise TimeoutError, "Write timed out after #{write_timeout} seconds"
83
81
  end
84
82
  end
85
83
  end
@@ -63,7 +63,7 @@ module HTTP
63
63
  @uri = Addressable::URI.new(options_or_uri)
64
64
  when Addressable::URI
65
65
  @uri = options_or_uri
66
- else fail TypeError, "expected Hash for options, got #{options_or_uri.class}"
66
+ else raise TypeError, "expected Hash for options, got #{options_or_uri.class}"
67
67
  end
68
68
  end
69
69
 
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module HTTP
3
- VERSION = "2.0.0.pre".freeze
3
+ VERSION = "2.0.0".freeze
4
4
  end
@@ -202,6 +202,12 @@ RSpec.describe HTTP::Request do
202
202
  context "with proxy" do
203
203
  let(:proxy) { {:user => "user", :pass => "pass"} }
204
204
  it { is_expected.to eq "GET http://example.com/foo?bar=baz HTTP/1.1" }
205
+
206
+ context "and HTTPS uri" do
207
+ let(:request_uri) { "https://example.com/foo?bar=baz" }
208
+
209
+ it { is_expected.to eq "GET /foo?bar=baz HTTP/1.1" }
210
+ end
205
211
  end
206
212
  end
207
213
  end
@@ -34,6 +34,126 @@ RSpec.describe HTTP::Response::Status do
34
34
  end
35
35
  end
36
36
 
37
+ context "with 1xx codes" do
38
+ subject { (100...200).map { |code| described_class.new code } }
39
+
40
+ it "is #informational?" do
41
+ expect(subject).to all satisfy(&:informational?)
42
+ end
43
+
44
+ it "is not #success?" do
45
+ expect(subject).to all satisfy { |status| !status.success? }
46
+ end
47
+
48
+ it "is not #redirect?" do
49
+ expect(subject).to all satisfy { |status| !status.redirect? }
50
+ end
51
+
52
+ it "is not #client_error?" do
53
+ expect(subject).to all satisfy { |status| !status.client_error? }
54
+ end
55
+
56
+ it "is not #server_error?" do
57
+ expect(subject).to all satisfy { |status| !status.server_error? }
58
+ end
59
+ end
60
+
61
+ context "with 2xx codes" do
62
+ subject { (200...300).map { |code| described_class.new code } }
63
+
64
+ it "is not #informational?" do
65
+ expect(subject).to all satisfy { |status| !status.informational? }
66
+ end
67
+
68
+ it "is #success?" do
69
+ expect(subject).to all satisfy(&:success?)
70
+ end
71
+
72
+ it "is not #redirect?" do
73
+ expect(subject).to all satisfy { |status| !status.redirect? }
74
+ end
75
+
76
+ it "is not #client_error?" do
77
+ expect(subject).to all satisfy { |status| !status.client_error? }
78
+ end
79
+
80
+ it "is not #server_error?" do
81
+ expect(subject).to all satisfy { |status| !status.server_error? }
82
+ end
83
+ end
84
+
85
+ context "with 3xx codes" do
86
+ subject { (300...400).map { |code| described_class.new code } }
87
+
88
+ it "is not #informational?" do
89
+ expect(subject).to all satisfy { |status| !status.informational? }
90
+ end
91
+
92
+ it "is not #success?" do
93
+ expect(subject).to all satisfy { |status| !status.success? }
94
+ end
95
+
96
+ it "is #redirect?" do
97
+ expect(subject).to all satisfy(&:redirect?)
98
+ end
99
+
100
+ it "is not #client_error?" do
101
+ expect(subject).to all satisfy { |status| !status.client_error? }
102
+ end
103
+
104
+ it "is not #server_error?" do
105
+ expect(subject).to all satisfy { |status| !status.server_error? }
106
+ end
107
+ end
108
+
109
+ context "with 4xx codes" do
110
+ subject { (400...500).map { |code| described_class.new code } }
111
+
112
+ it "is not #informational?" do
113
+ expect(subject).to all satisfy { |status| !status.informational? }
114
+ end
115
+
116
+ it "is not #success?" do
117
+ expect(subject).to all satisfy { |status| !status.success? }
118
+ end
119
+
120
+ it "is not #redirect?" do
121
+ expect(subject).to all satisfy { |status| !status.redirect? }
122
+ end
123
+
124
+ it "is #client_error?" do
125
+ expect(subject).to all satisfy(&:client_error?)
126
+ end
127
+
128
+ it "is not #server_error?" do
129
+ expect(subject).to all satisfy { |status| !status.server_error? }
130
+ end
131
+ end
132
+
133
+ context "with 5xx codes" do
134
+ subject { (500...600).map { |code| described_class.new code } }
135
+
136
+ it "is not #informational?" do
137
+ expect(subject).to all satisfy { |status| !status.informational? }
138
+ end
139
+
140
+ it "is not #success?" do
141
+ expect(subject).to all satisfy { |status| !status.success? }
142
+ end
143
+
144
+ it "is not #redirect?" do
145
+ expect(subject).to all satisfy { |status| !status.redirect? }
146
+ end
147
+
148
+ it "is not #client_error?" do
149
+ expect(subject).to all satisfy { |status| !status.client_error? }
150
+ end
151
+
152
+ it "is #server_error?" do
153
+ expect(subject).to all satisfy(&:server_error?)
154
+ end
155
+ end
156
+
37
157
  describe "#to_sym" do
38
158
  subject { described_class.new(code).to_sym }
39
159
 
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: 2.0.0.pre
4
+ version: 2.0.0
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-04-03 00:00:00.000000000 Z
14
+ date: 2016-04-23 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: http_parser.rb
@@ -178,9 +178,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
178
178
  version: '0'
179
179
  required_rubygems_version: !ruby/object:Gem::Requirement
180
180
  requirements:
181
- - - ">"
181
+ - - ">="
182
182
  - !ruby/object:Gem::Version
183
- version: 1.3.1
183
+ version: '0'
184
184
  requirements: []
185
185
  rubyforge_project:
186
186
  rubygems_version: 2.5.1