Skip to content

Commit

Permalink
use :em_client_class in Rainbows!
Browse files Browse the repository at this point in the history
This allows us to avoid modifying the builtin
Rainbows::EventMachine::Client class.

This is intended for Rainbows! with the following commits:
7223b868624d19f3421045c2bc5b075bacd83694
ab175517f8fd22acada6daa46c89edda080fa6a9
(git://bogomips.org/rainbows)
  • Loading branch information
Eric Wong authored and lifo committed Aug 5, 2011
1 parent 1079977 commit 500cb87
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 50 deletions.
44 changes: 44 additions & 0 deletions lib/cramp/websocket/rainbows.rb
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,44 @@
class Cramp::Websocket::Rainbows < Rainbows::EventMachine::Client
include Cramp::WebsocketExtension

def receive_data(data)
case @state
when :websocket
callback = @env[WEBSOCKET_RECEIVE_CALLBACK]
callback.call(data) if callback
else
super
end
end

def on_read(data)
if @state == :headers
@hp.add_parse(data) or return want_more
@state = :body
if 0 == @hp.content_length && !websocket?
app_call NULL_IO # common case
else # nil or len > 0
prepare_request_body
end
elsif @state == :body && websocket? && @hp.body_eof?
@state = :websocket
@input.rewind

handler = @env['HTTP_SEC_WEBSOCKET_KEY1'] &&
@env['HTTP_SEC_WEBSOCKET_KEY2'] ? Protocol76 : Protocol75
write(handler.new(@env, websocket_url, @buf).handshake)
app_call NULL_IO
else
super
end
rescue => e
handle_error(e)
end

def write_response(status, headers, body, alive)
write_headers(status, headers, alive) unless websocket?
write_body_each(body)
ensure
body.close if body.respond_to?(:close)
end
end
57 changes: 7 additions & 50 deletions lib/cramp/websocket/rainbows_backend.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,51 +1,8 @@
require 'rainbows' # :enddoc:

require "rainbows"
class Rainbows::EventMachine::Client class Cramp::Websocket
include Cramp::WebsocketExtension # we use autoload since Rainbows::EventMachine::Client should only be

# loaded in the worker proceses and we want to be preload_app-friendly
def receive_data_with_websocket(data) autoload :Rainbows, "cramp/websocket/rainbows"
case @state
when :websocket
callback = @env[WEBSOCKET_RECEIVE_CALLBACK]
callback.call(data) if callback
else
receive_data_without_websocket(data)
end
end

alias_method_chain :receive_data, :websocket

def on_read_with_websocket(data)
if @state == :headers
@hp.add_parse(data) or return want_more
@state = :body
if 0 == @hp.content_length && !websocket?
app_call NULL_IO # common case
else # nil or len > 0
prepare_request_body
end
elsif @state == :body && websocket? && @hp.body_eof?
@state = :websocket
@input.rewind

handler = @env['HTTP_SEC_WEBSOCKET_KEY1'] && @env['HTTP_SEC_WEBSOCKET_KEY2'] ? Protocol76 : Protocol75
write(handler.new(@env, websocket_url, @buf).handshake)
app_call NULL_IO
else
on_read_without_websocket(data)
end
rescue => e
handle_error(e)
end

alias_method_chain :on_read, :websocket

def write_response_with_websocket(status, headers, body, alive)
write_headers(status, headers, alive) unless websocket?
write_body_each(body)
ensure
body.close if body.respond_to?(:close)
end

alias_method_chain :write_response, :websocket
end end
Rainbows::O[:em_client_class] = "Cramp::Websocket::Rainbows"

0 comments on commit 500cb87

Please sign in to comment.