reel 0.4.0 → 0.5.0.pre

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of reel might be problematic. Click here for more details.

Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -2
  3. data/Gemfile +6 -0
  4. data/README.md +26 -16
  5. data/benchmarks/hello_reel.rb +1 -1
  6. data/benchmarks/reel_pool.rb +27 -0
  7. data/examples/hello_world.rb +2 -2
  8. data/examples/{ssl_hello_world.rb → https_hello_world.rb} +1 -1
  9. data/examples/roundtrip.rb +1 -1
  10. data/examples/server_sent_events.rb +22 -18
  11. data/examples/spy_hello_world.rb +22 -0
  12. data/examples/websockets.rb +3 -3
  13. data/lib/reel.rb +6 -9
  14. data/lib/reel/connection.rb +40 -42
  15. data/lib/reel/mixins.rb +3 -1
  16. data/lib/reel/request.rb +40 -9
  17. data/lib/reel/request/body.rb +65 -0
  18. data/lib/reel/request/info.rb +21 -0
  19. data/lib/reel/{request_parser.rb → request/parser.rb} +2 -2
  20. data/lib/reel/request/state_machine.rb +26 -0
  21. data/lib/reel/response.rb +4 -11
  22. data/lib/reel/response/writer.rb +59 -0
  23. data/lib/reel/server.rb +30 -6
  24. data/lib/reel/server/http.rb +20 -0
  25. data/lib/reel/server/https.rb +63 -0
  26. data/lib/reel/spy.rb +71 -0
  27. data/lib/reel/stream.rb +2 -2
  28. data/lib/reel/version.rb +2 -2
  29. data/lib/reel/websocket.rb +1 -1
  30. data/reel.gemspec +3 -3
  31. data/spec/fixtures/ca.crt +27 -0
  32. data/spec/fixtures/ca.key +27 -0
  33. data/spec/fixtures/client.crt +81 -20
  34. data/spec/fixtures/client.unsigned.crt +22 -0
  35. data/spec/fixtures/server.crt +80 -20
  36. data/spec/reel/connection_spec.rb +50 -11
  37. data/spec/reel/{server_spec.rb → http_server_spec.rb} +1 -1
  38. data/spec/reel/https_server_spec.rb +119 -0
  39. data/spec/reel/{response_writer_spec.rb → response/writer_spec.rb} +10 -2
  40. data/spec/reel/websocket_spec.rb +2 -2
  41. data/spec/spec_helper.rb +3 -34
  42. data/spec/support/example_request.rb +34 -0
  43. metadata +56 -43
  44. data/examples/chunked.rb +0 -25
  45. data/lib/reel/request_body.rb +0 -56
  46. data/lib/reel/request_info.rb +0 -19
  47. data/lib/reel/response_writer.rb +0 -76
  48. data/lib/reel/ssl_server.rb +0 -41
  49. data/spec/reel/ssl_server_spec.rb +0 -54
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
  require 'net/http'
3
3
 
4
- describe Reel::Server do
4
+ describe Reel::Server::HTTP do
5
5
  let(:endpoint) { URI(example_url) }
6
6
  let(:response_body) { "ohai thar" }
