reel 0.4.0.pre5 → 0.4.0.pre6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 44aa1cfa32bf4e362a459a5f18377ac56db1f8c7
4
- data.tar.gz: bbf8201bd08d1f803804bfde3857cea67b66d7fb
3
+ metadata.gz: 62ce6ab7ff51c2b2765a1f13a373135fe8f80f1d
4
+ data.tar.gz: 685cd6aaa68ba0abf31525113bcaa9dc1633e30e
5
5
  SHA512:
6
- metadata.gz: 5fe52aa183298afe122e513a32782b04249af3024aedef8c30ed5ab59949bf73fd2b33341d957d2f39800c4b0b3e78f83ef9a279e9916ae58f9d7f585c64ed1a
7
- data.tar.gz: 185e444d3044b97c939f94d8943039b3c5fcd6b5adb95a00c6cc044e8c003a489e9842270d4b95619b5fbd5472684134b839e12a061cb315729b8b82918dffc5
6
+ metadata.gz: 826bd08b859f751762f444d0ce4192c5efced88d41c1982b4f9488377fc4f051cabc79dadfe7a6859b120313c4e796713bb67b82aa06a85218e2bd7ab4490362
7
+ data.tar.gz: 47fe6ce99b5571deeffeb3909a42bb2b715ddf63e9bfb3b70a487efe4613f059257a1295202d1d4f04869053723712e00d8c1308358023b103ab6084e003eb76
data/CHANGES.md CHANGED
@@ -1,4 +1,4 @@
1
- 0.4.0.pre5
1
+ 0.4.0.pre6
2
2
  ----------
3
3
  * Rack adapter moved to the reel-rack project
4
4
  * Pipelining support
data/Gemfile CHANGED
@@ -1,7 +1,8 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'celluloid', github: 'celluloid/celluloid', branch: 'master'
4
- gem 'celluloid-io', github: 'celluloid/celluloid-io', branch: 'master'
3
+ gem 'celluloid', github: 'celluloid/celluloid'
4
+ gem 'celluloid-io', github: 'celluloid/celluloid-io'
5
+ gem 'http', github: 'tarcieri/http'
5
6
 
6
7
  gem 'jruby-openssl' if defined? JRUBY_VERSION
7
8
  gem 'coveralls', require: false
data/README.md CHANGED
@@ -59,8 +59,58 @@ Node.js (0.6.5) 11735 reqs/s (0.1 ms/req)
59
59
  All Ruby benchmarks done on Ruby 1.9.3. Latencies given are average-per-request
60
60
  and are not amortized across all concurrent requests.
61
61
 
