Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Move websocket handshake into mongrel2

  • Loading branch information...
commit a1a8eaa69e67409354d0ac984ba396b8afbcd152 1 parent 305665c
@jasom jasom authored
Showing with 37 additions and 10 deletions.
  1. +10 −10 src/connection.c
  2. +25 −0 src/websocket.c
  3. +2 −0  src/websocket.h
View
20 src/connection.c
@@ -322,7 +322,16 @@ int connection_http_to_handler(Connection *conn)
check(IOBuf_read_commit(conn->iob, Request_header_length(conn->req)) != -1, "Finaly commit failed streaming the connection to http handlers.");
if(is_websocket(conn)) {
- content_len=0;
+ bstring wsKey = Request_get(conn->req, &WS_SEC_WS_KEY);
+ bstring response= websocket_challenge(wsKey);
+
+ Response_send_status(conn,response);
+ bdestroy(response);
+
+ conn->handler = handler;
+ bdestroy(conn->req->request_method);
+ conn->req->request_method=bfromcstr("WEBSOCKET");
+ return REQ_SENT;
}
if(content_len == 0) {
@@ -342,15 +351,6 @@ int connection_http_to_handler(Connection *conn)
check_debug(rc == 0, "Failed to deliver to the handler.");
}
- // WebSocket detection
- if(is_websocket(conn)) {
- conn->handler = handler;
- bdestroy(conn->req->request_method);
- //We set this *after* passing the handshake to the handler so that the
- //handshake has the actual request method (hopefully GET) sent to
- //the handler
- conn->req->request_method=bfromcstr("WEBSOCKET");
- }
Log_request(conn, 200, content_len);
return REQ_SENT;
View
25 src/websocket.c
@@ -1,4 +1,5 @@
#include <websocket.h>
+#include <polarssl/sha1.h>
struct tagbstring WS_REQ_METHOD = bsStatic("HYBI");
struct tagbstring WS_CONNECTION = bsStatic("connection");
@@ -9,6 +10,8 @@ struct tagbstring WS_SEC_WS_KEY = bsStatic("sec-websocket-key");
struct tagbstring WS_SEC_WS_VER = bsStatic("sec-websocket-version");
struct tagbstring WS_FLAGS = bsStatic("FLAGS");
+#define WS_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
+
bstring websocket_make_header(unsigned char flags,uint64_t length, int masked,unsigned char key[])
{
static unsigned char buf[14];
@@ -42,3 +45,25 @@ bstring websocket_make_header(unsigned char flags,uint64_t length, int masked,un
}
return blk2bstr(buf,where);
}
+
+bstring websocket_challenge(bstring input)
+{
+ bstring buf=bfromcstralloc(20,"");
+ bstring tmpstring=bstrcpy(input);
+ bstring encodedSha1=NULL;
+
+ bcatcstr(tmpstring, WS_GUID);
+ sha1((unsigned char *)bdata(tmpstring),blength(tmpstring),(unsigned char *)bdata(buf));
+ buf->slen=20;
+ encodedSha1=bBase64Encode(buf);
+
+ bdestroy(tmpstring);
+ bdestroy(buf);
+
+ tmpstring = bformat("HTTP/1.1 101 Switching Protocols\r\n"
+ "Upgrade: websocket\r\n"
+ "Connection: Upgrade\r\n"
+ "Sec-WebSocket-Accept: %s\r\n\r\n",bdata(encodedSha1));
+ bdestroy(encodedSha1);
+ return tmpstring;
+}
View
2  src/websocket.h
@@ -116,6 +116,8 @@ static inline const char * WS_validate_packet(const unsigned char * header,int c
bstring websocket_make_header(unsigned char flags,uint64_t length, int masked,unsigned char key[]);
+bstring websocket_challenge(bstring input);
+
enum Ws_Flags {
WSFLAG_CONN=1,
WSFLAG_UPGRADE=2,
Please sign in to comment.
Something went wrong with that request. Please try again.