Skip to content

Commit

Permalink
Fix WebSockets close handshake
Browse files Browse the repository at this point in the history
  • Loading branch information
samoconnor committed Feb 14, 2018
1 parent 0022e6b commit 2cea2f7
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 8 deletions.
10 changes: 6 additions & 4 deletions src/Streams.jl
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,16 @@ function IOExtras.closewrite(http::Stream{Response})
end

function IOExtras.closewrite(http::Stream{Request})
@require iswritable(http)

closebody(http)
closewrite(http.stream)
if iswritable(http)
closebody(http)
closewrite(http.stream)
end

if hasheader(http.message, "Connection", "close") ||
http.message.version < v"1.1" &&
!hasheader(http.message, "Connection", "keep-alive")
!hasheader(http.message, "Connection", "keep-alive") ||
!hasheader(http.message, "Connection", "upgrade")

@debug 1 "\"Connection: close\": $(http.stream)"
close(http.stream)
Expand Down
12 changes: 8 additions & 4 deletions src/WebSockets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ end
is_websocket_upgrade(r::HTTP.Message) =
(r isa HTTP.Request && r.method == "GET" || r.status == 101) &&
HTTP.hasheader(r, "Connection", "upgrade") &&
HTTP.hasheader(r, "Upgrade", "webscoket")
HTTP.hasheader(r, "Upgrade", "websocket")


function check_upgrade(http)
Expand Down Expand Up @@ -111,7 +111,9 @@ function open(f::Function, url; binary=false, verbose=false, kw...)
end

io = ConnectionPool.getrawstream(http)
f(WebSocket(io; binary=binary))
ws = WebSocket(io; binary=binary)
f(ws)
close(ws)

This comment has been minimized.

Copy link
@samoconnor

samoconnor Feb 14, 2018

Author Contributor

doing close here relieves the user from the need to do close in their do function

end
end

Expand Down Expand Up @@ -143,7 +145,9 @@ function upgrade(f::Function, http::HTTP.Stream; binary=false)
startwrite(http)

io = ConnectionPool.getrawstream(http)
f(WebSocket(io; binary=binary, server=true))
ws = WebSocket(io; binary=binary, server=true)
f(ws)
close(ws)
end


Expand Down Expand Up @@ -221,7 +225,7 @@ function Base.close(ws::WebSocket)
if !ws.txclosed
closewrite(ws)
end
while !ws.rxclosed
while !eof(ws) # FIXME Timeout in case other end does not send CLOSE?
readframe(ws)
end
close(ws.io)
Expand Down
24 changes: 24 additions & 0 deletions test/WebSockets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,28 @@ for s in ["ws", "wss"]

end

p = UInt16(8000)
@async HTTP.listen("127.0.0.1",p) do http
if HTTP.WebSockets.is_websocket_upgrade(http.message)
HTTP.WebSockets.upgrade(http) do ws
while !eof(ws)
data = readavailable(ws)
write(ws,data)
end
end
end
end

sleep(2)

info("Testing local server...")
HTTP.WebSockets.open("ws://127.0.0.1:$(p)") do ws
write(ws, "Foo")
@test String(readavailable(ws)) == "Foo"

write(ws, "Bar")
@test String(readavailable(ws)) == "Bar"
end


end # testset

0 comments on commit 2cea2f7

Please sign in to comment.