reel 0.1.0 → 0.2.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.
- data/.travis.yml +2 -5
- data/CHANGES.md +6 -2
- data/README.md +19 -7
- data/bin/reel +49 -5
- data/examples/hello_world.rb +9 -3
- data/examples/websockets.rb +124 -0
- data/lib/rack/handler/reel.rb +84 -0
- data/lib/reel.rb +15 -0
- data/lib/reel/connection.rb +47 -32
- data/lib/reel/rack_worker.rb +90 -0
- data/lib/reel/request.rb +46 -8
- data/lib/reel/response.rb +8 -4
- data/lib/reel/server.rb +7 -4
- data/lib/reel/version.rb +1 -1
- data/lib/reel/websocket.rb +64 -0
- data/reel.gemspec +7 -5
- data/spec/reel/connection_spec.rb +14 -17
- data/spec/reel/rack_worker_spec.rb +67 -0
- data/spec/reel/response_spec.rb +3 -19
- data/spec/reel/server_spec.rb +28 -22
- data/spec/reel/websocket_spec.rb +92 -0
- data/spec/spec_helper.rb +24 -4
- metadata +46 -15
data/spec/reel/server_spec.rb
CHANGED
@@ -4,36 +4,42 @@ require 'net/http'
|
|
4
4
|
describe Reel::Server do
|
5
5
|
let(:endpoint) { URI("http://#{example_addr}:#{example_port}#{example_url}") }
|
6
6
|
let(:response_body) { "ohai thar" }
|
7
|
-
|
7
|
+
|
8
8
|
it "receives HTTP requests and sends responses" do
|
9
|
-
|
9
|
+
ex = nil
|
10
|
+
|
10
11
|
handler = proc do |connection|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
begin
|
13
|
+
request = connection.request
|
14
|
+
request.method.should eq :get
|
15
|
+
request.version.should eq "1.1"
|
16
|
+
request.url.should eq example_url
|
17
|
+
|
18
|
+
connection.respond :ok, response_body
|
19
|
+
rescue => ex
|
20
|
+
end
|
18
21
|
end
|
19
|
-
|
22
|
+
|
20
23
|
with_reel(handler) do
|
21
24
|
response = Net::HTTP.get endpoint
|
22
25
|
response.should eq response_body
|
23
26
|
end
|
24
|
-
|
25
|
-
|
27
|
+
|
28
|
+
raise ex if ex
|
26
29
|
end
|
27
|
-
|
30
|
+
|
28
31
|
it "echoes request bodies as response bodies" do
|
29
|
-
|
32
|
+
ex = nil
|
33
|
+
|
30
34
|
handler = proc do |connection|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
+
begin
|
36
|
+
request = connection.request
|
37
|
+
request.method.should eq :post
|
38
|
+
connection.respond :ok, request.body
|
39
|
+
rescue => ex
|
40
|
+
end
|
35
41
|
end
|
36
|
-
|
42
|
+
|
37
43
|
with_reel(handler) do
|
38
44
|
http = Net::HTTP.new(endpoint.host, endpoint.port)
|
39
45
|
request = Net::HTTP::Post.new(endpoint.request_uri)
|
@@ -43,7 +49,7 @@ describe Reel::Server do
|
|
43
49
|
response.should be_a Net::HTTPOK
|
44
50
|
response.body.should == response_body
|
45
51
|
end
|
46
|
-
|
47
|
-
|
52
|
+
|
53
|
+
raise ex if ex
|
48
54
|
end
|
49
|
-
end
|
55
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Reel::WebSocket do
|
4
|
+
let(:example_host) { "www.example.com" }
|
5
|
+
let(:example_path) { "/example"}
|
6
|
+
let(:example_url) { "ws://#{example_host}#{example_path}" }
|
7
|
+
let(:example_message) { "Hello, World!" }
|
8
|
+
let(:another_message) { "What's going on?" }
|
9
|
+
|
10
|
+
let :handshake_headers do
|
11
|
+
{
|
12
|
+
"Host" => example_host,
|
13
|
+
"Upgrade" => "websocket",
|
14
|
+
"Connection" => "Upgrade",
|
15
|
+
"Sec-WebSocket-Key" => "dGhlIHNhbXBsZSBub25jZQ==",
|
16
|
+
"Origin" => "http://example.com",
|
17
|
+
"Sec-WebSocket-Protocol" => "chat, superchat",
|
18
|
+
"Sec-WebSocket-Version" => "13"
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:handshake) { WebSocket::ClientHandshake.new(:get, example_url, handshake_headers) }
|
23
|
+
|
24
|
+
it "performs websocket handshakes" do
|
25
|
+
with_socket_pair do |client, connection|
|
26
|
+
client << handshake.to_data
|
27
|
+
|
28
|
+
websocket = connection.request
|
29
|
+
websocket.should be_a Reel::WebSocket
|
30
|
+
|
31
|
+
handshake.errors.should be_empty
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "knows its URL" do
|
36
|
+
with_websocket_pair do |_, websocket|
|
37
|
+
websocket.url.should == example_path
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it "knows its headers" do
|
42
|
+
with_websocket_pair do |_, websocket|
|
43
|
+
websocket['Host'].should == example_host
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "reads frames" do
|
48
|
+
with_websocket_pair do |client, websocket|
|
49
|
+
client << WebSocket::Message.new(example_message).to_data
|
50
|
+
client << WebSocket::Message.new(another_message).to_data
|
51
|
+
|
52
|
+
websocket.read.should == example_message
|
53
|
+
websocket.read.should == another_message
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it "writes messages" do
|
58
|
+
with_websocket_pair do |client, websocket|
|
59
|
+
websocket.write example_message
|
60
|
+
websocket.write another_message
|
61
|
+
|
62
|
+
parser = WebSocket::Parser.new
|
63
|
+
|
64
|
+
parser.append client.readpartial(4096) until first_message = parser.next_message
|
65
|
+
first_message.should == example_message
|
66
|
+
|
67
|
+
parser.append client.readpartial(4096) until next_message = parser.next_message
|
68
|
+
next_message.should == another_message
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it "closes" do
|
73
|
+
with_websocket_pair do |_, websocket|
|
74
|
+
websocket.should_not be_closed
|
75
|
+
websocket.close
|
76
|
+
websocket.should be_closed
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def with_websocket_pair
|
81
|
+
with_socket_pair do |client, connection|
|
82
|
+
client << handshake.to_data
|
83
|
+
websocket = connection.request
|
84
|
+
websocket.should be_a Reel::WebSocket
|
85
|
+
|
86
|
+
# Discard handshake
|
87
|
+
client.readpartial(4096)
|
88
|
+
|
89
|
+
yield client, websocket
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require 'bundler/setup'
|
2
2
|
require 'reel'
|
3
3
|
|
4
|
+
logfile = File.open(File.expand_path("../../log/test.log", __FILE__), 'a')
|
5
|
+
Celluloid.logger = Logger.new(logfile)
|
6
|
+
|
4
7
|
def example_addr; '127.0.0.1'; end
|
5
8
|
def example_port; 1234; end
|
6
9
|
def example_url; "/example"; end
|
@@ -12,13 +15,30 @@ ensure
|
|
12
15
|
server.terminate
|
13
16
|
end
|
14
17
|
|
18
|
+
def with_socket_pair
|
19
|
+
host = '127.0.0.1'
|
20
|
+
port = 10103
|
21
|
+
|
22
|
+
server = TCPServer.new(host, port)
|
23
|
+
client = TCPSocket.new(host, port)
|
24
|
+
peer = server.accept
|
25
|
+
|
26
|
+
begin
|
27
|
+
yield client, Reel::Connection.new(peer)
|
28
|
+
ensure
|
29
|
+
server.close rescue nil
|
30
|
+
client.close rescue nil
|
31
|
+
peer.close rescue nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
15
35
|
class ExampleRequest
|
16
36
|
extend Forwardable
|
17
37
|
def_delegators :@headers, :[], :[]=
|
18
|
-
attr_accessor :path, :version, :body
|
38
|
+
attr_accessor :method, :path, :version, :body
|
19
39
|
|
20
|
-
def initialize(
|
21
|
-
@
|
40
|
+
def initialize(method = :get, path = "/", version = "1.1", headers = {}, body = nil)
|
41
|
+
@method = method.to_s.upcase
|
22
42
|
@path = path
|
23
43
|
@version = "1.1"
|
24
44
|
@headers = {
|
@@ -39,7 +59,7 @@ class ExampleRequest
|
|
39
59
|
@headers['Content-Length'] = @body.length
|
40
60
|
end
|
41
61
|
|
42
|
-
"#{@
|
62
|
+
"#{@method} #{@path} HTTP/#{@version}\r\n" <<
|
43
63
|
@headers.map { |k, v| "#{k}: #{v}" }.join("\r\n") << "\r\n\r\n" <<
|
44
64
|
(@body ? @body : '')
|
45
65
|
end
|
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.0.pre
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Tony Arcieri
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-08-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: celluloid-io
|
16
|
-
requirement: &
|
16
|
+
requirement: &70212936553620 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.8.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70212936553620
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: http
|
27
|
-
requirement: &
|
27
|
+
requirement: &70212936553120 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.2.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70212936553120
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: http_parser.rb
|
38
|
-
requirement: &
|
38
|
+
requirement: &70212936552660 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,32 @@ dependencies:
|
|
43
43
|
version: 0.5.3
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70212936552660
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: websocket_parser
|
49
|
+
requirement: &70212936552200 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.1.0
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70212936552200
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rack
|
60
|
+
requirement: &70212936551740 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 1.4.0
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70212936551740
|
47
69
|
- !ruby/object:Gem::Dependency
|
48
70
|
name: rake
|
49
|
-
requirement: &
|
71
|
+
requirement: &70212936551360 !ruby/object:Gem::Requirement
|
50
72
|
none: false
|
51
73
|
requirements:
|
52
74
|
- - ! '>='
|
@@ -54,10 +76,10 @@ dependencies:
|
|
54
76
|
version: '0'
|
55
77
|
type: :development
|
56
78
|
prerelease: false
|
57
|
-
version_requirements: *
|
79
|
+
version_requirements: *70212936551360
|
58
80
|
- !ruby/object:Gem::Dependency
|
59
81
|
name: rspec
|
60
|
-
requirement: &
|
82
|
+
requirement: &70212936550900 !ruby/object:Gem::Requirement
|
61
83
|
none: false
|
62
84
|
requirements:
|
63
85
|
- - ! '>='
|
@@ -65,7 +87,7 @@ dependencies:
|
|
65
87
|
version: '0'
|
66
88
|
type: :development
|
67
89
|
prerelease: false
|
68
|
-
version_requirements: *
|
90
|
+
version_requirements: *70212936550900
|
69
91
|
description: A Celluloid::IO-powered HTTP server
|
70
92
|
email:
|
71
93
|
- tony.arcieri@gmail.com
|
@@ -88,20 +110,27 @@ files:
|
|
88
110
|
- benchmarks/hello_reel.rb
|
89
111
|
- bin/reel
|
90
112
|
- examples/hello_world.rb
|
113
|
+
- examples/websockets.rb
|
114
|
+
- lib/rack/handler/reel.rb
|
91
115
|
- lib/reel.rb
|
92
116
|
- lib/reel/connection.rb
|
93
117
|
- lib/reel/logger.rb
|
118
|
+
- lib/reel/rack_worker.rb
|
94
119
|
- lib/reel/request.rb
|
95
120
|
- lib/reel/request_parser.rb
|
96
121
|
- lib/reel/response.rb
|
97
122
|
- lib/reel/server.rb
|
98
123
|
- lib/reel/version.rb
|
124
|
+
- lib/reel/websocket.rb
|
125
|
+
- log/.gitignore
|
99
126
|
- logo.png
|
100
127
|
- reel.gemspec
|
101
128
|
- spec/fixtures/example.txt
|
102
129
|
- spec/reel/connection_spec.rb
|
130
|
+
- spec/reel/rack_worker_spec.rb
|
103
131
|
- spec/reel/response_spec.rb
|
104
132
|
- spec/reel/server_spec.rb
|
133
|
+
- spec/reel/websocket_spec.rb
|
105
134
|
- spec/spec_helper.rb
|
106
135
|
- tasks/rspec.rake
|
107
136
|
homepage: https://github.com/celluloid/reel
|
@@ -119,9 +148,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
119
148
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
149
|
none: false
|
121
150
|
requirements:
|
122
|
-
- - ! '
|
151
|
+
- - ! '>'
|
123
152
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
153
|
+
version: 1.3.1
|
125
154
|
requirements: []
|
126
155
|
rubyforge_project:
|
127
156
|
rubygems_version: 1.8.10
|
@@ -131,7 +160,9 @@ summary: A reel good HTTP server
|
|
131
160
|
test_files:
|
132
161
|
- spec/fixtures/example.txt
|
133
162
|
- spec/reel/connection_spec.rb
|
163
|
+
- spec/reel/rack_worker_spec.rb
|
134
164
|
- spec/reel/response_spec.rb
|
135
165
|
- spec/reel/server_spec.rb
|
166
|
+
- spec/reel/websocket_spec.rb
|
136
167
|
- spec/spec_helper.rb
|
137
168
|
has_rdoc:
|