On Wed, 2010-06-30 at 14:46 +0200, Aleksandar Lazic wrote: > Dear Juhani, > > On Mit 30.06.2010 15:09, Juhani Åhman wrote: > >Hi everyone > > > >I've recently tried to use HAProxy as a reverse proxy to a WebSocket > >server like Moskovitz in this thread > >(http://www.mail-archive.com/haproxy@formilux.org/msg02754.html), but > >I've run into problems. I can only get websockets proxied in http mode > >when I'm using a browser which speaks revision pre-76 draft websockets > >(eg. Chromium 5.0.375.70). When using a rev. 76 browser (eg. Chromium > >6.0.414.0 or later) the websocket connections seem to always fail. > > > >I think the reason for this is that rev. 76 is not backwards compatible > >with earlier ones as it adds new headers HTTP_SEC_WEBSOCKET_KEY1, > >HTTP_SEC_WEBSOCKET_KEY2, HTTP_SEC_WEBSOCKET_PROTOCOL and maybe some > >others too. Apparently HAProxy doesn't like these new headers unless > >I'm running in tcp mode. I've tested this with Eventlet library which > >understands both pre-76 and 76 revisions. > > > >Is there anyway to get rev. 76 websockets working with HAProxy without > >using tcp mode? > > Please can you try to run haproxy with -p flag similar as in > > http://www.mail-archive.com/haproxy@formilux.org/msg02793.html > > Please can you also send us the output of > > haproxy -vv > > BR > > Aleks >
haproxy -vv output fuzzyb...@stacker:~$ haproxy -vv HA-Proxy version 1.4.8 2010/06/16 Copyright 2000-2010 Willy Tarreau <w...@1wt.eu> Build options : TARGET = linux26 CPU = generic CC = gcc CFLAGS = -O2 -g OPTIONS = USE_LINUX_SPLICE=1 USE_LINUX_TPROXY=1 USE_PCRE=1 Default settings : maxconn = 2000, bufsize = 16384, maxrewrite = 8192, maxpollevents = 200 Encrypted password support via crypt(3): yes Available polling systems : sepoll : pref=400, test result OK epoll : pref=300, test result OK poll : pref=200, test result OK select : pref=150, test result OK Total: 4 (4 usable), will use sepoll. my config global log 127.0.0.1 local0 log 127.0.0.1 local1 notice maxconn 16384 #chroot /usr/share/haproxy user haproxy group haproxy daemon #debug #quiet defaults mode http log global option httplog option dontlognull retries 3 option redispatch #option httpclose option forwardfor maxconn 10000 timeout connect 5s timeout client 60s timeout server 60s frontend all 0.0.0.0:80 timeout client 7d option nolinger acl websocket hdr(Upgrade) -i WebSocket AND hdr(Connection) -i Upgrade use_backend ws if websocket default_backend django #backend nginx # server media localhost:8080 check backend django server django localhost:8081 check backend ws timeout server 7d option nolinger server ws localhost:8081 check Enabling httpclose seems to break websockets with both rev 76 and pre-76. Disabling option nolinger does not have effect to websockets. here's the debug output with -p flag. tough, I don't understand what it was supposed to do. It didn't output anything to anywhere. r...@stacker:/var/run# haproxy -f /etc/haproxy/haproxy.cfg -d -p /var/run/haproxy-private.pid -sf $(</var/run/haproxy-private.pid) bash: /var/run/haproxy-private.pid: No such file or directory Available polling systems : sepoll : pref=400, test result OK epoll : pref=300, test result OK poll : pref=200, test result OK select : pref=150, test result OK Total: 4 (4 usable), will use sepoll. Using sepoll() as the polling mechanism. 00000000:all.accept(0004)=0006 from [127.0.0.1:50520] 00000000:all.clireq[0006:ffff]: GET /35/ HTTP/1.1 00000000:all.clihdr[0006:ffff]: Host: localhost 00000000:all.clihdr[0006:ffff]: Connection: keep-alive 00000000:all.clihdr[0006:ffff]: Referer: http://localhost/ 00000000:all.clihdr[0006:ffff]: Cache-Control: max-age=0 00000000:all.clihdr[0006:ffff]: Accept: application/xml,application/xhtml +xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 00000000:all.clihdr[0006:ffff]: User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.2 (KHTML, like Gecko) Chrome/6.0.452.0 Safari/534.2 00000000:all.clihdr[0006:ffff]: Accept-Encoding: gzip,deflate,sdch 00000000:all.clihdr[0006:ffff]: Accept-Language: en-US,en;q=0.8 00000000:all.clihdr[0006:ffff]: Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 00000000:all.clihdr[0006:ffff]: Cookie: csrftoken=4a6ff9be8c08d063178b5b0f0efde0a7 00000000:django.srvrep[0006:0007]: HTTP/1.1 200 OK 00000000:django.srvhdr[0006:0007]: Vary: Cookie, Accept-Encoding 00000000:django.srvhdr[0006:0007]: Content-Length: 11003 00000000:django.srvhdr[0006:0007]: Content-Type: text/html; charset=utf-8 00000000:django.srvhdr[0006:0007]: Content-Encoding: gzip 00000000:django.srvhdr[0006:0007]: Date: Wed, 30 Jun 2010 13:51:25 GMT 00000000:django.srvhdr[0006:0007]: Connection: keep-alive 00000001:all.accept(0004)=0008 from [127.0.0.1:50522] 00000001:all.clireq[0008:ffff]: GET / HTTP/1.1 00000001:all.clihdr[0008:ffff]: Upgrade: WebSocket 00000001:all.clihdr[0008:ffff]: Connection: Upgrade 00000001:all.clihdr[0008:ffff]: Host: 127.0.0.1 00000001:all.clihdr[0008:ffff]: Origin: http://localhost 00000001:all.clihdr[0008:ffff]: Sec-WebSocket-Key1: V(7823t 6E{)8U8K48^% 00000001:all.clihdr[0008:ffff]: Sec-WebSocket-Key2: 3M5=wYx1y1818t 9j:O82 G 00000002:all.accept(0004)=000a from [127.0.0.1:50535] 00000002:all.clireq[000a:ffff]: GET / HTTP/1.1 00000002:all.clihdr[000a:ffff]: Upgrade: WebSocket 00000002:all.clihdr[000a:ffff]: Connection: Upgrade 00000002:all.clihdr[000a:ffff]: Host: 127.0.0.1 00000002:all.clihdr[000a:ffff]: Origin: http://localhost 00000002:all.clihdr[000a:ffff]: Sec-WebSocket-Key1: 196J>;n 7^1M101o50 00000002:all.clihdr[000a:ffff]: Sec-WebSocket-Key2: 2 7 90M 5B >0 8 E69 2 ^C