Skip to content
This repository has been archived by the owner on Sep 17, 2019. It is now read-only.

Support for HTTP/1.1 Upgrade ala Section 3.2 of the new soon-to-be RFC #48

Closed
wants to merge 6 commits into from
Closed

Conversation

jsipprell
Copy link

The following PR adds support for HTTP/1.1 upgrading ala Section 3.2.

The public interface for this is quite similar to ConfigureServer:

var h2srv *http.Server
var conf *http2.Server
http2.UpgradeServer(h2srv, conf).ListenAndServe()

Internally this is performed by cloning h2serv before calling http2.ConfigureServer() and hooking its handler. When a request is detected which meets the upgrade requirements (Connection, Upgrade and HTTP2-Settings headers), the settings payload is decoded, the HTTP/1.1 portion of the upgrade is finalized, the connection is flushed and then hijacked. Finally, the hijacked connection is passed off to http2's handleConn.

In order to facilitate injection of a hijacked net.Conn into http2's state machine some minor changes to server.go were made:

  1. handleConn() was refactored slightly by adding a new func: newConn() which takes an optional pre-state []Setting slice and an upgrade callback function.
  2. A new member was added to the serverConn struct: a single-use upgrade channel which returns a func() that will be called once all settings frames have been ack'd. This callback is used to mock the original HTTP/1.1 request as a header frame payload on the half-closed stream id 1 (as per the spec). A final call to processHeaderBlockFragment() triggers downstream application request processing as per usual.

NOTE: Because the spec includes the dubious requirement that any request entity bodies must be read in-full before the protocol upgrade can begin, any attempts to transmit a request body are detected and will result in a silent failure to upgrade and a fallback to HTTP/1.1 handling.

This has been tested using Curl 7.42.0-DEV built against nghttp2/0.7.12-DEV as well as nghttp2 itself. Unit tests are provided which require docker & gohttp2/curl (via http2_test.go).

@bradfitz
Copy link
Owner

This repo just moved into the official Go repo.

See https://github.com/bradfitz/http2/blob/master/README for the move details.

File new bugs at: https://github.com/golang/go/issues/new?title=x/net/http2:+

Closing this PR as we're now using Gerrit for code review. Please file a bug or send the review to Gerrit if this is still relevant. Sorry for how long this languished here.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants