Last active
December 15, 2015 16:09
-
-
Save timclassic/5287161 to your computer and use it in GitHub Desktop.
Fix for "Misultin websocket hixie76 implementation doesn't work behind haproxy" (https://github.com/ostinelli/misultin/issues/98). Misultin is EOL'd, so I thought I'd paste my patch here.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/misultin_websocket_draft-hixie-76.erl b/src/misultin_websocket_draft-hixie-76.erl | |
index 6bcd8e1..d691e97 100644 | |
--- a/src/misultin_websocket_draft-hixie-76.erl | |
+++ b/src/misultin_websocket_draft-hixie-76.erl | |
@@ -70,9 +70,19 @@ check_websocket(Headers) -> | |
% ---------------------------------------------------------------------------------------------------------- | |
-spec handshake(Req::#req{}, Headers::http_headers(), {Path::string(), Origin::string(), Host::string()}) -> iolist(). | |
handshake(#req{socket = Sock, socket_mode = SocketMode, ws_force_ssl = WsForceSsl}, Headers, {Path, Origin, Host}) -> | |
- % build data | |
- Key1 = misultin_utility:header_get_value('Sec-WebSocket-Key1', Headers), | |
- Key2 = misultin_utility:header_get_value('Sec-WebSocket-Key2', Headers), | |
+ % prepare handhsake response | |
+ WsMode = case SocketMode of | |
+ ssl -> "wss"; | |
+ http when WsForceSsl =:= true -> "wss"; % behind stunnel or similar, client is using ssl | |
+ http when WsForceSsl =:= false -> "ws" | |
+ end, | |
+ Handshake = ["HTTP/1.1 101 WebSocket Protocol Handshake\r\n", | |
+ "Upgrade: WebSocket\r\n", | |
+ "Connection: Upgrade\r\n", | |
+ "Sec-WebSocket-Origin: ", Origin, "\r\n", | |
+ "Sec-WebSocket-Location: ", WsMode, "://", lists:concat([Host, Path]), "\r\n\r\n"], | |
+ ok = misultin_socket:send(Sock, Handshake, SocketMode), | |
+ | |
% handshake needs body of the request, still need to read it [TODO: default recv timeout hard set, will be exported when WS protocol is final] | |
misultin_socket:setopts(Sock, [{packet, raw}, {active, false}], SocketMode), | |
Body = case misultin_socket:recv(Sock, 8, 30*1000, SocketMode) of | |
@@ -84,13 +94,12 @@ handshake(#req{socket = Sock, socket_mode = SocketMode, ws_force_ssl = WsForceSs | |
?LOG_ERROR("tcp error treating data: ~p", [_Other]), | |
<<>> | |
end, | |
- ?LOG_DEBUG("got content in body of websocket request: ~p", [Body]), | |
- % prepare handhsake response | |
- WsMode = case SocketMode of | |
- ssl -> "wss"; | |
- http when WsForceSsl =:= true -> "wss"; % behind stunnel or similar, client is using ssl | |
- http when WsForceSsl =:= false -> "ws" | |
- end, | |
+ ?LOG_DEBUG("got content in body of websocket request: ~p", [Body]), | |
+ | |
+ % build data | |
+ Key1 = misultin_utility:header_get_value('Sec-WebSocket-Key1', Headers), | |
+ Key2 = misultin_utility:header_get_value('Sec-WebSocket-Key2', Headers), | |
+ | |
% build challenge | |
Ikey1 = [D || D <- Key1, $0 =< D, D =< $9], | |
Ikey2 = [D || D <- Key2, $0 =< D, D =< $9], | |
@@ -100,14 +109,9 @@ handshake(#req{socket = Sock, socket_mode = SocketMode, ws_force_ssl = WsForceSs | |
Part2 = erlang:list_to_integer(Ikey2) div Blank2, | |
Ckey = <<Part1:4/big-unsigned-integer-unit:8, Part2:4/big-unsigned-integer-unit:8, Body/binary>>, | |
Challenge = erlang:md5(Ckey), | |
- % format | |
- ["HTTP/1.1 101 WebSocket Protocol Handshake\r\n", | |
- "Upgrade: WebSocket\r\n", | |
- "Connection: Upgrade\r\n", | |
- "Sec-WebSocket-Origin: ", Origin, "\r\n", | |
- "Sec-WebSocket-Location: ", WsMode, "://", lists:concat([Host, Path]), "\r\n\r\n", | |
- Challenge | |
- ]. | |
+ | |
+ % return challenge | |
+ [Challenge]. | |
% ---------------------------------------------------------------------------------------------------------- | |
% Function: -> websocket_close | {websocket_close, DataToSendBeforeClose::binary() | iolist()} | NewState |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment