I am deploying a Golang(go1.16.7) backend on a Namecheap vps, using Apache(httpd...Server version: Apache/2.4.37 (centos 8))
Eveything works except the websocket connection.
The request is made to:
wss://editor.xyzw.com/crownies/ws/upload/file?email=gbenroscience@gmail.com
When I try to access the websocket connection, it gives:
the client is not using the websocket protocol:'upgrade' token not found in 'Connection' header
(I printed this error out in the golang code in production)
The websocket works locally in development, so I know the Golang code works well. I am certain that the issue is somewhere with my vhost configuration in Apache.
Here is my vhost file:
<VirtualHost *:443>
ServerName editor.xyzw.com
ServerAlias editor.xyzw.com www.editor.xyzw.com http://www.editor.xyzw.com
UseCanonicalName Off
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" combined
CustomLog /var/log/httpd/editor_access.log combined
ErrorLog /var/log/httpd/editor_error.log
DocumentRoot /path/to/my/document/root
SSLEngine on
SSLCertificateFile /opt/ssl/cert.crt
SSLCertificateKeyFile /opt/ssl/cert.key
SSLCACertificateFile /opt/ssl/cert.ca-bundle
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule ^/ws(.*) ws://localhost:8080/crownies/ws/$1 [P,L]
ProxyRequests off
<Location />
ProxyPass http://localhost:8080/
ProxyPassReverse http://localhost:8080/
</Location>
</VirtualHost>
The request headers from Google Chrome:
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: Upgrade
Cookie: user=blah-blah-blah
Host: editor.xyzw.com
Origin: https://editor.xyzw.com
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: blah-blah-blah==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36
Please what could be the issue with my vhost?
I think Location takes precedence over rewrites, so when the paths overlap, you have to stick to rewrites. Don't forget to set proper timeouts for the backend too, for example (adjust to your needs):
# Worker Options
<Proxy http://localhost:8080>
ProxySet keepalive=On smax=1 connectiontimeout=10 retry=10 timeout=30 ttl=15
</Proxy>
<Proxy ws://localhost:8080>
ProxySet keepalive=On smax=1 connectiontimeout=10 retry=10 timeout=900 ttl=15
</Proxy>
# Rewrites
RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /ws/(.*) ws://localhost:8080/crownies/ws/$1 [P,L]
RewriteRule /(.*) http://localhost:8080/$1 [P,L]
ProxyPassReverse / http://localhost:8080/