Как использовать Apache в качестве обратного прокси для WebSockets с Undertow в качестве сервера

У меня включены WebSockets с использованием сервера Undertow. Когда я запускаю сервер Undertow напрямую, WebSockets работают хорошо. Я обслуживаю свои страницы, используя HTTPS, и я тестирую конечную точку, используя «wss:» в javascript: это работает.

Но теперь я пытаюсь использовать Apache в качестве обратного прокси-сервера и хочу, чтобы он позволял соединениям WebSocket достигать сервера Undertow. Это мой текущий виртуальный хост:

<VirtualHost *:80 *:443>
    ServerName test.example.org

    SSLEngine on 
    SSLCertificateFile /etc/letsencrypt/live/example.org/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.org/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/example.org/chain.pem

    ProxyPass / http://test.example.org:44444/
    ProxyPassReverse / http://test.example.org:44444/

</VirtualHost>

Здесь Undertow запускается как HTTP-сервер (не HTTPS) на порту 44444, а безопасность SSL обеспечивается Apache.

Все HTML-страницы работают хорошо, но когда я пытаюсь запустить соединение WebSocket, я получаю эту ошибку (Chrome):

WebSocket connection to 'wss://test.example.org/websockets/echo' failed: Error during WebSocket handshake: 'Upgrade' header is missing

И, когда я смотрю на вкладку «Сеть», я вижу, что действительно отсутствуют два заголовка в ответе от сервера при вызове «wss://»: «Connection: Upgrade» и «Upgrade: WebSocket». Эти заголовки присутствуют, когда я подключаюсь к Undertow напрямую, без Apache.

Заголовки «Sec-WebSocket-Accept» и «Sec-WebSocket-Location» есть, но, я думаю, это вторая проблема, «Sec-WebSocket-Location» — это «ws://test.example.org/websockets/echo», а не «wss://test.example.org/websockets/echo', поскольку Undertow работает по протоколу HTTP, а не HTTPS.

Наконец, в документации mod_proxy_wstunnel говорится: "Соединение автоматически обновлено до подключения через веб-сокет". Что это значит? Apache самостоятельно обновляет HTTP-соединение до соединения WebSocket? Это не то, что я хочу! Я хочу обрабатывать первоначальный HTTP-запрос и процессы обновления самостоятельно, используя Undertow. Я использую информацию из начального HTTP-соединения, чтобы проверить, может ли пользователь подключиться к запрошенной конечной точке, и, если да, я программно вызываю WebSocketProtocolHandshakeHandler#handleRequest(exchange) Undertow для обновления до соединения WebSocket. Я просто хочу, чтобы Apache пропускал все, не вмешиваясь.

Любая помощь в том, как запускать WebSockets с помощью Undertow за обратным прокси-сервером Apache?


person electrotype    schedule 18.06.2016    source источник


Ответы (1)


Я устал и решил попробовать Nginx.

В течение 3 часов я не только заработал WebSockets, но все мои сайты на сервере были перенесены на него. Супер легко.

Волшебные строки для WebSockets в nginx.conf:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Я понимаю, что «Upgrade» — это специальный заголовок «hop-by-hop», который должен быть явно настроен для сохранения.

Я надеюсь, что для Apache есть подобное решение, но документации по этому поводу так мало!

person electrotype    schedule 18.06.2016