Add a web socket call concept for connecting.

Similar to HTTP and Call, the WebSocketCall is a representation of a pending HTTP request and subsequent upgrade to speak web sockets. Upon synchronous execution you are handed a WebSocket instance for synchronous writing and also pass in a WebSocketListener for async callbacks due to reading.

The API changes in this commits also generalize WebSocket such that it's agnostic to being a client or server peer.

Closes #1173.

Missing tests:

 * [x] Non-101 response
 * [x] Response with failed web socket upgrade (multiple)
... for example, suppose `writeClose()` blocks for a long time, because the outgoing stream is backed up. That could be blocked for many seconds in an well-behaving application, such as a program that's bandwidth-limited.

That means we unnecessarily delay the call to `listener.onClose()`