• Kenton Varda's avatar
    Redesign server-side WebSocket handling. · 632888d6
    Kenton Varda authored
    Previously HttpService had two virtual methods: request() and openWebSocket(). Since it's legitimate to respond to a WebSocket request with a normal HTTP response, openWebSocket() actually had a default implementation that fell back to request().
    
    In the new design, there is only request(). The HttpService detects a WebSocket request by checking the headers. A convenience method, HttpHeaders::isWebSocket(), is provided for this purpose.
    
    The new approach makes life much easier for services composed of many layers. For example, you might write an HttpService implementation which performs some URL or header rewrite and then calls on to another HttpService. Previously, every such wrapper would have to separately handle regular requests and WebSockets, usually with near-identical code. Of course, you could factor out the common code, but in practice this often turned out pretty clunky. Worse, developers would often just omit the openWebSocket() implementation since implementing only request() seems to work fine -- until you need a WebSocket, and everything is broken. With the new approach, you have to go somewhat out of your way to write a wrapper layer that breaks WebSockets.
    
    I did not apply the same logic to HttpClient because:
    
    1. It's not as easy: HttpClient's methods return results rather than calling a callback on completion, so unifying the methods would have forced request()'s signature to change. Lots of code would need to be updated, and would likely become uglier, as request() would now have to return a `webSocketOrBody` variant type even when the caller isn't asking for a WebSocket.
    2. People don't implement custom HttpClients nearly as often as they implement custom HttpServices.
    632888d6
Name
Last commit
Last update
c++ Loading commit data...
doc Loading commit data...
highlighting Loading commit data...
security-advisories Loading commit data...
.gitignore Loading commit data...
.travis.yml Loading commit data...
CMakeLists.txt Loading commit data...
CONTRIBUTORS Loading commit data...
LICENSE Loading commit data...
README.md Loading commit data...
RELEASE-PROCESS.md Loading commit data...
appveyor.yml Loading commit data...
mega-test-kenton-home.cfg Loading commit data...
mega-test-kenton-work.cfg Loading commit data...
mega-test-quick.cfg Loading commit data...
mega-test.py Loading commit data...
release.sh Loading commit data...
style-guide.md Loading commit data...
super-test.sh Loading commit data...