62
- API
63
- ---
62
+ Framework Adapters
63
+ ------------------
64
+
65
+ ### Rack
66
+
67
+ A Rack adapter for Reel is available at:
68
+
69
+ https://github.com/celluloid/reel-rack
70
+
71
+ ### Webmachine
72
+
73
+ The most notable library with native Reel support is
74
+ [webmachine-ruby](https://github.com/seancribbs/webmachine-ruby),
75
+ an advanced HTTP framework for Ruby with a complete state machine for proper
76
+ processing of HTTP/1.1 requests. Together with Reel, Webmachine provides
77
+ full streaming support for both requests and responses.
78
+
79
+ To use Reel with Webmachine, add the following to your Gemfile:
80
+
81
+ ```ruby
82
+ gem 'webmachine', git: 'git://github.com/seancribbs/webmachine-ruby.git'
83
+ ```
84
+
85
+ Then use `config.adapter = :Reel` when configuring a Webmachine app, e.g:
86
+
87
+ ```ruby
88
+ MyApp = Webmachine::Application.new do |app|
89
+ app.routes do
90
+ add ['*'], MyHome
91
+ end
92
+
93
+ app.configure do |config|
94
+ config.ip = MYAPP_IP
95
+ config.port = MYAPP_PORT
96
+ config.adapter = :Reel
97
+
98
+ # Optional: handler for incoming websockets
99
+ config.adapter_options[:websocket_handler] = proc do |websocket|
100
+ # socket is a Reel::WebSocket
101
+ socket << "hello, world"
102
+ end
103
+ end
104
+ end
105
+
106
+ MyApp.run
107
+ ```
108
+
109
+ See the [Webmachine documentation](http://rubydoc.info/gems/webmachine/frames/file/README.md)
110
+ for further information
111
+
112
+ Ruby API
113
+ --------
64
114
 
65
115
  *NOTE: these examples are for the Reel 0.4.0.pre2 API*
66
116
 
@@ -134,56 +184,6 @@ end
134
184
  MyServer.run
135
185
  ```
136
186
 
137
- Framework Adapters
138
- ------------------
139
-
140
- ### Rack
141
-
142
- A Rack adapter for Reel is available at:
143
-
144
- https://github.com/celluloid/reel-rack
145
-
146
- ### Webmachine
147
-
148
- The most notable library with native Reel support is
149
- [webmachine-ruby](https://github.com/seancribbs/webmachine-ruby),
150
- an advanced HTTP framework for Ruby with a complete state machine for proper
151
- processing of HTTP/1.1 requests. Together with Reel, Webmachine provides
152
- full streaming support for both requests and responses.
153
-
154
- To use Reel with Webmachine, add the following to your Gemfile:
155
-
156
- ```ruby
157
- gem 'webmachine', git: 'git://github.com/seancribbs/webmachine-ruby.git'
158
- ```
159
-
160
- Then use `config.adapter = :Reel` when configuring a Webmachine app, e.g:
161
-
162
- ```ruby
163
- MyApp = Webmachine::Application.new do |app|
164
- app.routes do
165
- add ['*'], MyHome
166
- end
167
-
168
- app.configure do |config|
169
- config.ip = MYAPP_IP
170
- config.port = MYAPP_PORT
171
- config.adapter = :Reel
172
-
173
- # Optional: handler for incoming websockets
174
- config.adapter_options[:websocket_handler] = proc do |websocket|
175
- # socket is a Reel::WebSocket
176
- socket << "hello, world"
177
- end
178
- end
179
- end
180
-
181
- MyApp.run
182
- ```
183
-
184
- See the [Webmachine documentation](http://rubydoc.info/gems/webmachine/frames/file/README.md)
185
- for further information
186
-
187
187
  Contributing
188
188
  ------------
189
189
 
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env ruby
2
+ # Run with: bundle exec examples/server_sent_events.rb
3
+ # Test with: curl -vNH 'Accept: text/event-stream' -H 'Last-Event-ID: 1' -H 'Cache-Control: no-cache' http://localhost:63310
4
+
5
+ require 'bundler/setup'
6
+ require 'time'
7
+ require 'reel'
8
+
9
+ class ServerSentEvents < Reel::Server
10
+ include Celluloid::Logger
11
+
12
+ def initialize(ip = '127.0.0.1', port = 63310)
13
+ @connections = []
14
+ @history = []
15
+ @lastMessageId = 0
16
+ async.ping
17
+ async.ring
18
+ super(ip, port, &method(:on_connection))
19
+ end
20
+
21
+ def broadcast(event, data)
22
+ #only keep the last 5000 Events
23
+ if @history.size >= 6000
24
+ @history.slice!(0, @history.size - 1000)
25
+ end
26
+ @lastMessageId += 1
27
+ @history << {id: @lastMessageId, event: event, data: data}
28
+ info "Sending Event: #{event} Data: #{data} to #{@connections.count} Clients"
29
+ @connections.each do |socket|
30
+ async.send_sse(socket, data, event, @lastMessageId)
31
+ end
32
+ true
33
+ end
34
+
35
+ private
36
+ #event and id are optional
37
+ def send_sse(socket, data, event = nil, id = nil)
38
+ begin
39
+ socket.id id if id
40
+ socket.event event if event
41
+ socket.data data
42
+ rescue IOError, Errno::ECONNRESET, Errno::EPIPE
43
+ @connections.delete(socket)
44
+ end
45
+ end
46
+
47
+ def send_ping
48
+ @connections.each do |socket|
49
+ begin
50
+ #Lines that start with a Colon are Comments and will be ignored
51
+ socket << ":\n"
52
+ rescue IOError, Errno::ECONNRESET, Errno::EPIPE
53
+ @connections.delete(socket)
54
+ end
55
+ end
56
+ end
57
+
58
+ def ping
59
+ #apache 2.2 closes connections after five seconds when nothing is send
60
+ every(5) do
61
+ send_ping
62
+ end
63
+ end
64
+
65
+ def ring
66
+ every(2) do
67
+ broadcast(:time, Time.now.httpdate)
68
+ end
69
+ end
70
+
71
+ def handle_request(request)
72
+ query = {}
73
+ (request.query_string || '').split('&').each do |kv|
74
+ key, value = kv.split('=')
75
+ if key && value
76
+ key, value = CGI.unescape(key), CGI.unescape(value)
77
+ query[key] = value
78
+ end
79
+ end
80
+ body = Reel::EventStream.new do |socket|
81
+ @connections << socket
82
+ socket.retry 5000
83
+ #after a Connection reset resend newer Messages to the Client
84
+ if @history.count > 0 && id = (request.headers['Last-Event-ID'] || query['lastEventId'])
85
+ begin
86
+ id = Integer(id)
87
+ if history = @history.select {|h| h[:id] >= id}.map {|a| "id: %d\nevent: %s\ndata: %s" % [a[:id], a[:event], a[:data]]}.join("\n\n")
88
+ socket << "%s\n\n" % [history]
89
+ else
90
+ socket << "id\n\n"
91
+ end
92
+ rescue ArgumentError, IOError, Errno::ECONNRESET, Errno::EPIPE
93
+ @connections.delete(socket)
94
+ request.close
95
+ end
96
+ else
97
+ socket << "id\n\n"
98
+ end
99
+ end
100
+ #X-Accel-Buffering is nginx(?) specific. Setting this to "no" will allow unbuffered responses suitable for Comet and HTTP streaming applications
101
+ request.respond Reel::StreamResponse.new(:ok, {
102
+ 'Content-Type' => 'text/event-stream; charset=utf-8',
103
+ 'Cache-Control' => 'no-cache',
104
+ 'X-Accel-Buffering' => 'no',
105
+ 'Access-Control-Allow-Origin' => '*'}, body)
106
+ end
107
+
108
+ def on_connection(connection)
109
+ connection.each_request do |request|
110
+ handle_request(request)
111
+ end
112
+ end
113
+ end
114
+
115
+ ServerSentEvents.run
data/lib/reel/response.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  module Reel
2
2
  class Response
3
+ include HTTP::Header
3
4
 
4
5
  CONTENT_LENGTH = 'Content-Length'.freeze
5
6
  TRANSFER_ENCODING = 'Transfer-Encoding'.freeze
6
7
  CHUNKED = 'chunked'.freeze
7
8
 
8
- # Use status code tables from the Http gem
9
- STATUS_CODES = Http::Response::STATUS_CODES
10
- SYMBOL_TO_STATUS_CODE = Http::Response::SYMBOL_TO_STATUS_CODE
9
+ # Use status code tables from the HTTP gem
10
+ STATUS_CODES = HTTP::Response::STATUS_CODES
11
+ SYMBOL_TO_STATUS_CODE = HTTP::Response::SYMBOL_TO_STATUS_CODE
11
12
 
12
13
  attr_reader :status # Status has a special setter to coerce symbol names
13
14
  attr_accessor :reason # Reason can be set explicitly if desired
@@ -62,7 +63,7 @@ module Reel
62
63
 
63
64
  def canonicalize_headers(headers)
64
65
  headers.inject({}) do |headers, (header, value)|
65
- headers.merge Http.canonicalize_header(header) => value.to_s
66
+ headers.merge canonicalize_header(header) => value.to_s
66
67
  end.freeze
67
68
  end
68
69
  private :canonicalize_headers
data/lib/reel/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Reel
2
- VERSION = "0.4.0.pre5"
2
+ VERSION = "0.4.0.pre6"
3
3
  CODENAME = "Garbo"
4
4
  end
@@ -15,4 +15,17 @@ describe Reel::Response do
15
15
  response[(response.length - fixture.length)..-1].should eq fixture
16
16
  end
17
17
  end
18
+
19
+ it "canonicalizes response headers" do
20
+ with_socket_pair do |client, connection|
21
+ client << ExampleRequest.new.to_s
22
+ request = connection.request
23
+
24
+ connection.respond Reel::Response.new(:ok, {"content-type" => "application/json"}, "['mmmkay']")
25
+ connection.close
26
+
27
+ response = client.read(4096)
28
+ expect(response["Content-Type: application/json"]).to_not be_nil
29
+ end
30
+ end
18
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0.pre5
4
+ version: 0.4.0.pre6
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-08 00:00:00.000000000 Z
11
+ date: 2013-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid
@@ -131,6 +131,7 @@ files:
131
131
  - examples/chunked.rb
132
132
  - examples/hello_world.rb
133
133
  - examples/roundtrip.rb
134
+ - examples/server_sent_events.rb
134
135
  - examples/ssl_hello_world.rb
135
136
  - examples/websockets.rb
136
137
  - lib/reel.rb
@@ -198,3 +199,4 @@ test_files:
198
199
  - spec/reel/ssl_server_spec.rb
199
200
  - spec/reel/websocket_spec.rb
200
201
  - spec/spec_helper.rb
202
+ has_rdoc: