mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 20:57:36 +03:00
don't close the request stream when http3.DataStreamer was used (#3413)
This commit is contained in:
parent
0ec8ee3cff
commit
6511723c28
2 changed files with 37 additions and 11 deletions
|
@ -582,15 +582,17 @@ func (s *Server) handleRequest(conn quic.Connection, str quic.Stream, decoder *q
|
||||||
handler.ServeHTTP(r, req)
|
handler.ServeHTTP(r, req)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if !r.usedDataStream() {
|
if r.usedDataStream() {
|
||||||
if panicked {
|
return requestError{err: errHijacked}
|
||||||
r.WriteHeader(500)
|
|
||||||
} else {
|
|
||||||
r.WriteHeader(200)
|
|
||||||
}
|
|
||||||
// If the EOF was read by the handler, CancelRead() is a no-op.
|
|
||||||
str.CancelRead(quic.StreamErrorCode(errorNoError))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if panicked {
|
||||||
|
r.WriteHeader(500)
|
||||||
|
} else {
|
||||||
|
r.WriteHeader(200)
|
||||||
|
}
|
||||||
|
// If the EOF was read by the handler, CancelRead() is a no-op.
|
||||||
|
str.CancelRead(quic.StreamErrorCode(errorNoError))
|
||||||
return requestError{}
|
return requestError{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -228,13 +228,37 @@ var _ = Describe("Server", func() {
|
||||||
str.Write([]byte("foobar"))
|
str.Write([]byte("foobar"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
rspWritten := make(chan struct{})
|
||||||
setRequest(encodeRequest(exampleGetRequest))
|
setRequest(encodeRequest(exampleGetRequest))
|
||||||
str.EXPECT().Context().Return(reqContext)
|
str.EXPECT().Context().Return(reqContext)
|
||||||
str.EXPECT().Write([]byte("foobar"))
|
str.EXPECT().Write([]byte("foobar")).Do(func(b []byte) (int, error) {
|
||||||
|
close(rspWritten)
|
||||||
|
return len(b), nil
|
||||||
|
})
|
||||||
// don't EXPECT CancelRead()
|
// don't EXPECT CancelRead()
|
||||||
|
|
||||||
serr := s.handleRequest(conn, str, qpackDecoder, nil)
|
ctrlStr := mockquic.NewMockStream(mockCtrl)
|
||||||
Expect(serr.err).ToNot(HaveOccurred())
|
ctrlStr.EXPECT().Write(gomock.Any()).AnyTimes()
|
||||||
|
conn.EXPECT().OpenUniStream().Return(ctrlStr, nil)
|
||||||
|
conn.EXPECT().AcceptUniStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.ReceiveStream, error) {
|
||||||
|
<-rspWritten
|
||||||
|
return nil, errors.New("done")
|
||||||
|
})
|
||||||
|
conn.EXPECT().AcceptStream(gomock.Any()).Return(str, nil)
|
||||||
|
conn.EXPECT().AcceptStream(gomock.Any()).DoAndReturn(func(context.Context) (quic.Stream, error) {
|
||||||
|
<-rspWritten
|
||||||
|
return nil, errors.New("done")
|
||||||
|
})
|
||||||
|
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
defer GinkgoRecover()
|
||||||
|
defer close(done)
|
||||||
|
s.handleConn(conn)
|
||||||
|
}()
|
||||||
|
Eventually(rspWritten).Should(BeClosed())
|
||||||
|
time.Sleep(50 * time.Millisecond) // make sure that after str.Write there are no further calls to stream methods
|
||||||
|
Eventually(done).Should(BeClosed())
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("hijacking unidirectional streams", func() {
|
Context("hijacking unidirectional streams", func() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue