В моем хосте Apache 2.4 я пытаюсь получить все https://
трафик для передачи на порт 443, но все ws://
движение вперед на ws://*:6969
.
Например:
https://example.com/index
просто пошел бы в https://example.com/index:443
как обычно.
ws://example.com/anypathhere/
будет направлен ws://example.com/anypathhere:6969
Пока что я пробовал закомментированные значения в vhost.
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/ca.crt
SSLCertificateKeyFile /etc/pki/tls/private/ca.key
DocumentRoot /var/www/html/
RewriteOptions Inherit
AccessFileName .htaccess
AllowEncodedSlashes NoDecode
DirectoryIndex disabled
<Directory /var/www/html>
Options +FollowSymlinks
RewriteEngine On
AllowOverride All
Require all granted
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* %{REQUEST_URI}index.php [L]
</Directory>
ServerName localhost.localdomain
#ProxyPreserveHost On
#ProxyRequests Off
#ProxyPassMatch / ws://192.16.4.177:6969/ retry=0
#ProxyPassReverse ws:// ws://192.16.4.177:6969/
#ProxyPass ws:// ws://192.16.4.177:6969/
#RewriteEngine On
#RewriteRule ws:// ws://%{HTTP_HOST}/$1:6969 [NC,R=301,L]
Все это приводит к
Firefox can't establish a connection to the server at ws://192.16.4.177:443
или ошибка 400.
К сожалению, я не думаю, что есть простой способ сделать это. Ответ Питера не работает, потому что Websockets совмещает HTTP (S) как запрос GET с специальные заголовки. Какая бы ни была логика mod_rewrite
использует для обнаружения схемы URL-адресов недостаточно умен, чтобы обнаружить это, поэтому схема всегда отображается как http
или https
.
Теоретически вы можете искать заголовки самостоятельно, используя примерно следующий синтаксис:
RewriteCond %{HTTP:Upgrade} ^websocket$ [nocase]
RewriteRule ^(.*)$ ws://192.16.4.177:6969/$1 [proxy]
Однако, хотя это правило действительно соответствует открывающемуся клиентскому рукопожатию (подтвержденному в моих журналах), это не дает мне работающего перенаправления через Websocket. Я подозреваю что mod_rewrite
на самом деле не понимает, как проксировать соединения Websocket, даже если вы можете получить рукопожатие, чтобы перейти в нужное место.
Это оставляет нам ответ JinnFox. Если вы можете переместить конечную точку Websockets куда-нибудь, кроме /
, это может быть приемлемым решением.
P.S. Тем временем я обнаружил, что NGINX справляется с этим практически без проблем (прокрутите вниз до шага 6, чтобы найти фрагмент кода, который работает как для HTTP, так и для WS).
Вам действительно нужно добавить vhost для трафика ws, который прослушивает *:80
Есть одна точка, которая терпит неудачу либо с RewriteCond
или с ProxyPass
в неправильном VHost-файле. Ваш трафик зашифрован сертификатом, который вы используете. Следовательно, соединение не будет установлено правильно. Ваш удаленный хост не может его прочитать.
На основании документации в википедия:
Связь осуществляется через TCP-порт с номером 80 [..]
Ваш дополнительный VHost-файл должен выглядеть так:
<VirtualHost *:80>
ServerName localhost.localdomain
ProxyPreserveHost On
ProxyRequests Off
ProxyPassReverse / ws://192.16.4.177:6969/
ProxyPass / ws://192.16.4.177:6969/
</VirtualHost>
Как объяснение. Все ваши запросы, проходящие через http: 80, перенаправляются на ws: 6969.
Лучший способ сделать это - сказать клиенту, чтобы он использовал правильный порт ... но если вы хотите использовать прокси или перенаправить, когда они используют неправильный порт:
Я ничего не знаю о ws: //, но считаю, что вам нужно использовать RewriteCond
для этого, поскольку RewriteRule
и аналогичные не содержат схемы для сопоставления. Увидеть директива ссылка. Это, вероятно, будет работать только в том случае, если запросы ws: // выглядят как запросы HTTP или у вас есть модуль, который специально обрабатывает запросы ws: //. (Использовать RewriteCond
, вы можете перечислять его столько раз, сколько хотите, и оно применяется только к следующему RewriteRule [или подобному?])
например. для проксирования:
RewriteEngine On
ProxyRequests Off
ProxyPreserveHost On
RewriteCond %{REQUEST_SCHEME} "^ws$"
RewriteRule "^(/?.*)$" ws://otherhost:6969/$1 [P]