diff --git a/h2quic/client.go b/h2quic/client.go index fd7eb85ef..c712915a3 100644 --- a/h2quic/client.go +++ b/h2quic/client.go @@ -168,8 +168,7 @@ func (c *Client) Do(req *http.Request) (*http.Response, error) { c.cryptoChangedCond.Wait() } hdrChan := make(chan *http.Response) - // TODO: think about what to do with a TooManyOpenStreams error. Wait and retry? - dataStream, err := c.session.OpenStream() + dataStream, err := c.session.OpenStreamSync() if err != nil { c.Close(err) return nil, err diff --git a/h2quic/client_test.go b/h2quic/client_test.go index 24b826698..c2eeaae02 100644 --- a/h2quic/client_test.go +++ b/h2quic/client_test.go @@ -181,6 +181,21 @@ var _ = Describe("Client", func() { Expect(client.session.(*mockSession).closedWithError).To(MatchError(client.headerErr)) }) + It("blocks if no stream is available", func() { + session.blockOpenStreamSync = true + var doReturned bool + go func() { + defer GinkgoRecover() + _, err := client.Do(request) + Expect(err).ToNot(HaveOccurred()) + doReturned = true + }() + headerStream.dataToRead.Write([]byte("invalid response")) + go client.handleHeaderStream() + + Consistently(func() bool { return doReturned }).Should(BeFalse()) + }) + Context("validating the address", func() { It("refuses to do requests for the wrong host", func() { req, err := http.NewRequest("https", "https://quic.clemente.io:1336/foobar.html", nil) diff --git a/h2quic/server_test.go b/h2quic/server_test.go index f760c6e17..b1e30c01e 100644 --- a/h2quic/server_test.go +++ b/h2quic/server_test.go @@ -9,6 +9,7 @@ import ( "runtime" "sync" "syscall" + "time" "golang.org/x/net/http2" "golang.org/x/net/http2/hpack" @@ -23,12 +24,13 @@ import ( ) type mockSession struct { - closed bool - closedWithError error - dataStream quic.Stream - streamToAccept quic.Stream - streamToOpen quic.Stream - streamOpenErr error + closed bool + closedWithError error + dataStream quic.Stream + streamToAccept quic.Stream + streamToOpen quic.Stream + blockOpenStreamSync bool + streamOpenErr error } func (s *mockSession) GetOrOpenStream(id protocol.StreamID) (quic.Stream, error) { @@ -44,7 +46,10 @@ func (s *mockSession) OpenStream() (quic.Stream, error) { return s.streamToOpen, nil } func (s *mockSession) OpenStreamSync() (quic.Stream, error) { - panic("not implemented") + if s.blockOpenStreamSync { + time.Sleep(time.Hour) + } + return s.OpenStream() } func (s *mockSession) Close(e error) error { s.closed = true