Navigation Menu

Skip to content

Commit

Permalink
invoke callback on successfull websocket upgrade & invoke stream on e…
Browse files Browse the repository at this point in the history
…very new message
  • Loading branch information
igrigorik committed Dec 20, 2009
1 parent fba7fd5 commit 76691b0
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 40 deletions.
40 changes: 19 additions & 21 deletions lib/em-http/client.rb
Expand Up @@ -246,10 +246,18 @@ def stream(&blk)
@stream = blk
end

# raw data push from the client (WebSocket)
def push(data)
p "\x00#{data}\xff"
send_data "\x00#{data}\xff"
# raw data push from the client (WebSocket) should
# only be invoked after handshake, otherwise it will
# inject data into the header exchange
#
# frames need to start with 0x00-0x7f byte and end with
# an 0xFF byte. Per spec, we can also set the first
# byte to a value betweent 0x80 and 0xFF, followed by
# a leading length indicator
def send(data)
if @state == :websocket
send_data("\x00#{data}\xff")
end
end

def normalize_body
Expand Down Expand Up @@ -296,7 +304,7 @@ def send_request_header
end
end

# Set the Host header if it hasn't been specified already
# Set the Host header if it hasn't been specified already
head['host'] ||= encode_host

# Set the User-Agent if it hasn't been specified
Expand All @@ -316,7 +324,6 @@ def send_request_body
end

def receive_data(data)
p "got: #{data.inspect}"
@data << data
dispatch
end
Expand Down Expand Up @@ -423,15 +430,14 @@ def parse_response_proxy
end

def parse_response_header
puts 'parsing header'
return false unless parse_header(@response_header)

unless @response_header.http_status and @response_header.http_reason
@state = :invalid
on_error "no HTTP response"
return false
end
p 'wtf'

# correct location header - some servers will incorrectly give a relative URI
if @response_header.location
begin
Expand All @@ -455,6 +461,7 @@ def parse_response_header
if websocket?
if @response_header.status == 101
@state = :websocket
succeed
else
fail "websocket handshake failed"
end
Expand Down Expand Up @@ -579,19 +586,10 @@ def process_body
end

def process_websocket
# if @data =~ /\x00\x00(.*)\xff/
@response << @data
@stream.call(@data)
@response = ''
@data.clear
# end
# if @response_header.status == 101
# push ("test")
# sleep(1)
# succeed(self)
# else
# fail(self)
# end
if not @data.empty?
@stream.call(@data.read.gsub(/^(\x00)|(\xff)$/, ""))
@data.clear
end
end

end
Expand Down
31 changes: 12 additions & 19 deletions test/test_request.rb
Expand Up @@ -521,9 +521,14 @@ def failed
end

context "websocket connection" do
# Spec: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-55
#
# ws.onopen = http.callback
# ws.onmessage = http.stream { |msg| }
#

it "should invoke errback on failed upgrade" do
EventMachine.run {

http = EventMachine::HttpRequest.new('ws://127.0.0.1:8080/').get :timeout => 0

http.callback { failed }
Expand All @@ -536,36 +541,24 @@ def failed

it "should complete websocket handshake" do
EventMachine.run {

MSG = "hello bi-directional data exchange"
http = EventMachine::HttpRequest.new('ws://127.0.0.1:2200/').get :timeout => 1

http.errback { failed }
http.callback {
http.response_header.status.should == 101
http.response_header['CONNECTION'].should match(/Upgrade/)
http.response_header['UPGRADE'].should match(/WebSocket/)

EventMachine.stop

p "connected!"
p http;

http.push("hello world")
p 'sent data?'

# push should only be invoked after handshake is complete
http.send(MSG)
}

num = 0
http.stream {
# p http.response
puts "recieved: #{http.response.inspect}"
sleep (1)
http.push "yo.. #{num}"
num+=1
http.stream { |chunk|
chunk.should == MSG
EventMachine.stop
}

# Needs to delayed as a callback until the handshake is complete
# http.push "data"
}
end
end
Expand Down

0 comments on commit 76691b0

Please sign in to comment.