close the connection when encountering an error on the header stream

fixes #403
This commit is contained in:
Marten Seemann
2017-01-26 14:12:50 +09:00
parent 86e02c4d2c
commit dfa0137bd6
2 changed files with 24 additions and 3 deletions

View File

@@ -112,6 +112,7 @@ func (s *Server) handleStream(session streamCreator, stream utils.Stream) {
if _, ok := err.(*qerr.QuicError); !ok { if _, ok := err.(*qerr.QuicError); !ok {
utils.Errorf("error handling h2 request: %s", err.Error()) utils.Errorf("error handling h2 request: %s", err.Error())
} }
session.Close(qerr.Error(qerr.InvalidHeadersStreamData, err.Error()))
return return
} }
} }

View File

@@ -1,6 +1,7 @@
package h2quic package h2quic
import ( import (
"bytes"
"net" "net"
"net/http" "net/http"
"os" "os"
@@ -12,6 +13,7 @@ import (
"golang.org/x/net/http2/hpack" "golang.org/x/net/http2/hpack"
"github.com/lucas-clemente/quic-go/protocol" "github.com/lucas-clemente/quic-go/protocol"
"github.com/lucas-clemente/quic-go/qerr"
"github.com/lucas-clemente/quic-go/testdata" "github.com/lucas-clemente/quic-go/testdata"
"github.com/lucas-clemente/quic-go/utils" "github.com/lucas-clemente/quic-go/utils"
@@ -20,14 +22,19 @@ import (
) )
type mockSession struct { type mockSession struct {
closed bool closed bool
dataStream *mockStream closedWithError error
dataStream *mockStream
} }
func (s *mockSession) GetOrOpenStream(id protocol.StreamID) (utils.Stream, error) { func (s *mockSession) GetOrOpenStream(id protocol.StreamID) (utils.Stream, error) {
return s.dataStream, nil return s.dataStream, nil
} }
func (s *mockSession) Close(error) error { s.closed = true; return nil } func (s *mockSession) Close(e error) error {
s.closed = true
s.closedWithError = e
return nil
}
func (s *mockSession) RemoteAddr() *net.UDPAddr { func (s *mockSession) RemoteAddr() *net.UDPAddr {
return &net.UDPAddr{IP: []byte{127, 0, 0, 1}, Port: 42} return &net.UDPAddr{IP: []byte{127, 0, 0, 1}, Port: 42}
} }
@@ -190,6 +197,19 @@ var _ = Describe("H2 server", func() {
Eventually(func() bool { return handlerCalled }).Should(BeTrue()) Eventually(func() bool { return handlerCalled }).Should(BeTrue())
}) })
It("closes the connection if it encounters an error on the header stream", func() {
var handlerCalled bool
s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
handlerCalled = true
})
headerStream := &mockStream{id: 3}
headerStream.dataToRead.Write(bytes.Repeat([]byte{0}, 100))
s.handleStream(session, headerStream)
Consistently(func() bool { return handlerCalled }).Should(BeFalse())
Eventually(func() bool { return session.closed }).Should(BeTrue())
Expect(session.closedWithError).To(MatchError(qerr.Error(qerr.InvalidHeadersStreamData, "connection error: PROTOCOL_ERROR")))
})
It("ignores other streams", func() { It("ignores other streams", func() {
var handlerCalled bool var handlerCalled bool
s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {