Конфигурация прокси https для socket.io для apache2 - PullRequest
0 голосов
/ 22 февраля 2020

У меня есть рабочая установка socket.io с JavaScript -клиентом и python -сервером. Клиент в основном состоит из одной строки: Ошибка во время рукопожатия WebSocket: Неожиданный код ответа: 404

socket = io.connect('');

Сценарий сервера можно найти по адресу https://github.com/miguelgrinberg/python-socketio/blob/master/examples/server/wsgi/app.py - я запускаю сервер на порту 5000.

Все, что вам, вероятно, нужно знать о клиенте и сервере, - это то, что они отлично работают на моей установке localhost apache и что socket.io запускается с GET-запросов и обновлений до веб-сокета оттуда. Вот как выглядит успешное рукопожатие:

http://localhost:5000/socket.io/?EIO=3&transport=polling&t=N1kLfSx
http://localhost:5000/socket.io/?EIO=3&transport=polling&t=N1kLfTI&sid=70ddae8b36da4f0f8f9a851fa2c0121e
ws://localhost:5000/socket.io/?EIO=3&transport=websocket&sid=70ddae8b36da4f0f8f9a851fa2c0121e

Теперь у нас есть веб-розетка, и остальная часть связи проходит через это.

Я пытаюсь в течение двух дней: чтобы запустить пример на моем веб-сервере - поэтому я ищу рабочую конфигурацию apache https, которая передает запросы на мой сервер на порт 5000.

Я перепробовал десятки вариантов конфигураций, но ни одна из них работает - все они очень похожи на это. Часть, предназначенная для перезаписи URL, предназначена для прокси подключения к веб-сокету после успешного начального рукопожатия.

RewriteEngine On
RewriteCond %{REQUEST_URI}  ^/socket.io            [NC]
RewriteCond %{QUERY_STRING} transport=websocket    [NC]
RewriteRule /(.*)           ws://localhost:5000/$1 [P,L]

ProxyPass        /socket.io/ http://localhost:5000/socket.io/
ProxyPassReverse /socket.io/ http://localhost:5000/socket.io/

Apache перенаправляет первый GET-запрос socket.io на сервер, а сервер отвечает:

    ÿ0{"sid":"2efa0dbbce4c4eef958e70b393639610","upgrades":["websocket"],"pingTimeout":60000,"pingInterval":25000}ÿ42["my_response",{"data":"Connected","count":0}]ÿ40

Затем веб-розетка открывается и закрывается снова (код 404). Затем клиент отправляет запрос POST, который не выполняется (код 400). Затем клиент начинает сначала с шага 1: делает GET-запрос, получает новый идентификатор сеанса ...

(специальные символы ÿXX также появляются в рабочем сообщении localhost - поэтому они, кажется, принадлежат там).

Что я делаю не так?

ОБНОВЛЕНИЕ - приближаемся к решению!

Я пробовал несколько Python и NodeJS реализаций примера сервера socket.io а также несколько клиентских скриптов - все они создали одну и ту же проблему, которая подтвердила мой тезис о том, что проблема Apache.

Я установил Nginx и нашел конфигурацию, которая наконец-то сработала! Это волшебные c строки:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Я сейчас использую отладочный сервер, который печатает все полученные HTTP-запросы, чтобы сравнить Nginx запросы с запросами Apache2 с целью настройки Apache2 передать те же заголовки, что и Nginx.

Последняя проблема, похоже, заключается в переводе строк конфигурации Nginx в Apache2. Звучит проще, чем это ... но это будет ключом к решению.

1 Ответ

0 голосов
/ 01 марта 2020

Наконец-то! После недели исследований я наконец нашел рабочее решение:

Я поместил этот код в раздел моей конфигурации Apache2:

        ProxyRequests off
        ProxyVia on
        RewriteEngine On

        RewriteEngine On
        RewriteCond %{HTTP:Connection} Upgrade [NC]
        RewriteCond %{HTTP:Upgrade} websocket [NC]
        RewriteRule /(.*) ws://127.0.0.1:8080/$1 [P,L]

        ProxyPass               / http://127.0.0.1:5000/
        ProxyPassReverse        / http://127.0.0.1:5000/

Существует миллион конфигураций, и я попробовал их все - это единственный, который работал на меня. Проблема заключалась в том, что Apache2 не переадресовывал заголовки «Upgrade = websocket» и «Connection = upgrade». Данные команды перезаписи заставляют Apache2 добавлять эти заголовки к прокси-соединению.

При исследовании этого я сначала нашел рабочую конфигурацию Nginx, которую я затем преобразовал в Apache2. Так что если у вас есть такая проблема с Nginx, вы можете использовать ее здесь:

        location / {
                proxy_pass http://127.0.0.1:5000/;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;
        }

Этот маленький NodeJS TCP-сервер мне очень помог с отладкой заголовков HTTP: https://riptutorial.com/node-js/example/22405/a-simple-tcp-server

...