http 0.8.0.pre4 → 0.8.0.pre5

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.
@@ -68,12 +68,6 @@ RSpec.describe HTTP::Response::Status do
68
68
 
69
69
  # "Bad Request"
70
70
  its([400]) { is_expected.to be :bad_request }
71
-
72
- # "Request-URI Too Long"
73
- its([414]) { is_expected.to be :request_uri_too_long }
74
-
75
- # "I'm a Teapot"
76
- its([418]) { is_expected.to be :im_a_teapot }
77
71
  end
78
72
 
79
73
  described_class::SYMBOLS.each do |code, symbol|
@@ -106,12 +106,12 @@ RSpec.describe HTTP do
106
106
 
107
107
  context "with redirects" do
108
108
  it "is easy for 301" do
109
- response = HTTP.with_follow(true).get("#{dummy.endpoint}/redirect-301")
109
+ response = HTTP.follow.get("#{dummy.endpoint}/redirect-301")
110
110
  expect(response.to_s).to match(/<!doctype html>/)
111
111
  end
112
112
 
113
113
  it "is easy for 302" do
114
- response = HTTP.with_follow(true).get("#{dummy.endpoint}/redirect-302")
114
+ response = HTTP.follow.get("#{dummy.endpoint}/redirect-302")
115
115
  expect(response.to_s).to match(/<!doctype html>/)
116
116
  end
117
117
  end
data/spec/spec_helper.rb CHANGED
@@ -17,13 +17,6 @@ require "http"
17
17
  require "rspec/its"
18
18
  require "support/capture_warning"
19
19
 
20
- # Allow testing against a SSL server
21
- def certs_dir
22
- Pathname.new File.expand_path("../../tmp/certs", __FILE__)
23
- end
24
-
25
- require "support/create_certs"
26
-
27
20
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
28
21
  RSpec.configure do |config|
29
22
  config.expect_with :rspec do |expectations|
@@ -5,6 +5,7 @@ require "support/black_hole"
5
5
  require "support/dummy_server/servlet"
6
6
  require "support/servers/config"
7
7
  require "support/servers/runner"
8
+ require "support/ssl_helper"
8
9
 
9
10
  class DummyServer < WEBrick::HTTPServer
10
11
  include ServerConfig
@@ -16,37 +17,25 @@ class DummyServer < WEBrick::HTTPServer
16
17
  :Logger => BlackHole
17
18
  }.freeze
18
19
 
19
- def initialize(options = {})
20
- if options[:ssl]
21
- override_config = {
22
- :SSLEnable => true,
23
- :SSLStartImmediately => true
24
- }
25
- else
26
- override_config = {}
27
- end
28
-
29
- super CONFIG.merge(override_config)
20
+ SSL_CONFIG = CONFIG.merge(
21
+ :SSLEnable => true,
22
+ :SSLStartImmediately => true
23
+ ).freeze
30
24
 
25
+ def initialize(options = {})
26
+ super(options[:ssl] ? SSL_CONFIG : CONFIG)
31
27
  mount("/", Servlet)
32
28
  end
33
29
 
34
30
  def endpoint
35
- "#{ssl? ? 'https' : 'http'}://#{addr}:#{port}"
31
+ "#{scheme}://#{addr}:#{port}"
32
+ end
33
+
34
+ def scheme
35
+ config[:SSLEnable] ? "https" : "http"
36
36
  end
37
37
 
38
38
  def ssl_context
39
- @ssl_context ||= begin
40
- context = OpenSSL::SSL::SSLContext.new
41
- context.verify_mode = OpenSSL::SSL::VERIFY_PEER
42
- context.key = OpenSSL::PKey::RSA.new(
43
- File.read(File.join(certs_dir, "server.key"))
44
- )
45
- context.cert = OpenSSL::X509::Certificate.new(
46
- File.read(File.join(certs_dir, "server.crt"))
47
- )
48
- context.ca_file = File.join(certs_dir, "ca.crt")
49
- context
50
- end
39
+ @ssl_context ||= SSLHelper.server_context
51
40
  end
