title: How to set up an apache proxy for Meteor/SockJS and WebSocket?
body: <p>I have an apache proxy for a meteor app and apache and meteor are on two separate machines. I need it that way as apache has to serve a lot of real websites and it wouldn't be a good idea to install the meteor app on this machine due to its limited resources.</p>
  
  <p>However the WebSocket handshake fails with response code 400 "Can upgrade only to websocket" if I try to connect from the outside via the proxy. Everything works fine when I connect from within the LAN directly to the meteor machine.
  When WebSocket fails SockJS/Meteor falls back to XHR but unfortunately this brings up some bugs in the app in question. So I really need WebSocket to work in most of the cases.</p>
  
  <p>I patched my apache installation with the patch mentioned here: <a href="https://stackoverflow.com/a/16998664">https://stackoverflow.com/a/16998664</a>
  That looked like it went well but nothing changed...</p>
  
  <p>My apache proxy directives currently are as follows:</p>
  
  <pre><code>ProxyRequests Off
  ProxyPreserveHost On
  ModPagespeed Off
  &lt;proxy&gt;
  Order deny,allow
  Allow from all
  &lt;/proxy&gt;
  ProxyPass / http://10.0.2.6:3000/
  ProxyPassReverse / http://10.0.2.6:3000/
  </code></pre>
  
  <p>And I even know what's triggering the problem. The apache proxy messes around with the header. The original request header of the packet in question leaving my machine looks like this:</p>
  
  <pre><code>GET /sockjs/430/minw4r_o/websocket HTTP/1.1
  Upgrade: websocket
  Connection: Upgrade
  Host: example.com
  Origin: http://example.com
  Pragma: no-cache
  Cache-Control: no-cache
  Sec-WebSocket-Key: myKey
  Sec-WebSocket-Version: 13
  Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
  User-Agent: My Agent
  </code></pre>
  
  <p>While the packet gets forwarded from the apache proxy like this:</p>
  
  <pre><code>GET /sockjs/430/minw4r_o/websocket HTTP/1.1
  Host: example.com
  Origin: http://example.com
  Pragma: no-cache
  Cache-Control: no-cache
  Sec-WebSocket-Key: myKey
  Sec-WebSocket-Version: 13
  Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
  User-Agent: My Agent
  X-Forwarded-For: 24.xxx.xxx.xxx
  X-Forwarded-Host: example.com
  X-Forwarded-Server: example.com
  Connection: Keep-Alive
  </code></pre>
  
  <p>So "Upgrade" gets removed and "Connection" altered and so the websocket handshake fails. Now I could try to always set "Upgrade" to "websocket" with a RequestHeader directive. However this doesn't feel right and I guess it would bring up other problems and so I was wondering if there is a real solution to this problem? Or is this something the patch from <a href="https://stackoverflow.com/a/16998664">https://stackoverflow.com/a/16998664</a> should address and something went wrong on my end applying it?</p>
  
  <p>From what I have read switching to nginx could make this setup easier. I will consider this but when possible I'd like to do this with apache as nginx would make other things more complicated and cost me a lot of time.</p>