implement HTTP/3 stream hijacking

This commit is contained in:
Marten Seemann
2022-03-22 17:40:10 +01:00
parent a54816867f
commit 48a2cce9df
10 changed files with 152 additions and 37 deletions

View File

@@ -24,7 +24,7 @@ var _ = Describe("Frames", func() {
data = append(data, make([]byte, 0x42)...)
buf := bytes.NewBuffer(data)
(&dataFrame{Length: 0x1234}).Write(buf)
frame, err := parseNextFrame(buf)
frame, err := parseNextFrame(buf, nil)
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(BeAssignableToTypeOf(&dataFrame{}))
Expect(frame.(*dataFrame).Length).To(Equal(uint64(0x1234)))
@@ -34,7 +34,7 @@ var _ = Describe("Frames", func() {
It("parses", func() {
data := appendVarInt(nil, 0) // type byte
data = appendVarInt(data, 0x1337)
frame, err := parseNextFrame(bytes.NewReader(data))
frame, err := parseNextFrame(bytes.NewReader(data), nil)
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(BeAssignableToTypeOf(&dataFrame{}))
Expect(frame.(*dataFrame).Length).To(Equal(uint64(0x1337)))
@@ -43,7 +43,7 @@ var _ = Describe("Frames", func() {
It("writes", func() {
buf := &bytes.Buffer{}
(&dataFrame{Length: 0xdeadbeef}).Write(buf)
frame, err := parseNextFrame(buf)
frame, err := parseNextFrame(buf, nil)
Expect(err).ToNot(HaveOccurred())
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(BeAssignableToTypeOf(&dataFrame{}))
@@ -55,7 +55,7 @@ var _ = Describe("Frames", func() {
It("parses", func() {
data := appendVarInt(nil, 1) // type byte
data = appendVarInt(data, 0x1337)
frame, err := parseNextFrame(bytes.NewReader(data))
frame, err := parseNextFrame(bytes.NewReader(data), nil)
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(BeAssignableToTypeOf(&headersFrame{}))
Expect(frame.(*headersFrame).Length).To(Equal(uint64(0x1337)))
@@ -64,7 +64,7 @@ var _ = Describe("Frames", func() {
It("writes", func() {
buf := &bytes.Buffer{}
(&headersFrame{Length: 0xdeadbeef}).Write(buf)
frame, err := parseNextFrame(buf)
frame, err := parseNextFrame(buf, nil)
Expect(err).ToNot(HaveOccurred())
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(BeAssignableToTypeOf(&headersFrame{}))
@@ -81,7 +81,7 @@ var _ = Describe("Frames", func() {
data := appendVarInt(nil, 4) // type byte
data = appendVarInt(data, uint64(len(settings)))
data = append(data, settings...)
frame, err := parseNextFrame(bytes.NewReader(data))
frame, err := parseNextFrame(bytes.NewReader(data), nil)
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(BeAssignableToTypeOf(&settingsFrame{}))
sf := frame.(*settingsFrame)
@@ -97,7 +97,7 @@ var _ = Describe("Frames", func() {
data := appendVarInt(nil, 4) // type byte
data = appendVarInt(data, uint64(len(settings)))
data = append(data, settings...)
_, err := parseNextFrame(bytes.NewReader(data))
_, err := parseNextFrame(bytes.NewReader(data), nil)
Expect(err).To(MatchError("duplicate setting: 13"))
})
@@ -109,7 +109,7 @@ var _ = Describe("Frames", func() {
}}
buf := &bytes.Buffer{}
sf.Write(buf)
frame, err := parseNextFrame(buf)
frame, err := parseNextFrame(buf, nil)
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(Equal(sf))
})
@@ -123,13 +123,13 @@ var _ = Describe("Frames", func() {
sf.Write(buf)
data := buf.Bytes()
_, err := parseNextFrame(bytes.NewReader(data))
_, err := parseNextFrame(bytes.NewReader(data), nil)
Expect(err).ToNot(HaveOccurred())
for i := range data {
b := make([]byte, i)
copy(b, data[:i])
_, err := parseNextFrame(bytes.NewReader(b))
_, err := parseNextFrame(bytes.NewReader(b), nil)
Expect(err).To(MatchError(io.EOF))
}
})
@@ -141,7 +141,7 @@ var _ = Describe("Frames", func() {
data := appendVarInt(nil, 4) // type byte
data = appendVarInt(data, uint64(len(settings)))
data = append(data, settings...)
f, err := parseNextFrame(bytes.NewReader(data))
f, err := parseNextFrame(bytes.NewReader(data), nil)
Expect(err).ToNot(HaveOccurred())
Expect(f).To(BeAssignableToTypeOf(&settingsFrame{}))
sf := f.(*settingsFrame)
@@ -156,7 +156,7 @@ var _ = Describe("Frames", func() {
data := appendVarInt(nil, 4) // type byte
data = appendVarInt(data, uint64(len(settings)))
data = append(data, settings...)
_, err := parseNextFrame(bytes.NewReader(data))
_, err := parseNextFrame(bytes.NewReader(data), nil)
Expect(err).To(MatchError(fmt.Sprintf("duplicate setting: %d", settingDatagram)))
})
@@ -166,7 +166,7 @@ var _ = Describe("Frames", func() {
data := appendVarInt(nil, 4) // type byte
data = appendVarInt(data, uint64(len(settings)))
data = append(data, settings...)
_, err := parseNextFrame(bytes.NewReader(data))
_, err := parseNextFrame(bytes.NewReader(data), nil)
Expect(err).To(MatchError("invalid value for H3_DATAGRAM: 1337"))
})
@@ -174,10 +174,55 @@ var _ = Describe("Frames", func() {
sf := &settingsFrame{Datagram: true}
buf := &bytes.Buffer{}
sf.Write(buf)
frame, err := parseNextFrame(buf)
frame, err := parseNextFrame(buf, nil)
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(Equal(sf))
})
})
})
Context("hijacking", func() {
It("reads a frame without hijacking the stream", func() {
buf := &bytes.Buffer{}
quicvarint.Write(buf, 1337)
customFrameContents := []byte("foobar")
buf.Write(customFrameContents)
var called bool
_, err := parseNextFrame(buf, func(ft FrameType) (hijacked bool, err error) {
Expect(ft).To(BeEquivalentTo(1337))
called = true
b := make([]byte, 3)
_, err = io.ReadFull(buf, b)
Expect(err).ToNot(HaveOccurred())
Expect(string(b)).To(Equal("foo"))
return true, nil
})
Expect(err).To(MatchError(errHijacked))
Expect(called).To(BeTrue())
})
It("reads a frame without hijacking the stream", func() {
buf := &bytes.Buffer{}
quicvarint.Write(buf, 1337)
customFrameContents := []byte("custom frame")
buf.Write(customFrameContents)
(&dataFrame{Length: 6}).Write(buf)
buf.WriteString("foobar")
var called bool
frame, err := parseNextFrame(buf, func(ft FrameType) (hijacked bool, err error) {
Expect(ft).To(BeEquivalentTo(1337))
called = true
b := make([]byte, len(customFrameContents))
_, err = io.ReadFull(buf, b)
Expect(err).ToNot(HaveOccurred())
Expect(string(b)).To(Equal(string(customFrameContents)))
return false, nil
})
Expect(err).ToNot(HaveOccurred())
Expect(frame).To(Equal(&dataFrame{Length: 6}))
Expect(called).To(BeTrue())
})
})
})