reel 0.5.0 → 0.6.0.pre1
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.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/.travis.yml +3 -4
- data/CHANGES.md +25 -5
- data/Gemfile +3 -3
- data/Guardfile +13 -23
- data/examples/roundtrip.rb +15 -5
- data/lib/reel.rb +1 -0
- data/lib/reel/connection.rb +4 -2
- data/lib/reel/request.rb +2 -2
- data/lib/reel/request/body.rb +4 -0
- data/lib/reel/request/info.rb +7 -2
- data/lib/reel/request/parser.rb +5 -1
- data/lib/reel/response.rb +2 -2
- data/lib/reel/response/writer.rb +1 -1
- data/lib/reel/server.rb +21 -10
- data/lib/reel/server/http.rb +1 -1
- data/lib/reel/server/https.rb +6 -18
- data/lib/reel/server/unix.rb +18 -0
- data/lib/reel/spy.rb +2 -1
- data/lib/reel/stream.rb +2 -2
- data/lib/reel/version.rb +2 -2
- data/lib/reel/websocket.rb +77 -44
- data/reel.gemspec +4 -1
- data/spec/reel/connection_spec.rb +85 -66
- data/spec/reel/http_server_spec.rb +8 -11
- data/spec/reel/https_server_spec.rb +22 -33
- data/spec/reel/response/writer_spec.rb +1 -1
- data/spec/reel/response_spec.rb +2 -2
- data/spec/reel/unix_server_spec.rb +41 -0
- data/spec/reel/websocket_spec.rb +95 -20
- data/spec/spec_helper.rb +26 -4
- data/spec/support/create_certs.rb +73 -0
- metadata +65 -43
- data/spec/fixtures/ca.crt +0 -27
- data/spec/fixtures/ca.key +0 -27
- data/spec/fixtures/client.crt +0 -83
- data/spec/fixtures/client.key +0 -27
- data/spec/fixtures/client.unsigned.crt +0 -22
- data/spec/fixtures/server.crt +0 -82
- data/spec/fixtures/server.key +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1a993a695b913f3274786678b7a8080749b5e2b
|
4
|
+
data.tar.gz: fcdccf97f738d01e317292f4f5499f8990d3948a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a25fb72f593a8f05bae8272a4e5d3aeec408af15673ec05216b9abcaf2fae06f127e08f88b7cccc2f0c42f86a319e0ae2ae26bf6c22e7599c5da3fb52f4d8c76
|
7
|
+
data.tar.gz: 0707f29757b92d69e6b9c025702fc2da0823e8e19164c8b3a81f5347d4de3f2f71fb4b94f7000eb9c6dc4bb5d9609185b4a7df61e3211b86d789b0175658b16a
|
data/.rspec
CHANGED
data/.travis.yml
CHANGED
@@ -1,18 +1,17 @@
|
|
1
1
|
rvm:
|
2
2
|
- 1.9.3
|
3
3
|
- 2.0.0
|
4
|
-
- 2.1.
|
4
|
+
- 2.1.2
|
5
5
|
- ruby-head
|
6
6
|
- jruby
|
7
7
|
- jruby-head
|
8
|
-
- rbx
|
8
|
+
- rbx-2
|
9
9
|
|
10
10
|
matrix:
|
11
11
|
allow_failures:
|
12
12
|
- rvm: ruby-head
|
13
|
-
- rvm: jruby
|
14
13
|
- rvm: jruby-head
|
15
|
-
- rvm: rbx
|
14
|
+
- rvm: rbx-2
|
16
15
|
|
17
16
|
notifications:
|
18
17
|
irc: "irc.freenode.org#celluloid"
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,25 @@
|
|
1
|
+
0.6.0 (2015-03-24)
|
2
|
+
-----
|
3
|
+
* Fix stack level too deep when writing to ChunkStream
|
4
|
+
* Use HTTP::Resonse::Status::REASONS table ( HTTP::Response::* deprecated in the HTTP gem )
|
5
|
+
* Use Timers 3.0.0 API
|
6
|
+
* Case-insensitivity for header field names ( i.e. in case a proxy downcases them )
|
7
|
+
* Catch when openssl sometimes fires ECONNRESET, EPIPE, ETIMEDOUT, EHOSTUNREACH and as an error
|
8
|
+
* Unused `optimize` socket modifications taken off all server implementations
|
9
|
+
* Fixed 404 error in roundtrip example
|
10
|
+
* Fixed "Reel::StateError: already processing a request" when client is killed
|
11
|
+
* Numerous updates to rspec.
|
12
|
+
* Switched to websocket/driver and improved websocket handling
|
13
|
+
* Implement DriverEnvironment to fix websocket example
|
14
|
+
* Refactored Server::HTTPS to be more idomatic
|
15
|
+
* Fixed jRuby related test failures
|
16
|
+
* Fixed "ArgumentError: Data object has already been freed" caused by underlying parser.
|
17
|
+
* FINALLY! Support for UNIX Socket servers across all RVM's, as of jRuby 1.7.19
|
18
|
+
* Unified Server#run removes need for duplication of #run across all Server implementations.
|
19
|
+
* Standardized method of rescuing exceptions unique to each type of Server in unified #run method.
|
20
|
+
|
1
21
|
0.5.0 (2014-04-15)
|
2
|
-
|
22
|
+
-----
|
3
23
|
* Reel::Server(::SSL) renamed to Reel::Server::HTTP and Reel::Server::HTTPS
|
4
24
|
* New Reel::Spy API for observing requests and responses from the server
|
5
25
|
* Fixes to chunked encoding handling
|
@@ -8,7 +28,7 @@
|
|
8
28
|
* Ensure response bodies are always closed
|
9
29
|
* Support for passing a fixnum status to Connection#respond
|
10
30
|
|
11
|
-
0.4.0
|
31
|
+
0.4.0 (2013-09-14)
|
12
32
|
-----
|
13
33
|
* Rack adapter moved to the reel-rack project
|
14
34
|
* Pipelining support
|
@@ -23,7 +43,7 @@
|
|
23
43
|
* Remove Reel::App (unmaintained, sorry)
|
24
44
|
* Reel::CODENAME added (0.4.0 is "Garbo")
|
25
45
|
|
26
|
-
0.3.0
|
46
|
+
0.3.0 (2013-02-01)
|
27
47
|
-----
|
28
48
|
* Reel::App: Sinatra-like DSL for defining Reel apps using Octarine
|
29
49
|
* Chunked upload support
|
@@ -33,12 +53,12 @@
|
|
33
53
|
* Bugfix: Send CRLF after chunks
|
34
54
|
* Bugfix: Increase TCP connection backlog to 1024
|
35
55
|
|
36
|
-
0.2.0
|
56
|
+
0.2.0 (2012-09-03)
|
37
57
|
-----
|
38
58
|
* Initial WebSockets support via Reel::WebSocket
|
39
59
|
* Experimental Rack adapter by Alberto Fernández-Capel
|
40
60
|
* Octarine (Sinatra-like DSL) support by Grant Rodgers
|
41
61
|
|
42
|
-
0.1.0
|
62
|
+
0.1.0 (2012-07-12)
|
43
63
|
-----
|
44
64
|
* Initial release
|
data/Gemfile
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem 'celluloid'
|
4
|
-
gem 'celluloid-io'
|
5
|
-
gem 'http'
|
3
|
+
gem 'celluloid'
|
4
|
+
gem 'celluloid-io'
|
5
|
+
gem 'http'
|
6
6
|
|
7
7
|
gem 'jruby-openssl' if defined? JRUBY_VERSION
|
8
8
|
gem 'coveralls', require: false
|
data/Guardfile
CHANGED
@@ -1,24 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
watch(
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
watch('config/routes.rb') { "spec/routing" }
|
15
|
-
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
16
|
-
|
17
|
-
# Capybara features specs
|
18
|
-
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
|
19
|
-
|
20
|
-
# Turnip features and steps
|
21
|
-
watch(%r{^spec/acceptance/(.+)\.feature$})
|
22
|
-
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
1
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
2
|
+
require "guard/rspec/dsl"
|
3
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
4
|
+
|
5
|
+
# RSpec files
|
6
|
+
rspec = dsl.rspec
|
7
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
8
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
9
|
+
watch(rspec.spec_files)
|
10
|
+
|
11
|
+
# Ruby files
|
12
|
+
ruby = dsl.ruby
|
13
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
23
14
|
end
|
24
|
-
|
data/examples/roundtrip.rb
CHANGED
@@ -71,12 +71,22 @@ class WebServer < Reel::Server::HTTP
|
|
71
71
|
|
72
72
|
def on_connection(connection)
|
73
73
|
while request = connection.request
|
74
|
-
|
75
|
-
when Reel::Request
|
76
|
-
route_request connection, request
|
77
|
-
when Reel::WebSocket
|
74
|
+
if request.websocket?
|
78
75
|
info "Received a WebSocket connection"
|
79
|
-
|
76
|
+
|
77
|
+
# We're going to hand off this connection to another actor (Writer/Reader)
|
78
|
+
# However, initially Reel::Connections are "attached" to the
|
79
|
+
# Reel::Server::HTTP actor, meaning that the server manages the connection
|
80
|
+
# lifecycle (e.g. error handling) for us.
|
81
|
+
#
|
82
|
+
# If we want to hand this connection off to another actor, we first
|
83
|
+
# need to detach it from the Reel::Server (in this case, Reel::Server::HTTP)
|
84
|
+
connection.detach
|
85
|
+
|
86
|
+
route_websocket request.websocket
|
87
|
+
return
|
88
|
+
else
|
89
|
+
route_request connection, request
|
80
90
|
end
|
81
91
|
end
|
82
92
|
end
|
data/lib/reel.rb
CHANGED
data/lib/reel/connection.rb
CHANGED
@@ -56,7 +56,7 @@ module Reel
|
|
56
56
|
|
57
57
|
req = @parser.current_request
|
58
58
|
@request_fsm.transition :headers
|
59
|
-
@keepalive = false if req[CONNECTION] == CLOSE || req.version == HTTP_VERSION_1_0
|
59
|
+
@keepalive = false if req.nil? || req[CONNECTION] == CLOSE || req.version == HTTP_VERSION_1_0
|
60
60
|
@current_request = req
|
61
61
|
|
62
62
|
req
|
@@ -120,10 +120,12 @@ module Reel
|
|
120
120
|
@parser.reset
|
121
121
|
@request_fsm.transition :closed
|
122
122
|
end
|
123
|
-
rescue IOError,
|
123
|
+
rescue IOError, SystemCallError, RequestError
|
124
124
|
# The client disconnected early, or there is no request
|
125
125
|
@keepalive = false
|
126
126
|
@request_fsm.transition :closed
|
127
|
+
@parser.reset
|
128
|
+
@current_request = nil
|
127
129
|
end
|
128
130
|
|
129
131
|
# Close the connection
|
data/lib/reel/request.rb
CHANGED
@@ -112,8 +112,8 @@ module Reel
|
|
112
112
|
# the underlying connection
|
113
113
|
def websocket
|
114
114
|
@websocket ||= begin
|
115
|
-
raise StateError, "can't upgrade this request to a websocket" unless websocket?
|
116
|
-
WebSocket.new(
|
115
|
+
raise StateError, "can't upgrade this request to a websocket" unless websocket?
|
116
|
+
WebSocket.new(self, @connection)
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
data/lib/reel/request/body.rb
CHANGED
data/lib/reel/request/info.rb
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
module Reel
|
2
2
|
class Request
|
3
3
|
class Info
|
4
|
+
|
5
|
+
CASE_INSENSITVE_HASH = Hash.new do |hash, key|
|
6
|
+
hash[hash.keys.find {|k| k =~ /#{key}/i}] if key
|
7
|
+
end
|
8
|
+
|
4
9
|
attr_reader :http_method, :url, :http_version, :headers
|
5
10
|
|
6
11
|
def initialize(http_method, url, http_version, headers)
|
7
12
|
@http_method = http_method
|
8
13
|
@url = url
|
9
14
|
@http_version = http_version
|
10
|
-
@headers = headers
|
15
|
+
@headers = CASE_INSENSITVE_HASH.merge headers
|
11
16
|
end
|
12
17
|
|
13
18
|
UPGRADE = 'Upgrade'.freeze
|
@@ -18,4 +23,4 @@ module Reel
|
|
18
23
|
end
|
19
24
|
end
|
20
25
|
end
|
21
|
-
end
|
26
|
+
end
|
data/lib/reel/request/parser.rb
CHANGED
data/lib/reel/response.rb
CHANGED
@@ -7,8 +7,8 @@ module Reel
|
|
7
7
|
CHUNKED = 'chunked'.freeze
|
8
8
|
|
9
9
|
# Use status code tables from the HTTP gem
|
10
|
-
STATUS_CODES = HTTP::Response::
|
11
|
-
SYMBOL_TO_STATUS_CODE =
|
10
|
+
STATUS_CODES = HTTP::Response::Status::REASONS
|
11
|
+
SYMBOL_TO_STATUS_CODE = Hash[STATUS_CODES.map { |k, v| [v.downcase.gsub(/\s|-/, '_').to_sym, k] }].freeze
|
12
12
|
|
13
13
|
attr_reader :status # Status has a special setter to coerce symbol names
|
14
14
|
attr_accessor :reason # Reason can be set explicitly if desired
|
data/lib/reel/response/writer.rb
CHANGED
data/lib/reel/server.rb
CHANGED
@@ -2,14 +2,14 @@ module Reel
|
|
2
2
|
# Base class for Reel servers.
|
3
3
|
#
|
4
4
|
# This class is a Celluloid::IO actor which provides a barebones server
|
5
|
-
# which does not open a socket itself, it just begin handling connections
|
6
|
-
# initialized with a specific kind of protocol-based server.
|
5
|
+
# which does not open a socket itself, it just begin handling connections
|
6
|
+
# once initialized with a specific kind of protocol-based server.
|
7
7
|
|
8
8
|
# For specific protocol support, use:
|
9
9
|
|
10
10
|
# Reel::Server::HTTP
|
11
11
|
# Reel::Server::HTTPS
|
12
|
-
#
|
12
|
+
# Reel::Server::UNIX ( not on jRuby yet )
|
13
13
|
|
14
14
|
class Server
|
15
15
|
include Celluloid::IO
|
@@ -25,6 +25,15 @@ module Reel
|
|
25
25
|
@callback = callback
|
26
26
|
@server = server
|
27
27
|
|
28
|
+
@options[:rescue] ||= []
|
29
|
+
@options[:rescue] += [
|
30
|
+
Errno::ECONNRESET,
|
31
|
+
Errno::EPIPE,
|
32
|
+
Errno::EINPROGRESS,
|
33
|
+
Errno::ETIMEDOUT,
|
34
|
+
Errno::EHOSTUNREACH
|
35
|
+
]
|
36
|
+
|
28
37
|
@server.listen(options.fetch(:backlog, DEFAULT_BACKLOG))
|
29
38
|
|
30
39
|
async.run
|
@@ -35,13 +44,15 @@ module Reel
|
|
35
44
|
end
|
36
45
|
|
37
46
|
def run
|
38
|
-
loop {
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
47
|
+
loop {
|
48
|
+
begin
|
49
|
+
socket = @server.accept
|
50
|
+
rescue *@options[:rescue] => ex
|
51
|
+
Logger.warn "Error accepting socket: #{ex.class}: #{ex.to_s}"
|
52
|
+
next
|
53
|
+
end
|
54
|
+
async.handle_connection socket
|
55
|
+
}
|
45
56
|
end
|
46
57
|
|
47
58
|
def handle_connection(socket)
|
data/lib/reel/server/http.rb
CHANGED
@@ -10,7 +10,7 @@ module Reel
|
|
10
10
|
#
|
11
11
|
# @return [Reel::Server::HTTP] Reel HTTP server actor
|
12
12
|
def initialize(host, port, options={}, &callback)
|
13
|
-
|
13
|
+
server = Celluloid::IO::TCPServer.new(host, port)
|
14
14
|
options.merge!(host: host, port: port)
|
15
15
|
super(server, options, &callback)
|
16
16
|
end
|
data/lib/reel/server/https.rb
CHANGED
@@ -27,37 +27,25 @@ module Reel
|
|
27
27
|
|
28
28
|
# if verify_mode isn't explicitly set, verify peers if we've
|
29
29
|
# been provided CA information that would enable us to do so
|
30
|
-
ssl_context.verify_mode =
|
31
|
-
when options.include?(:verify_mode)
|
30
|
+
ssl_context.verify_mode = if options.include?(:verify_mode)
|
32
31
|
options[:verify_mode]
|
33
|
-
|
32
|
+
elsif options.include?(:ca_file)
|
34
33
|
OpenSSL::SSL::VERIFY_PEER
|
35
|
-
|
34
|
+
elsif options.include?(:ca_path)
|
36
35
|
OpenSSL::SSL::VERIFY_PEER
|
37
36
|
else
|
38
37
|
OpenSSL::SSL::VERIFY_NONE
|
39
38
|
end
|
40
39
|
|
41
|
-
|
40
|
+
@tcpserver = Celluloid::IO::TCPServer.new(host, port)
|
42
41
|
|
43
42
|
server = Celluloid::IO::SSLServer.new(@tcpserver, ssl_context)
|
44
43
|
options.merge!(host: host, port: port)
|
45
44
|
|
45
|
+
options[:rescue] = [ OpenSSL::SSL::SSLError ]
|
46
|
+
|
46
47
|
super(server, options, &callback)
|
47
48
|
end
|
48
|
-
|
49
|
-
def run
|
50
|
-
loop do
|
51
|
-
begin
|
52
|
-
socket = @server.accept
|
53
|
-
rescue OpenSSL::SSL::SSLError => ex
|
54
|
-
Logger.warn "Error accepting SSLSocket: #{ex.class}: #{ex.to_s}"
|
55
|
-
retry
|
56
|
-
end
|
57
|
-
|
58
|
-
async.handle_connection socket
|
59
|
-
end
|
60
|
-
end
|
61
49
|
end
|
62
50
|
end
|
63
51
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Reel
|
2
|
+
class Server
|
3
|
+
class UNIX < Server
|
4
|
+
|
5
|
+
# Create a new Reel HTTPS server
|
6
|
+
#
|
7
|
+
# @option options [String] socket path to bind to
|
8
|
+
# @option options [Fixnum] backlog of requests to accept
|
9
|
+
#
|
10
|
+
# @return [Reel::Server::UNIX] Reel UNIX server actor
|
11
|
+
def initialize(socket_path, options={}, &callback)
|
12
|
+
server = Celluloid::IO::UNIXServer.new(socket_path)
|
13
|
+
options[:socket_path] = socket_path
|
14
|
+
super(server, options, &callback)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/reel/spy.rb
CHANGED
@@ -6,6 +6,7 @@ module Reel
|
|
6
6
|
extend Forwardable
|
7
7
|
|
8
8
|
def_delegators :@socket, :closed?
|
9
|
+
def_delegators :@socket, :addr, :peeraddr, :setsockopt, :getsockname
|
9
10
|
|
10
11
|
def initialize(socket, logger = STDOUT)
|
11
12
|
@socket, @logger = socket, logger
|
@@ -68,4 +69,4 @@ module Reel
|
|
68
69
|
def gold(str); colorize(33, str); end
|
69
70
|
end
|
70
71
|
end
|
71
|
-
end
|
72
|
+
end
|
data/lib/reel/stream.rb
CHANGED
@@ -64,8 +64,8 @@ module Reel
|
|
64
64
|
class ChunkStream < Stream
|
65
65
|
def write(chunk)
|
66
66
|
chunk_header = chunk.bytesize.to_s(16)
|
67
|
-
|
68
|
-
|
67
|
+
super chunk_header + Response::Writer::CRLF
|
68
|
+
super chunk + Response::Writer::CRLF
|
69
69
|
self
|
70
70
|
end
|
71
71
|
alias :<< :write
|