From 61309896b8d2991c29cdb8980d4fbd81fbdd6520 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 29 Jan 2020 15:37:59 +0700 Subject: [PATCH] allow 0-RTT in HTTP/0.9 client and server --- interop/http09/client.go | 13 ++++++++++--- interop/http09/http_test.go | 4 ++-- interop/http09/server.go | 4 ++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/interop/http09/client.go b/interop/http09/client.go index 69bbced1e..c5a5166e8 100644 --- a/interop/http09/client.go +++ b/interop/http09/client.go @@ -15,6 +15,10 @@ import ( "github.com/lucas-clemente/quic-go" ) +// MethodGet0RTT allows a GET request to be sent using 0-RTT. +// Note that 0-RTT data doesn't provide replay protection. +const MethodGet0RTT = "GET_0RTT" + // RoundTripper performs HTTP/0.9 roundtrips over QUIC. type RoundTripper struct { mutex sync.Mutex @@ -30,7 +34,7 @@ var _ http.RoundTripper = &RoundTripper{} // RoundTrip performs a HTTP/0.9 request. // It only supports GET requests. func (r *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - if req.Method != http.MethodGet { + if req.Method != http.MethodGet && req.Method != MethodGet0RTT { return nil, errors.New("only GET requests supported") } @@ -76,17 +80,20 @@ type client struct { quicConf *quic.Config once sync.Once - sess quic.Session + sess quic.EarlySession dialErr error } func (c *client) RoundTrip(req *http.Request) (*http.Response, error) { c.once.Do(func() { - c.sess, c.dialErr = quic.DialAddr(c.hostname, c.tlsConf, c.quicConf) + c.sess, c.dialErr = quic.DialAddrEarly(c.hostname, c.tlsConf, c.quicConf) }) if c.dialErr != nil { return nil, c.dialErr } + if req.Method != MethodGet0RTT { + <-c.sess.HandshakeComplete().Done() + } return c.doRequest(req) } diff --git a/interop/http09/http_test.go b/interop/http09/http_test.go index d81ec0302..4942135c6 100644 --- a/interop/http09/http_test.go +++ b/interop/http09/http_test.go @@ -36,8 +36,8 @@ var _ = Describe("HTTP 0.9 integration tests", func() { defer close(done) _ = server.ListenAndServe() }() - var ln quic.Listener - Eventually(func() quic.Listener { + var ln quic.EarlyListener + Eventually(func() quic.EarlyListener { server.mutex.Lock() defer server.mutex.Unlock() ln = server.listener diff --git a/interop/http09/server.go b/interop/http09/server.go index 0277ef31e..99e653798 100644 --- a/interop/http09/server.go +++ b/interop/http09/server.go @@ -41,7 +41,7 @@ type Server struct { QuicConfig *quic.Config mutex sync.Mutex - listener quic.Listener + listener quic.EarlyListener } // Close closes the server. @@ -69,7 +69,7 @@ func (s *Server) ListenAndServe() error { tlsConf := s.TLSConfig.Clone() tlsConf.NextProtos = []string{h09alpn} - ln, err := quic.Listen(conn, tlsConf, s.QuicConfig) + ln, err := quic.ListenEarly(conn, tlsConf, s.QuicConfig) if err != nil { return err }