A simpler repro is: # in one terminal # a cheap backend server $ while ((1)); do (echo -ne "HTTP/1.1 401 Unauthorized\r\nContent-Length: 0\r\n\r\n" ; cat ) | nc -l 9000; done # in another terminal, launch official httpd docker image $ docker run -p 8080:8080 httpd:2.4 bash -c 'echo -ne "Listen 8080\nLogLevel trace8\nLoadModule proxy_module modules/mod_proxy.so\nLoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so\n<VirtualHost *:8080>\n ProxyPass /ws/gateway/ ws://172.17.0.1:9000/\n\n</VirtualHost>\n" >> /usr/local/apache2/conf/httpd.conf; httpd-foreground' # works $ curl 'http://localhost:8080/' # BUG? prints both http requests to the nc server, instead of serving files for the first request $ curl -v -H 'Connection: Upgrade' -H 'Upgrade: websocket' 'http://localhost:8080/ws/gateway/notification/notify' --next 'http://localhost:8080/' ; echo Jon On Wed, Nov 25, 2020 at 2:21 PM Jon Harper <jon.harper87@xxxxxxxxx> wrote: > > Hi list, > > I'm seeking help for the following problem. I have an httpd doing two things: > - serving files > - reverse proxying websockets to a backend server. > In the general case, things work fine. > > However, when the websocket server refuses the websocket handshake > with httpd by replying 401 Unauthorized, if the client sends another > request for files (**not websocket**) in the same TCP connection (http > keepalive), then the second request is incorrectly reverse proxied to > the websocket server. > > Is there a solution to this? > > The problem is visible with this very simple following configuration: > > Listen 8080 > LoadModule proxy_module modules/mod_proxy.so > LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so > <VirtualHost *:8080> > # an explicit worker > ProxyPass /ws/gateway/ ws://BACKEND:9000/ > </VirtualHost> > > If you run this and check with curl: > # first getting a file works > $ curl 'http://localhost:8080/' > <html><body><h1>It works!</h1></body></html> > > # but here, connecting a websocket that is refused by the server and > then getting the file > # in the same tcp connection is incorrectly routed to the websocket > server, which answers > # with a 404 > $ curl -v -H 'Connection: Upgrade' -H 'Upgrade: websocket' > 'http://localhost:8080/ws/gateway/notification/notify' --next > 'http://localhost:8080/' ; echo > {"timestamp":"2020-11-25T11:43:28.097+0000","path":"/","status":404,"error":"Not > Found","message":null,"requestId":"dacfa51f-33"} > > > Note that using the following configuration also show the problem: > LoadModule proxy_module modules/mod_proxy.so > LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so > LoadModule rewrite_module modules/mod_rewrite.so > <VirtualHost *:8080> > # same problem with reverse proxying with the default worker > RewriteEngine On > RewriteRule /ws/gateway/(.*) ws://BACKEND:9000/$1 [P] > </VirtualHost> > > > If you want to reproduce locally, please feel free to use the > following docker images: > # my backend, a spring-boot gateway. > # use this or any other websocket server that refuses the websocket handshake > # but keeps the tcp connection open. > $ docker run -p 9000:9000 gridsuite/gateway > > # using the official httpd image with the configuration above with trace8 logs > # 172.17.0.1 is the default ip of your computer on the docker network > $ docker run -p 8080:8080 httpd:2.4 bash -c 'echo -ne "Listen > 8080\nLogLevel trace8\nLoadModule proxy_module > modules/mod_proxy.so\nLoadModule proxy_wstunnel_module > modules/mod_proxy_wstunnel.so\n<VirtualHost *:8080>\n ProxyPass > /ws/gateway/ ws://172.17.0.1:9000/\n\n</VirtualHost>\n" >> > /usr/local/apache2/conf/httpd.conf; httpd-foreground' > > # run the curl commands to show the problem > $ curl 'http://localhost:8080/' > $ curl -v -H 'Connection: Upgrade' -H 'Upgrade: websocket' > 'http://localhost:8080/ws/gateway/notification/notify' --next > 'http://localhost:8080/' ; echo > > > I have tried many things, setting a ttl, turning keepalive Off > globaly, adding disablereuse=On but nothing worked. Thanks in advance, > Jon --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@xxxxxxxxxxxxxxxx For additional commands, e-mail: users-help@xxxxxxxxxxxxxxxx