52
41
  end
@@ -1,4 +1,4 @@
1
- RSpec.shared_context "HTTP handling" do |ssl = false|
1
+ RSpec.shared_context "HTTP handling" do
2
2
  describe "timeouts" do
3
3
  let(:conn_timeout) { 1 }
4
4
  let(:read_timeout) { 1 }
@@ -73,56 +73,18 @@ RSpec.shared_context "HTTP handling" do |ssl = false|
73
73
 
74
74
  let(:response) { client.get(server.endpoint).body.to_s }
75
75
 
76
- context "with localhost" do
77
- let(:endpoint) { server.endpoint.sub("127.0.0.1", "localhost") }
78
-
79
- it "errors if DNS takes too long" do
80
- # Block the localhost lookup
81
- expect(timeout_class::HostResolver)
82
- .to receive(:getaddress).with("localhost").and_return(nil)
83
-
84
- # Request
85
- expect(Resolv::DNS).to receive(:open).with(:timeout => 1) do |_|
86
- sleep 1.25
87
- "127.0.0.1"
88
- end
89
-
90
- expect { client.get(server.endpoint.sub("127.0.0.1", "localhost")) }
91
- .to raise_error(HTTP::TimeoutError, /Timed out/)
92
- end
93
- end
94
-
95
76
  it "errors if connecting takes too long" do
96
- socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
97
-
98
- fake_socket = double(:to_io => socket)
99
- expect(fake_socket).to receive(:connect_nonblock) do |*args|
77
+ expect(TCPSocket).to receive(:open) do
100
78
  sleep 1.25
101
- socket.connect_nonblock(*args)
102
79
  end
103
80
 
104
- allow_any_instance_of(timeout_class).to receive(:socket).and_return(fake_socket)
105
-
106
- expect { response }.to raise_error(HTTP::TimeoutError, /Timed out/)
81
+ expect { response }.to raise_error(HTTP::TimeoutError, /execution/)
107
82
  end
108
83
 
109
84
  it "errors if reading takes too long" do
110
85
  expect { client.get("#{server.endpoint}/sleep").body.to_s }
111
86
  .to raise_error(HTTP::TimeoutError, /Timed out/)
112
87
  end
113
-
114
- unless ssl
115
- it "errors if writing takes too long" do
116
- socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
117
- allow_any_instance_of(timeout_class).to receive(:socket).and_return(socket)
118
-
119
- expect(socket).to receive(:<<) do |*|
120
- sleep 1.25
121
- end
122
-
123
- expect { response }.to raise_error(HTTP::TimeoutError, /Timed out/)
124
- end
125
- end
126
88
  end
127
89
  end
128
90
 
@@ -148,6 +110,18 @@ RSpec.shared_context "HTTP handling" do |ssl = false|
148
110
  expect(sockets_used.uniq.length).to eq(1)
149
111
  end
150
112
 
113
+ context "on a mixed state" do
114
+ it "re-opens the connection" do
115
+ first_socket_id = client.get("#{server.endpoint}/socket/1").body.to_s
116
+
117
+ client.instance_variable_set(:@state, :dirty)
118
+
119
+ second_socket_id = client.get("#{server.endpoint}/socket/2").body.to_s
120
+
121
+ expect(first_socket_id).to_not eq(second_socket_id)
122
+ end
123
+ end
124
+
151
125
  context "when trying to read a stale body" do
152
126
  it "errors" do
153
127
  client.get("#{server.endpoint}/not-found")
@@ -169,8 +143,8 @@ RSpec.shared_context "HTTP handling" do |ssl = false|
169
143
 
170
144
  context "with a socket issue" do
171
145
  it "transparently reopens" do
172
- first_socket = client.get("#{server.endpoint}/socket").body.to_s
173
- expect(first_socket).to_not eq("")
146
+ first_socket_id = client.get("#{server.endpoint}/socket").body.to_s
147
+ expect(first_socket_id).to_not eq("")
174
148
  # Kill off the sockets we used
