cramp 0.7 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -56,6 +56,14 @@ module Cramp
56
56
  send_initial_response(status, headers, halt_body)
57
57
  end
58
58
 
59
+ def request
60
+ @request ||= Rack::Request.new(@env)
61
+ end
62
+
63
+ def params
64
+ @params ||= @env['usher.params']
65
+ end
66
+
59
67
  end
60
68
  end
61
69
  end
@@ -5,14 +5,6 @@ module Cramp
5
5
  include PeriodicTimer
6
6
  include KeepConnectionAlive
7
7
 
8
- def request
9
- @request ||= Rack::Request.new(@env)
10
- end
11
-
12
- def params
13
- @params ||= @env['usher.params']
14
- end
15
-
16
8
  def render(body)
17
9
  @body.call(body)
18
10
  end
@@ -0,0 +1,62 @@
1
+ require 'thin'
2
+
3
+ class Thin::Connection
4
+ WEBSOCKET_RECEIVE_CALLBACK = 'websocket.receive_callback'.freeze
5
+
6
+ # Called when data is received from the client.
7
+ def receive_data(data)
8
+ trace { data }
9
+
10
+ case @serving
11
+ when :websocket
12
+ callback = @request.env[WEBSOCKET_RECEIVE_CALLBACK]
13
+ callback.call(data) if callback
14
+ else
15
+ if @request.parse(data)
16
+ if @request.websocket?
17
+ @response.websocket_upgrade_data = @request.websocket_upgrade_data
18
+ @serving = :websocket
19
+ end
20
+
21
+ process
22
+ end
23
+ end
24
+ rescue InvalidRequest => e
25
+ log "!! Invalid request"
26
+ log_error e
27
+ close_connection
28
+ end
29
+ end
30
+
31
+ class Thin::Request
32
+ def websocket?
33
+ @env['HTTP_CONNECTION'] == 'Upgrade' && @env['HTTP_UPGRADE'] == 'WebSocket'
34
+ end
35
+
36
+ # upgrade headers for websocket connections
37
+ def websocket_upgrade_data
38
+ location = "ws://#{@env['HTTP_HOST']}#{@env['REQUEST_PATH']}"
39
+
40
+ upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
41
+ upgrade << "Upgrade: WebSocket\r\n"
42
+ upgrade << "Connection: Upgrade\r\n"
43
+ upgrade << "WebSocket-Origin: #{@env['HTTP_ORIGIN']}\r\n"
44
+ upgrade << "WebSocket-Location: #{location}\r\n\r\n"
45
+
46
+ upgrade
47
+ end
48
+ end
49
+
50
+ class Thin::Response
51
+ # Headers for sending Websocket upgrade
52
+ attr_accessor :websocket_upgrade_data
53
+
54
+ def each
55
+ websocket_upgrade_data ? yield(websocket_upgrade_data) : yield(head)
56
+ if @body.is_a?(String)
57
+ yield @body
58
+ else
59
+ @body.each { |chunk| yield chunk }
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,40 @@
1
+ module Cramp
2
+ module Controller
3
+ class Websocket < Abstract
4
+
5
+ include PeriodicTimer
6
+
7
+ class_inheritable_accessor :on_data_callbacks, :instance_reader => false
8
+ self.on_data_callbacks = []
9
+
10
+ class << self
11
+ def backend=(backend)
12
+ raise "Websocket backend #{backend} is unknown" unless [:thin].include?(backend.to_sym)
13
+ require "cramp/controller/websocket/#{backend}_backend.rb"
14
+ end
15
+
16
+ def on_data(*methods)
17
+ self.on_data_callbacks += methods
18
+ end
19
+ end
20
+
21
+ def process
22
+ @env['websocket.receive_callback'] = method(:_on_data_receive)
23
+ super
24
+ end
25
+
26
+ def render(body)
27
+ @body.call("\x00#{body}\xff")
28
+ end
29
+
30
+ def _on_data_receive(data)
31
+ data = data.slice(/\000([^\377]*)\377/).gsub(/^\x00|\xff$/, '')
32
+
33
+ self.on_data_callbacks.each do |callback|
34
+ EM.next_tick { send(callback, data) }
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -1,10 +1,10 @@
1
1
  require 'cramp'
2
- require 'usher'
3
2
  require 'rack'
4
3
 
5
4
  module Cramp
6
5
  module Controller
7
6
  autoload :Action, "cramp/controller/action"
7
+ autoload :Websocket, "cramp/controller/websocket"
8
8
  autoload :Body, "cramp/controller/body"
9
9
  autoload :PeriodicTimer, "cramp/controller/periodic_timer"
10
10
  autoload :KeepConnectionAlive, "cramp/controller/keep_connection_alive"
data/lib/cramp.rb CHANGED
@@ -8,5 +8,5 @@ require 'active_support/concern'
8
8
  require 'cramp/core_ext'
9
9
 
10
10
  module Cramp
11
- VERSION = '0.7'
11
+ VERSION = '0.8'
12
12
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cramp
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.7"
4
+ version: "0.8"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pratik Naik
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-09 00:00:00 +05:30
12
+ date: 2010-01-10 00:00:00 +05:30
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - ~>
52
52
  - !ruby/object:Gem::Version
53
- version: 1.0.0
53
+ version: 1.1.0
54
54
  version:
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: mysqlplus
@@ -100,6 +100,8 @@ files:
100
100
  - lib/cramp/controller/periodic_timer.rb
101
101
  - lib/cramp/controller/rendering.rb
102
102
  - lib/cramp/controller/test_case.rb
103
+ - lib/cramp/controller/websocket/thin_backend.rb
104
+ - lib/cramp/controller/websocket.rb
103
105
  - lib/cramp/controller.rb
104
106
  - lib/cramp/core_ext.rb
105
107
  - lib/cramp/model/arel_monkey_patches.rb