diff --git a/Changelog.md b/Changelog.md index bbaa061b..33eddd7f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,7 +4,7 @@ - Add support for unidirectional streams (for IETF QUIC). - Add a `quic.Config` option for the maximum number of incoming streams. -- Add support for QUIC 42. +- Add support for QUIC 42 and 43. ## v0.7.0 (2018-02-03) diff --git a/h2quic/server.go b/h2quic/server.go index 857211d2..0f3ad6dc 100644 --- a/h2quic/server.go +++ b/h2quic/server.go @@ -154,10 +154,18 @@ func (s *Server) handleRequest(session streamCreator, headerStream quic.Stream, if err != nil { return qerr.Error(qerr.HeadersStreamDataDecompressFailure, "cannot read frame") } - h2headersFrame, ok := h2frame.(*http2.HeadersFrame) - if !ok { + var h2headersFrame *http2.HeadersFrame + switch f := h2frame.(type) { + case *http2.PriorityFrame: + // ignore PRIORITY frames + s.logger.Debugf("Ignoring H2 PRIORITY frame: %#v", f) + return nil + case *http2.HeadersFrame: + h2headersFrame = f + default: return qerr.Error(qerr.InvalidHeadersStreamData, "expected a header frame") } + if !h2headersFrame.HeadersEnded() { return errors.New("http2 header continuation not implemented") } diff --git a/h2quic/server_test.go b/h2quic/server_test.go index 5217a725..28597594 100644 --- a/h2quic/server_test.go +++ b/h2quic/server_test.go @@ -259,6 +259,24 @@ var _ = Describe("H2 server", func() { Expect(dataStream.reset).To(BeFalse()) }) + It("ignores PRIORITY frames", func() { + handlerCalled := make(chan struct{}) + s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + close(handlerCalled) + }) + buf := &bytes.Buffer{} + framer := http2.NewFramer(buf, nil) + err := framer.WritePriority(10, http2.PriorityParam{Weight: 42}) + Expect(err).ToNot(HaveOccurred()) + Expect(buf.Bytes()).ToNot(BeEmpty()) + headerStream.dataToRead.Write(buf.Bytes()) + err = s.handleRequest(session, headerStream, &sync.Mutex{}, hpackDecoder, h2framer) + Expect(err).ToNot(HaveOccurred()) + Consistently(handlerCalled).ShouldNot(BeClosed()) + Expect(dataStream.reset).To(BeFalse()) + Expect(dataStream.closed).To(BeFalse()) + }) + It("errors when non-header frames are received", func() { headerStream.dataToRead.Write([]byte{ 0x0, 0x0, 0x06, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, diff --git a/internal/protocol/version.go b/internal/protocol/version.go index f7dd70b3..a2d6080c 100644 --- a/internal/protocol/version.go +++ b/internal/protocol/version.go @@ -20,6 +20,7 @@ const ( const ( Version39 VersionNumber = gquicVersion0 + 3*0x100 + 0x9 Version42 VersionNumber = gquicVersion0 + 4*0x100 + 0x2 + Version43 VersionNumber = gquicVersion0 + 4*0x100 + 0x3 VersionTLS VersionNumber = 101 VersionWhatever VersionNumber = 0 // for when the version doesn't matter VersionUnknown VersionNumber = math.MaxUint32 @@ -28,6 +29,7 @@ const ( // SupportedVersions lists the versions that the server supports // must be in sorted descending order var SupportedVersions = []VersionNumber{ + Version43, Version42, Version39, } diff --git a/internal/protocol/version_test.go b/internal/protocol/version_test.go index 9d5cf95d..33653405 100644 --- a/internal/protocol/version_test.go +++ b/internal/protocol/version_test.go @@ -14,11 +14,13 @@ var _ = Describe("Version", func() { It("has the right gQUIC version number", func() { Expect(Version39).To(BeEquivalentTo(0x51303339)) Expect(Version42).To(BeEquivalentTo(0x51303432)) + Expect(Version43).To(BeEquivalentTo(0x51303433)) }) It("says if a version is valid", func() { Expect(IsValidVersion(Version39)).To(BeTrue()) Expect(IsValidVersion(Version42)).To(BeTrue()) + Expect(IsValidVersion(Version43)).To(BeTrue()) Expect(IsValidVersion(VersionTLS)).To(BeTrue()) Expect(IsValidVersion(VersionWhatever)).To(BeFalse()) Expect(IsValidVersion(VersionUnknown)).To(BeFalse()) @@ -28,12 +30,14 @@ var _ = Describe("Version", func() { It("says if a version supports TLS", func() { Expect(Version39.UsesTLS()).To(BeFalse()) Expect(Version42.UsesTLS()).To(BeFalse()) + Expect(Version43.UsesTLS()).To(BeFalse()) Expect(VersionTLS.UsesTLS()).To(BeTrue()) }) It("versions don't have reserved version numbers", func() { Expect(isReservedVersion(Version39)).To(BeFalse()) Expect(isReservedVersion(Version42)).To(BeFalse()) + Expect(isReservedVersion(Version43)).To(BeFalse()) Expect(isReservedVersion(VersionTLS)).To(BeFalse()) }) @@ -53,6 +57,7 @@ var _ = Describe("Version", func() { It("has the right representation for the H2 Alt-Svc tag", func() { Expect(Version39.ToAltSvc()).To(Equal("39")) Expect(Version42.ToAltSvc()).To(Equal("42")) + Expect(Version43.ToAltSvc()).To(Equal("43")) Expect(VersionTLS.ToAltSvc()).To(Equal("101")) // check with unsupported version numbers from the wiki Expect(VersionNumber(0x51303133).ToAltSvc()).To(Equal("13")) @@ -63,29 +68,33 @@ var _ = Describe("Version", func() { It("tells the Stream ID of the crypto stream", func() { Expect(Version39.CryptoStreamID()).To(Equal(StreamID(1))) Expect(Version42.CryptoStreamID()).To(Equal(StreamID(1))) + Expect(Version43.CryptoStreamID()).To(Equal(StreamID(1))) Expect(VersionTLS.CryptoStreamID()).To(Equal(StreamID(0))) }) It("tells if a version uses the IETF frame types", func() { Expect(Version39.UsesIETFFrameFormat()).To(BeFalse()) Expect(Version42.UsesIETFFrameFormat()).To(BeFalse()) + Expect(Version43.UsesIETFFrameFormat()).To(BeFalse()) Expect(VersionTLS.UsesIETFFrameFormat()).To(BeTrue()) }) It("tells if a version uses the IETF frame types", func() { Expect(Version39.UsesIETFFrameFormat()).To(BeFalse()) Expect(Version42.UsesIETFFrameFormat()).To(BeFalse()) + Expect(Version43.UsesIETFFrameFormat()).To(BeFalse()) Expect(VersionTLS.UsesIETFFrameFormat()).To(BeTrue()) }) It("tells if a version uses STOP_WAITING frames", func() { Expect(Version39.UsesStopWaitingFrames()).To(BeTrue()) Expect(Version42.UsesStopWaitingFrames()).To(BeTrue()) + Expect(Version43.UsesStopWaitingFrames()).To(BeTrue()) Expect(VersionTLS.UsesStopWaitingFrames()).To(BeFalse()) }) It("says if a stream contributes to connection-level flowcontrol, for gQUIC", func() { - for _, v := range []VersionNumber{Version39, Version42} { + for _, v := range []VersionNumber{Version39, Version42, Version43} { version := v Expect(version.StreamContributesToConnectionFlowControl(1)).To(BeFalse()) Expect(version.StreamContributesToConnectionFlowControl(2)).To(BeTrue())