В моем Apache 2.4 vhost я пытаюсь получить все 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 ошибок.
Вам действительно нужно добавить виртуальный хост для трафика WS, который прослушивает *: 80
Есть одна точка, которая не работает либо с RewriteCond
, либо с ProxyPass
на неправильный VHost-File.
Ваш трафик зашифрован сертификатом, который вы используете. Следовательно, соединение не будет установлено правильно. Ваш удаленный хост не может его прочитать.
На основании документации в wikipedia :
Связь осуществляется через 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
لذلك ، نظرًا لأن قاعدة إعادة الكتابة
وما شابهها لا تحتوي على المخطط المناسب. راجع مرجع التوجيه . من المحتمل أن يعمل هذا فقط إذا كانت طلبات ws: // تشبه طلبات HTTP ، أو إذا كان لديك وحدة تتعامل بشكل خاص مع طلبات ws: //. (لاستخدام RewriteCond
، يمكنك سردها عدة مرات كما تريد ، وهي تنطبق فقط على قاعدة إعادة الكتابة التالية [أو ما شابه ذلك؟])
على سبيل المثال. بالنسبة إلى الوكلاء:
RewriteEngine On
ProxyRequests Off
ProxyPreserveHost On
RewriteCond %{REQUEST_SCHEME} "^ws$"
RewriteRule "^(/?.*)$" ws://otherhost:6969/$1 [P]
К сожалению, я не думаю, что есть простой способ сделать это. Ответ Питера не работает, потому что 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).