175
149
  # rubocop:disable Style/RescueModifier
176
150
  DummyServer::Servlet.sockets.each do |socket|
@@ -183,8 +157,8 @@ RSpec.shared_context "HTTP handling" do |ssl = false|
183
157
  expect { client.get("#{server.endpoint}/socket").body.to_s }.to raise_error(IOError)
184
158
 
185
159
  # Should succeed since we create a new socket
186
- second_socket = client.get("#{server.endpoint}/socket").body.to_s
187
- expect(second_socket).to_not eq(first_socket)
160
+ second_socket_id = client.get("#{server.endpoint}/socket").body.to_s
161
+ expect(second_socket_id).to_not eq(first_socket_id)
188
162
  end
189
163
  end
190
164
 
@@ -1,8 +1,4 @@
1
1
  module ServerConfig
2
- def ssl?
3
- !!config[:SSLEnable]
4
- end
5
-
6
2
  def addr
7
3
  config[:BindAddress]
8
4
  end
@@ -0,0 +1,102 @@
1
+ require "pathname"
2
+
3
+ require "certificate_authority"
4
+
5
+ module SSLHelper
6
+ CERTS_PATH = Pathname.new File.expand_path("../../../tmp/certs", __FILE__)
7
+
8
+ class RootCertificate < ::CertificateAuthority::Certificate
9
+ EXTENSIONS = {"keyUsage" => {"usage" => %w(critical keyCertSign)}}
10
+
11
+ def initialize
12
+ super()
13
+
14
+ subject.common_name = "honestachmed.com"
15
+ serial_number.number = 1
16
+ key_material.generate_key
17
+
18
+ self.signing_entity = true
19
+
20
+ sign!("extensions" => EXTENSIONS)
21
+ end
22
+
23
+ def file
24
+ return @file if defined? @file
25
+
26
+ CERTS_PATH.mkpath
27
+
28
+ cert_file = CERTS_PATH.join("ca.crt")
29
+ cert_file.open("w") { |io| io << to_pem }
30
+
31
+ @file = cert_file.to_s
32
+ end
33
+ end
34
+
35
+ class ChildCertificate < ::CertificateAuthority::Certificate
36
+ def initialize(parent)
37
+ super()
38
+
39
+ subject.common_name = "127.0.0.1"
40
+ serial_number.number = 1
41
+
42
+ key_material.generate_key
43
+
44
+ self.parent = parent
45
+
46
+ sign!
47
+ end
48
+
49
+ def cert
50
+ OpenSSL::X509::Certificate.new to_pem
51
+ end
52
+
53
+ def key
54
+ OpenSSL::PKey::RSA.new key_material.private_key.to_pem
55
+ end
56
+ end
57
+
58
+ class << self
59
+ def server_context
60
+ context = OpenSSL::SSL::SSLContext.new
61
+
62
+ context.verify_mode = OpenSSL::SSL::VERIFY_PEER
63
+ context.key = server_cert.key
64
+ context.cert = server_cert.cert
65
+ context.ca_file = ca.file
66
+
67
+ context
68
+ end
69
+
70
+ def client_context
71
+ context = OpenSSL::SSL::SSLContext.new
72
+
73
+ context.options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:options]
74
+ context.verify_mode = OpenSSL::SSL::VERIFY_PEER
75
+ context.key = client_cert.key
76
+ context.cert = client_cert.cert
77
+ context.ca_file = ca.file
78
+
79
+ context
80
+ end
81
+
82
+ def client_params
83
+ {
84
+ :key => client_cert.key,
85
+ :cert => client_cert.cert,
86
+ :ca_file => ca.file
87
+ }
88
+ end
89
+
90
+ %w(server client).each do |side|
91
+ class_eval <<-RUBY, __FILE__, __LINE__
92
+ def #{side}_cert
93
+ @#{side}_cert ||= ChildCertificate.new ca
94
+ end
95
+ RUBY
96
+ end
97
+
98
+ def ca
99
+ @ca ||= RootCertificate.new
100
+ end
101
+ end
102
+ 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: 0.8.0.pre4
4
+ version: 0.8.0.pre5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Arcieri
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-03-29 00:00:00.000000000 Z
13
+ date: 2015-03-31 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: http_parser.rb
@@ -138,13 +138,13 @@ files:
138
138
  - spec/support/black_hole.rb
139
139
  - spec/support/capture_warning.rb
140
140
  - spec/support/connection_reuse_shared.rb
141
- - spec/support/create_certs.rb
142
141
  - spec/support/dummy_server.rb
143
142
  - spec/support/dummy_server/servlet.rb
144
143
  - spec/support/http_handling_shared.rb
145
144
  - spec/support/proxy_server.rb
146
145
  - spec/support/servers/config.rb
147
146
  - spec/support/servers/runner.rb
147
+ - spec/support/ssl_helper.rb
148
148
  homepage: https://github.com/httprb/http.rb
149
149
  licenses:
150
150
  - MIT
@@ -199,11 +199,11 @@ test_files:
199
199
  - spec/support/black_hole.rb
200
200
  - spec/support/capture_warning.rb
201
201
  - spec/support/connection_reuse_shared.rb
202
- - spec/support/create_certs.rb
203
202
  - spec/support/dummy_server.rb
204
203
  - spec/support/dummy_server/servlet.rb
205
204
  - spec/support/http_handling_shared.rb
206
205
  - spec/support/proxy_server.rb
207
206
  - spec/support/servers/config.rb
208
207
  - spec/support/servers/runner.rb
208
+ - spec/support/ssl_helper.rb
209
209
  has_rdoc:
@@ -1,57 +0,0 @@
1
- require "fileutils"
2
- require "certificate_authority"
3
-
4
- FileUtils.mkdir_p(certs_dir)
5
-
6
- #
7
- # Certificate Authority
8
- #
9
-
10
- ca = CertificateAuthority::Certificate.new
11
-
12
- ca.subject.common_name = "honestachmed.com"
13
- ca.serial_number.number = 1
14
- ca.key_material.generate_key
15
- ca.signing_entity = true
16
-
17
- ca.sign! "extensions" => {"keyUsage" => {"usage" => %w(critical keyCertSign)}}
18
-
19
- ca_cert_path = File.join(certs_dir, "ca.crt")
20
- ca_key_path = File.join(certs_dir, "ca.key")
21
-
22
- File.write ca_cert_path, ca.to_pem
23
- File.write ca_key_path, ca.key_material.private_key.to_pem
24
-
25
- #
26
- # Server Certificate
27
- #
28
-
29
- server_cert = CertificateAuthority::Certificate.new
30
- server_cert.subject.common_name = "127.0.0.1"
31
- server_cert.serial_number.number = 1
32
- server_cert.key_material.generate_key
33
- server_cert.parent = ca
34
- server_cert.sign!
35
-
36
- server_cert_path = File.join(certs_dir, "server.crt")
37
- server_key_path = File.join(certs_dir, "server.key")
38
-
39
- File.write server_cert_path, server_cert.to_pem
40
- File.write server_key_path, server_cert.key_material.private_key.to_pem
41
-
42
- #
43
- # Client Certificate
44
- #
45
-
46
- client_cert = CertificateAuthority::Certificate.new
47
- client_cert.subject.common_name = "127.0.0.1"
48
- client_cert.serial_number.number = 1
49
- client_cert.key_material.generate_key
50
- client_cert.parent = ca
51
- client_cert.sign!
52
-
53
- client_cert_path = File.join(certs_dir, "client.crt")
54
- client_key_path = File.join(certs_dir, "client.key")
55
-
56
- File.write client_cert_path, client_cert.to_pem
57
- File.write client_key_path, client_cert.key_material.private_key.to_pem