# Websocket proxying module questions

**URL:** <https://www.ruby-forum.com/t/websocket-proxying-module-questions/199360>\
**Category:** NGINX\
**Created:** [November 19, 2010, 1:33pm UTC](https://www.ruby-forum.com/t/websocket-proxying-module-questions/199360 "2010-11-19T13:33:37Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![okkezSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/85f322/32.png) [@okkezSS](https://www.ruby-forum.com/u/okkezSS)\
**Post date:** [November 19, 2010, 1:33pm UTC](https://www.ruby-forum.com/t/websocket-proxying-module-questions/199360/1 "2010-11-19T13:33:37Z")

</div>

Hello,

I’m wondering if it’s possible to make a module for proxying websockets  
for nginx.

I read [Emiller’s Guide to Nginx Module Development – Evan Miller](http://www.evanmiller.org/nginx-modules-guide.html#proxying) …

> From what I understand nginx normally works like this:

1. keep connection with client
2. connect to proxy and make request
3. do something else
4. get response from proxy and reply to client

Now, a websocket connection will drop when it issues the upgrade command  
to nginx. A couple of questions

1. Does nginx need a persistent connection per client with the proxy to  
do websocket proxying?
2. For proper websocket proxying would the proxy rather have to be a  
gateway or tunneling proxy in nature?
3. If 2 holds, does that even fit into the nginx architecture?

I know there is handshake issues with draft 76, but assuming I ignore  
them, is it possible to implement a websocket proxy to nginx?  
If so, can anyone give me some hints on how to do that? If not what  
would be the alternative? If I were to build a websocket module  
for nginx, that does all the handshaking inside nginx, how would the  
backend notify nginx that there’s new data available?

Regards,  
Reza

Posted at Nginx Forum:

> **[websocket proxying module questions](https://forum.nginx.org/read.php?2,151908,151908#msg-151908)**
>
> Hello, I'm wondering if it's possible to make a module for proxying websockets for nginx. I read http://www.evanmiller.org/nginx-modules-guide.html#proxying ... From what I understand nginx normally works like this: 1. keep connection with client

---

<div class="post-metadata">

**Author:** ![rezajelveh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/45deac/32.png) [@rezajelveh](https://www.ruby-forum.com/u/rezajelveh)\
**Post date:** [November 20, 2010, 5:14pm UTC](https://www.ruby-forum.com/t/websocket-proxying-module-questions/199360/2 "2010-11-20T17:14:56Z")

</div>

ok another update.~m~16~m~5890598851256073…~m~16~m~~j~{“buffer”:[]}.  
doesn’t belong in the handshake response. it’s actually websocket  
framing.

the [socket.io](http://socket.io) server will respond not only with the handshake response  
but immediately throw a session id back at nginx. since nginx doesn’t  
know anything about websocket framing, it will think that it belongs to  
the challenge response and mess it up. any suggestions on how to switch  
from http to websocket framing?

Posted at Nginx Forum:

> **[Re: websocket proxying module questions](https://forum.nginx.org/read.php?2,151908,152070#msg-152070)**
>
> Hello, I'm wondering if it's possible to make a module for proxying websockets for nginx. I read http://www.evanmiller.org/nginx-modules-guide.html#proxying ... From what I understand nginx normally works like this: 1. keep connection with client

---

<div class="post-metadata">

**Author:** ![rezajelveh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/45deac/32.png) [@rezajelveh](https://www.ruby-forum.com/u/rezajelveh)\
**Post date:** [November 20, 2010, 4:29pm UTC](https://www.ruby-forum.com/t/websocket-proxying-module-questions/199360/3 "2010-11-20T16:29:08Z")

</div>

ok little update. first problem is obviously the missing 8 byte of the  
handshake.

what happens is the following:

clients sends handshake

GET /socket.io/websocket HTTP/1.1  
Upgrade: WebSocket  
Connection: Upgrade  
Host: websocket.local  
Origin: [http://websocket.local](http://websocket.local)  
Sec-WebSocket-Key1: '6F24 \>168D1m/2T7b  
Sec-WebSocket-Key2: 3 84w6 5 u{U45 7 17  
Cookie: socketio=websocket

12345678

the server would forward the following:  
GET /socket.io/websocket HTTP/1.0  
Host: websocket.local  
X-Real-IP: 127.0.0.1  
X-Forwarded-For: 127.0.0.1  
Connection: close  
Upgrade: WebSocket  
Origin: [http://websocket.local](http://websocket.local)  
Sec-WebSocket-Key1: '6F24 \>168D1m/2T7b  
Sec-WebSocket-Key2: 3 84w6 5 u{U45 7 17  
Cookie: socketio=websocket

note the missing websocket key3.

This is easily worked around(fixed) by adding

```
        if (ngx_strcasestrn(h->key.data, "upgrade", 7 - 1) &&
            ngx_strcasestrn(h->value.data, "websocket", 9 - 1)) {
                r->headers_in.content_length_n = 8;
                ngx_log_debug2(NGX_LOG_DEBUG_HTTP,

```

r-\>connection-\>log, 0,  
“Upgrade header found”);  
}

to ngx\_http\_request.c:ngx\_http\_process\_request\_headers  
the next thing i don’t get, node will response with a handshake:  
HTTP/1.1 101 WebSocket Protocol Handshake  
Upgrade: WebSocket  
Connection: Upgrade  
Sec-WebSocket-Origin: [http://websocket.local](http://websocket.local)  
Sec-WebSocket-Location: ws://websocket.local/socket.io/websocket

n.E…Q.}…/.(s.~m~16~m~5890598851256073…~m~16~m~~j~{“buffer”:[]}.

nginx will return the following:  
HTTP/1.1 101 WebSocket Protocol Handshake  
Server: nginx/0.7.67  
Date: Fri, 19 Nov 2010 13:41:48 GMT  
Transfer-Encoding: chunked  
Connection: keep-alive  
Upgrade: WebSocket  
Sec-WebSocket-Origin: [http://websocket.local](http://websocket.local)  
Sec-WebSocket-Location: ws://websocket.local/socket.io/websocket

44  
n.E…Q.}…/.(s.~m~16~m~5890598851256073…~m~16~m~~j~{“buffer”:[]}.

Question:

1. where do the 44 come in? how do they fit in?
2. can i store the state of the connection as being a websocket now. so  
that it doesn’t rewrite the connection header?

Regards,  
Reza

Posted at Nginx Forum:

> **[Re: websocket proxying module questions](https://forum.nginx.org/read.php?2,151908,152064#msg-152064)**
>
> Hello, I'm wondering if it's possible to make a module for proxying websockets for nginx. I read http://www.evanmiller.org/nginx-modules-guide.html#proxying ... From what I understand nginx normally works like this: 1. keep connection with client

---

<div class="post-metadata">

**Author:** ![rezajelveh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/45deac/32.png) [@rezajelveh](https://www.ruby-forum.com/u/rezajelveh)\
**Post date:** [November 21, 2010, 4:17pm UTC](https://www.ruby-forum.com/t/websocket-proxying-module-questions/199360/4 "2010-11-21T16:17:53Z")

</div>

another quick update, adding a content-length: 16 header in my [socket.io](http://socket.io)  
instance(note that’s not part of the websocket draft). nginx will  
forward the handshake response properly. and chrome and safari will  
establish a websocket connection which works only server → client. i  
explained it a bit more detailed in irc

14:02 [timebomb] no  
14:02 [timebomb] server to client  
14:02 [timebomb] there’s 2 problems  
14:03 [timebomb] no.1 when you make a high timeout proxy connection,  
nginx will assume the websocket frames are just the rest of the previous  
html response. so it will keep forwarding the websocket requests from  
the server back to the client  
14:03 [timebomb] however the frontend side isn’t able to send data  
back over that same connection  
14:04 [timebomb] no.2 once the websocket connection is established  
the framing is something like 00 data ff  
14:04 [timebomb] it will look like this:  
14:04 [timebomb] 127.0.0.1 - - [21/Nov/2010:13:28:27 +0100] “GET  
/socket.io/websocket HTTP/1.1” 101 589 “-” “-”  
14:04 [timebomb] 127.0.0.1 - - [21/Nov/2010:13:28:27 +0100]  
“\x00~m~4~m~~h~1#” 400 173 “-” “-”  
14:04 [timebomb] nginx will return a 400 bad request answer  
14:05 [timebomb] the best solution i can think of right now is to  
wrap that request in a html get at frontend side and then unwrap it  
internally at the proxy side  
14:07 [timebomb] also i needed to add a content-length: 16 header to  
my node.js handshake response and a content-length: 8Â internally in  
nginx for the handshake request otherwise nginx would drop the websocket  
key 3  
14:08 [Evet] things getting more complicated  
14:09 \*\*\* netzsportler [~removed\_email\_address@domain.invalid] has quit  
[Ping timeout: 245 seconds]  
14:09 [timebomb] about that wrap and unwrapping … it would be  
easily avoided if there was a way to avoid the html filter chain once  
the connection is established  
14:09 [timebomb] i just don’t know how and if that’s possible

Posted at Nginx Forum:

> **[Re: websocket proxying module questions](https://forum.nginx.org/read.php?2,151908,152227#msg-152227)**
>
> Hello, I'm wondering if it's possible to make a module for proxying websockets for nginx. I read http://www.evanmiller.org/nginx-modules-guide.html#proxying ... From what I understand nginx normally works like this: 1. keep connection with client
