Allow Route Services to be used with Web Sockets
Proposed Change
As a developer I want to attach a route service to my web socket app So that I can rate-limit it using the route service
We currently prevent web socket upgrades on routes that have a route service attached.
The check is implemented here
However, there is no technical reason why route services should not be able to handle web socket requests. I've tested this by commenting out the above check and attaching a route service to a web socket app. The handshake and traffic work just fine through the route service.
So long as the route service behaves correctly as a reverse proxy and forwards the Connection: Upgrade and Upgrade: Websocket headers to the destination app, there is no reason to block it at gorouter. After all, web socket requests are just HTTP requests.
This issue has been brought up by one of our customers who need a route service to rate-limit their app and have been complaining that it didn't work with web socket apps.
Note: The check is very old. It might be outdated. We recently removed the RequestHandler and let Go do all the work for web sockets. My suspicion is that the check was added because RequestHandler didn't play well together with route services.
Acceptance criteria
Scenario: My web socket app needs rate limiting via a route service. Given
cf push my-websocket-app
cf push ratelimiter
cf create-user-provided-service ratelimiter-service -r https://ratelimiter.bosh-lite.com
cf bind-route-service bosh-lite.com ratelimiter-service --hostname my-websocket-app
When I connect to wss://my-websocket-app.bosh-lite.com using a web socket client Then The connection will work through the route service as expected
Related links
Some more details:
- The check was introduced with 1bf9a13a98ef2230760b572186d52acc0fad9bad.
- Broadcom shut down the Pivotal tracker and it seems like #149929938 didn't make it into any of archives :,(
We are planning to remove the check eventually as our customers have use-cases for such scenarios and it doesn't seem like there is a good reason not to allow it.
Some more discussion on Slack.
We agreed that it's probably a good idea to have a feature flag to ensure operators can quickly revert back to the previous behavior should there be unexpected side-effects.
The Gorouter flag "route_services.enable_websockets" is introduced to enable web socket communication via route services and the default value for it is true.
Hi Geoff @geofffranks, could you please close the issue?
Neat! Thanks for implementing this 👍