On Mon, Dec 7, 2015 at 5:21 PM, Jacob Champion <champio...@gmail.com> wrote:
> On 12/07/2015 02:40 PM, William A Rowe Jr wrote: > >> Not "noise" at all... I'm imagining a mod_echo protocol example that >> looks much like your use case... >> >> 1st call to core_upgrade_request in post_read_req hook, after setenvif >> and mod_headers processing... tls is ready, echo (or websocket) would >> not be ready. Those ready indicate via ap_select_protocol hook response. >> > > Just to confirm, the purpose of splitting this up into two separate calls > to the same function is solely to deal with "OPTIONS *", which doesn't > follow the same logical path in httpd? Or is there another reason? > No, it is because the TLS handshake from the Upgrade: TLS handling is used in the auth path, everything from SSLRequireSSL to using the CN of a client certificate for authentication. TLS Upgrade must occur somewhere early in the post_read_request phase of operation. For that matter, so should h2c, I'd imagine, but those phases may already be invoked a second time in mod_http2, someone else could verify or disclaim that. ... normal pre-handler request preparation and auth ... >> >> 2nd call to core_upgrade_request in ap_invoke_handler hook, after all >> of these other preparations but excluding filter configuration (filters >> may >> differ for the new protocol), tls was handled earlier, echo (or websocket) >> are now ready, based on auth results. Those ready again indicate >> via ap_select_protocol hook response. >> >> WDYT? >> > > I have a suspicion that this isn't quite enough, at least not with the > code that's currently there. I really need to write code to confirm, but: > if WebSocket is enabled for the request-target path, but the upgrade > request is malformed, I still want my module to propose a WebSocket upgrade > to core, so that I have the ability to fail said upgrade with a 4xx _if_ > we're chosen as the eventual protocol. (If a different protocol is chosen, > the client lucks out.) > > Put another way, I'm going to propose WebSocket for the paths that the > server admin wants, whether the incoming request is valid/authorized or > not, and I still need some way to interrupt the upgrade if we're chosen and > the client hasn't sent a proper request. Does that makes sense? So how would a second invocation during the ap_invoke_handler cause an interruption in this? Upgrade: TLS would occur in the early processing, Upgrade: WebSocket would occur in the later processing phase, but still prior to invoking a handler for the HTTP/1.1 request. Remember that there is no 'error' for a malformed upgrade request, only a failure to proceed with 101-switching protocols. Right now the core Protocol API will only send an Upgrade: offer on the first request in a chain of keepalive requests. If the user agent asks for OPTIONS * and the WebSocket module declines to offer itself, and the user agent continues with a GET /webapp/... request that the WebSocket module is willing to upgrade, today the core Protocol API will not advertise that to the user agent on this kept-alive request for you. Of course there is a fail-case, and that would be Upgrade Required, but the protocol module needs to set this sometime before handler invocation. Right now you can't do that within core_upgrade_request hooks, because without an Upgrade: request from the client, the core_upgrade_request implementation calls none of the protocol hooks on a kept-alive 2nd or later request, right now. Stupid question, is there an Upgrade: of protocols within HTTP/2? An obvious case would be the websocket connection embedded within the h2c connection, but I expect that is not allowed. TLS upgrade would be nonsense on an h2c connection. But is there a provision for it in spec?