7
7
 
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+ require 'net/http'
3
+
4
+ describe Reel::Server::HTTPS do
5
+ let(:example_https_port) { example_port + 1 }
6
+ let(:example_url) { "https://#{example_addr}:#{example_https_port}#{example_path}" }
7
+ let(:endpoint) { URI(example_url) }
8
+ let(:response_body) { "ohai thar" }
9
+
10
+ let(:ca_file) { fixture_dir.join('ca.crt').to_s }
11
+
12
+ let(:server_cert) { fixture_dir.join("server.crt") .read }
13
+ let(:server_key) { fixture_dir.join("server.key") .read }
14
+ let(:client_cert) { fixture_dir.join("client.crt") .read }
15
+ let(:client_cert_unsigned) { fixture_dir.join("client.unsigned.crt").read }
16
+ let(:client_key) { fixture_dir.join("client.key") .read }
17
+
18
+ it "receives HTTP requests and sends responses" do
19
+ ex = nil
20
+
21
+ handler = proc do |connection|
22
+ begin
23
+ request = connection.request
24
+ request.method.should eq 'GET'
25
+ request.version.should eq "1.1"
26
+ request.url.should eq example_path
27
+
28
+ connection.respond :ok, response_body
29
+ rescue => ex
30
+ end
31
+ end
32
+
33
+ with_reel_https_server(handler) do
34
+ http = Net::HTTP.new(endpoint.host, endpoint.port)
35
+ http.use_ssl = true
36
+ http.ca_file = self.ca_file
37
+
38
+ request = Net::HTTP::Get.new(endpoint.path)
39
+ response = http.request(request)
40
+
41
+ response.body.should eq response_body
42
+ end
43
+
44
+ raise ex if ex
45
+ end
46
+
47
+ it 'verifies client SSL certs when provided with a CA' do
48
+ ex = nil
49
+
50
+ handler = proc do |connection|
51
+ begin
52
+ request = connection.request
53
+ request.method.should eq 'GET'
54
+ request.version.should eq '1.1'
55
+ request.url.should eq example_path
56
+
57
+ connection.respond :ok, response_body
58
+ rescue => ex
59
+ end
60
+ end
61
+
62
+ with_reel_https_server(handler, :ca_file => self.ca_file) do
63
+ http = Net::HTTP.new(endpoint.host, endpoint.port)
64
+ http.use_ssl = true
65
+ http.ca_file = self.ca_file
66
+ http.cert = OpenSSL::X509::Certificate.new self.client_cert
67
+ http.key = OpenSSL::PKey::RSA.new self.client_key
68
+
69
+ request = Net::HTTP::Get.new(endpoint.path)
70
+ response = http.request(request)
71
+
72
+ response.body.should eq response_body
73
+ end
74
+
75
+ raise ex if ex
76
+ end
77
+
78
+ it %{fails to verify client certificates that aren't signed} do
79
+ ex = nil
80
+
81
+ handler = proc do |connection|
82
+ begin
83
+ request = connection.request
84
+ request.method.should eq 'GET'
85
+ request.version.should eq '1.1'
86
+ request.url.should eq example_path
87
+
88
+ connection.respond :ok, response_body
89
+ rescue => ex
90
+ end
91
+ end
92
+
93
+ with_reel_https_server(handler, :ca_file => self.ca_file) do
94
+ http = Net::HTTP.new(endpoint.host, endpoint.port)
95
+ http.use_ssl = true
96
+ http.ca_file = self.ca_file
97
+ http.cert = OpenSSL::X509::Certificate.new self.client_cert_unsigned
98
+ http.key = OpenSSL::PKey::RSA.new self.client_key
99
+
100
+ request = Net::HTTP::Get.new(endpoint.path)
101
+
102
+ proc { http.request(request) }.should raise_error(OpenSSL::SSL::SSLError)
103
+ end
104
+
105
+ raise ex if ex
106
+ end
107
+
108
+ def with_reel_https_server(handler, options = {})
109
+ options = {
110
+ :cert => server_cert,
111
+ :key => server_key
112
+ }.merge(options)
113
+
114
+ server = described_class.new(example_addr, example_https_port, options, &handler)
115
+ yield server
116
+ ensure
117
+ server.terminate if server && server.alive?
118
+ end
119
+ end
@@ -1,8 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Reel::Response::Writer do
4
- let(:fixture_path) { File.expand_path("../../fixtures/example.txt", __FILE__) }
4
+ let(:fixture_path) { File.expand_path("../../../fixtures/example.txt", __FILE__) }
5
5
  let(:expected_response) { "HTTP/1.1 200 OK\r\nContent-Length: 56\r\n\r\n#{File.read(fixture_path)}" }
6
+
6
7
  it "streams static files" do
7
8
  with_socket_pair do |socket, peer|
8
9
  writer = described_class.new(socket)
@@ -12,7 +13,14 @@ describe Reel::Response::Writer do
12
13
  writer.handle_response(response)
13
14
  end
14
15
 
15
- peer.readpartial(4096).should eq expected_response
16
+ buf = ""
17
+ begin
18
+ buf << peer.read(95)
19
+ rescue IOError
20
+ # End of body!
21
+ end
22
+
23
+ expect(buf).to eq expected_response
16
24
  end
17
25
  end
18
26
  end
@@ -28,7 +28,7 @@ describe Reel::WebSocket do
28
28
 
29
29
  websocket = connection.request.websocket
30
30
  websocket.should be_a Reel::WebSocket
31
- expect { connection.close }.to raise_error(Reel::Connection::StateError)
31
+ expect { connection.close }.to raise_error(Reel::StateError)
32
32
  end
33
33
  end
34
34
 
@@ -89,7 +89,7 @@ describe Reel::WebSocket do
89
89
  websocket = request.websocket
90
90
  websocket.should be_a Reel::WebSocket
91
91
 
92
- expect { connection.remote_host }.to raise_error(Reel::Connection::StateError)
92
+ expect { connection.remote_host }.to raise_error(Reel::StateError)
93
93
  websocket.remote_host.should == remote_host
94
94
  end
95
95
  end
data/spec/spec_helper.rb CHANGED
@@ -5,6 +5,8 @@ require 'bundler/setup'
5
5
  require 'reel'
6
6
  require 'pry'
7
7
 
8
+ require 'support/example_request'
9
+
8
10
  logfile = File.open(File.expand_path("../../log/test.log", __FILE__), 'a')
9
11
  Celluloid.logger = Logger.new(logfile)
10
12
 
@@ -18,7 +20,7 @@ def example_path; "/example"; end
18
20
  def example_url; "http://#{example_addr}:#{example_port}#{example_path}"; end
19
21
 
20
22
  def with_reel(handler)
21
- server = Reel::Server.new(example_addr, example_port, &handler)
23
+ server = Reel::Server::HTTP.new(example_addr, example_port, &handler)
22
24
  yield server
23
25
  ensure
24
26
  server.terminate if server && server.alive?
@@ -41,39 +43,6 @@ def with_socket_pair
41
43
  end
42
44
  end
43
45
 
44
- class ExampleRequest
45
- extend Forwardable
46
- def_delegators :@headers, :[], :[]=
47
- attr_accessor :method, :path, :version, :body
48
-
49
- def initialize(method = :get, path = "/", version = "1.1", headers = {}, body = nil)
50
- @method = method.to_s.upcase
51
- @path = path
52
- @version = "1.1"
53
- @headers = {
54
- 'Host' => 'www.example.com',
55
- 'Connection' => 'keep-alive',
56
- 'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.78 S',
57
- 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
58
- 'Accept-Encoding' => 'gzip,deflate,sdch',
59
- 'Accept-Language' => 'en-US,en;q=0.8',
60
- 'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.3'
61
- }.merge(headers)
62
-
63
- @body = nil
64
- end
65
-
66
- def to_s
67
- if @body && !@headers['Content-Length']
68
- @headers['Content-Length'] = @body.length
69
- end
70
-
71
- "#{@method} #{@path} HTTP/#{@version}\r\n" <<
72
- @headers.map { |k, v| "#{k}: #{v}" }.join("\r\n") << "\r\n\r\n" <<
73
- (@body ? @body : '')
74
- end
75
- end
76
-
77
46
  module WebSocketHelpers
78
47
  def self.included(spec)
79
48
  spec.instance_eval do
@@ -0,0 +1,34 @@
1
+ require 'forwardable'
2
+
3
+ class ExampleRequest
4
+ extend Forwardable
5
+ def_delegators :@headers, :[], :[]=
6
+ attr_accessor :method, :path, :version, :body
7
+
8
+ def initialize(method = :get, path = "/", version = "1.1", headers = {}, body = nil)
9
+ @method = method.to_s.upcase
10
+ @path = path
11
+ @version = "1.1"
12
+ @headers = {
13
+ 'Host' => 'www.example.com',
14
+ 'Connection' => 'keep-alive',
15
+ 'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.78 S',
16
+ 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
17
+ 'Accept-Encoding' => 'gzip,deflate,sdch',
18
+ 'Accept-Language' => 'en-US,en;q=0.8',
19
+ 'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.3'
20
+ }.merge(headers)
21
+
22
+ @body = body
23
+ end
24
+
25
+ def to_s
26
+ if @body && !@headers['Content-Length']
27
+ @headers['Content-Length'] = @body.length
28
+ end
29
+
30
+ "#{@method} #{@path} HTTP/#{@version}\r\n" <<
31
+ @headers.map { |k, v| "#{k}: #{v}" }.join("\r\n") << "\r\n\r\n" <<
32
+ (@body ? @body : '')
33
+ end
34
+ end
metadata CHANGED
@@ -1,113 +1,113 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Arcieri
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-14 00:00:00.000000000 Z
11
+ date: 2014-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.15.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.15.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: celluloid-io
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.15.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.15.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: http
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 0.5.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.5.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: http_parser.rb
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 0.6.0.beta.2
61
+ version: 0.6.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 0.6.0.beta.2
68
+ version: 0.6.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: websocket_parser
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: 0.1.4
75
+ version: 0.1.6
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: 0.1.4
82
+ version: 0.1.6
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '0'
103
+ version: 2.11.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: '0'
110
+ version: 2.11.0
111
111
  description: A Celluloid::IO-powered HTTP server
112
112
  email:
113
113
  - tony.arcieri@gmail.com
@@ -115,10 +115,10 @@ executables: []
115
115
  extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
- - .coveralls.yml
119
- - .gitignore
120
- - .rspec
121
- - .travis.yml
118
+ - ".coveralls.yml"
119
+ - ".gitignore"
120
+ - ".rspec"
121
+ - ".travis.yml"
122
122
  - CHANGES.md
123
123
  - Gemfile
124
124
  - Guardfile
@@ -128,42 +128,50 @@ files:
128
128
  - benchmarks/hello_goliath.rb
129
129
  - benchmarks/hello_node.js
130
130
  - benchmarks/hello_reel.rb
131
- - examples/chunked.rb
131
+ - benchmarks/reel_pool.rb
132
132
  - examples/hello_world.rb
133
+ - examples/https_hello_world.rb
133
134
  - examples/roundtrip.rb
134
135
  - examples/server_sent_events.rb
135
- - examples/ssl_hello_world.rb
136
+ - examples/spy_hello_world.rb
136
137
  - examples/websockets.rb
137
138
  - lib/reel.rb
138
139
  - lib/reel/connection.rb
139
140
  - lib/reel/logger.rb
140
141
  - lib/reel/mixins.rb
141
142
  - lib/reel/request.rb
142
- - lib/reel/request_body.rb
143
- - lib/reel/request_info.rb
144
- - lib/reel/request_parser.rb
143
+ - lib/reel/request/body.rb
144
+ - lib/reel/request/info.rb
145
+ - lib/reel/request/parser.rb
146
+ - lib/reel/request/state_machine.rb
145
147
  - lib/reel/response.rb
146
- - lib/reel/response_writer.rb
148
+ - lib/reel/response/writer.rb
147
149
  - lib/reel/server.rb
148
- - lib/reel/ssl_server.rb
150
+ - lib/reel/server/http.rb
151
+ - lib/reel/server/https.rb
152
+ - lib/reel/spy.rb
149
153
  - lib/reel/stream.rb
150
154
  - lib/reel/version.rb
151
155
  - lib/reel/websocket.rb
152
156
  - log/.gitignore
153
157
  - logo.png
154
158
  - reel.gemspec
159
+ - spec/fixtures/ca.crt
160
+ - spec/fixtures/ca.key
155
161
  - spec/fixtures/client.crt
156
162
  - spec/fixtures/client.key
163
+ - spec/fixtures/client.unsigned.crt
157
164
  - spec/fixtures/example.txt
158
165
  - spec/fixtures/server.crt
159
166
  - spec/fixtures/server.key
160
167
  - spec/reel/connection_spec.rb
168
+ - spec/reel/http_server_spec.rb
169
+ - spec/reel/https_server_spec.rb
170
+ - spec/reel/response/writer_spec.rb
161
171
  - spec/reel/response_spec.rb
162
- - spec/reel/response_writer_spec.rb
163
- - spec/reel/server_spec.rb
164
- - spec/reel/ssl_server_spec.rb
165
172
  - spec/reel/websocket_spec.rb
166
173
  - spec/spec_helper.rb
174
+ - spec/support/example_request.rb
167
175
  - tasks/rspec.rake
168
176
  homepage: https://github.com/celluloid/reel
169
177
  licenses: []
@@ -174,30 +182,35 @@ require_paths:
174
182
  - lib
175
183
  required_ruby_version: !ruby/object:Gem::Requirement
176
184
  requirements:
177
- - - '>='
185
+ - - ">="
178
186
  - !ruby/object:Gem::Version
179
187
  version: '0'
180
188
  required_rubygems_version: !ruby/object:Gem::Requirement
181
189
  requirements:
182
- - - '>='
190
+ - - ">"
183
191
  - !ruby/object:Gem::Version
184
- version: '0'
192
+ version: 1.3.1
185
193
  requirements: []
186
194
  rubyforge_project:
187
- rubygems_version: 2.0.3
195
+ rubygems_version: 2.2.0
188
196
  signing_key:
189
197
  specification_version: 4
190
198
  summary: A Reel good HTTP server
191
199
  test_files:
200
+ - spec/fixtures/ca.crt
201
+ - spec/fixtures/ca.key
192
202
  - spec/fixtures/client.crt
193
203
  - spec/fixtures/client.key
204
+ - spec/fixtures/client.unsigned.crt
194
205
  - spec/fixtures/example.txt
195
206
  - spec/fixtures/server.crt
196
207
  - spec/fixtures/server.key
197
208
  - spec/reel/connection_spec.rb
209
+ - spec/reel/http_server_spec.rb
210
+ - spec/reel/https_server_spec.rb
211
+ - spec/reel/response/writer_spec.rb
198
212
  - spec/reel/response_spec.rb
199
- - spec/reel/response_writer_spec.rb
200
- - spec/reel/server_spec.rb
201
- - spec/reel/ssl_server_spec.rb
202
213
  - spec/reel/websocket_spec.rb
203
214
  - spec/spec_helper.rb
215
+ - spec/support/example_request.rb
216
+ has_rdoc: