forked from quic-go/quic-go
implement stream frame splitting in StreamFrame
This commit is contained in:
@@ -93,3 +93,23 @@ func (f *StreamFrame) Write(b *bytes.Buffer) error {
|
|||||||
func (f *StreamFrame) MaxLength() int {
|
func (f *StreamFrame) MaxLength() int {
|
||||||
return 1 + 4 + 8 + 2 + 1
|
return 1 + 4 + 8 + 2 + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MaybeSplitOffFrame removes the first n bytes and returns them as a separate frame. If n >= len(n), nil is returned and nothing is modified.
|
||||||
|
func (f *StreamFrame) MaybeSplitOffFrame(n int) *StreamFrame {
|
||||||
|
if n >= f.MaxLength()-1+len(f.Data) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
n -= f.MaxLength() - 1
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
f.Data = f.Data[n:]
|
||||||
|
f.Offset += uint64(n)
|
||||||
|
}()
|
||||||
|
|
||||||
|
return &StreamFrame{
|
||||||
|
FinBit: false,
|
||||||
|
StreamID: f.StreamID,
|
||||||
|
Offset: f.Offset,
|
||||||
|
Data: f.Data[:n],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,59 +9,88 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("StreamFrame", func() {
|
var _ = Describe("StreamFrame", func() {
|
||||||
Context("stream frames", func() {
|
Context("when parsing", func() {
|
||||||
Context("when parsing", func() {
|
It("accepts sample frame", func() {
|
||||||
It("accepts sample frame", func() {
|
b := bytes.NewReader([]byte{0xa0, 0x1, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'})
|
||||||
b := bytes.NewReader([]byte{0xa0, 0x1, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'})
|
frame, err := ParseStreamFrame(b)
|
||||||
frame, err := ParseStreamFrame(b)
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(frame.FinBit).To(BeFalse())
|
||||||
Expect(frame.FinBit).To(BeFalse())
|
Expect(frame.StreamID).To(Equal(protocol.StreamID(1)))
|
||||||
Expect(frame.StreamID).To(Equal(protocol.StreamID(1)))
|
Expect(frame.Offset).To(BeZero())
|
||||||
Expect(frame.Offset).To(BeZero())
|
Expect(frame.Data).To(Equal([]byte("foobar")))
|
||||||
Expect(frame.Data).To(Equal([]byte("foobar")))
|
|
||||||
})
|
|
||||||
|
|
||||||
It("accepts frame without datalength", func() {
|
|
||||||
b := bytes.NewReader([]byte{0x80, 0x1, 'f', 'o', 'o', 'b', 'a', 'r'})
|
|
||||||
frame, err := ParseStreamFrame(b)
|
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
Expect(frame.FinBit).To(BeFalse())
|
|
||||||
Expect(frame.StreamID).To(Equal(protocol.StreamID(1)))
|
|
||||||
Expect(frame.Offset).To(BeZero())
|
|
||||||
Expect(frame.Data).To(Equal([]byte("foobar")))
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("when writing", func() {
|
It("accepts frame without datalength", func() {
|
||||||
It("writes sample frame", func() {
|
b := bytes.NewReader([]byte{0x80, 0x1, 'f', 'o', 'o', 'b', 'a', 'r'})
|
||||||
b := &bytes.Buffer{}
|
frame, err := ParseStreamFrame(b)
|
||||||
(&StreamFrame{
|
Expect(err).ToNot(HaveOccurred())
|
||||||
StreamID: 1,
|
Expect(frame.FinBit).To(BeFalse())
|
||||||
Data: []byte("foobar"),
|
Expect(frame.StreamID).To(Equal(protocol.StreamID(1)))
|
||||||
}).Write(b)
|
Expect(frame.Offset).To(BeZero())
|
||||||
Expect(b.Bytes()).To(Equal([]byte{0xa3, 0x1, 0, 0, 0, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'}))
|
Expect(frame.Data).To(Equal([]byte("foobar")))
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
It("writes offsets", func() {
|
Context("when writing", func() {
|
||||||
b := &bytes.Buffer{}
|
It("writes sample frame", func() {
|
||||||
(&StreamFrame{
|
b := &bytes.Buffer{}
|
||||||
StreamID: 1,
|
(&StreamFrame{
|
||||||
Offset: 16,
|
StreamID: 1,
|
||||||
Data: []byte("foobar"),
|
Data: []byte("foobar"),
|
||||||
}).Write(b)
|
}).Write(b)
|
||||||
Expect(b.Bytes()).To(Equal([]byte{0xbf, 0x1, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'}))
|
Expect(b.Bytes()).To(Equal([]byte{0xa3, 0x1, 0, 0, 0, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'}))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("has proper max length", func() {
|
It("writes offsets", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
f := &StreamFrame{
|
(&StreamFrame{
|
||||||
StreamID: 1,
|
StreamID: 1,
|
||||||
Data: []byte("f"),
|
Offset: 16,
|
||||||
Offset: 1,
|
Data: []byte("foobar"),
|
||||||
}
|
}).Write(b)
|
||||||
f.Write(b)
|
Expect(b.Bytes()).To(Equal([]byte{0xbf, 0x1, 0, 0, 0, 0x10, 0, 0, 0, 0, 0, 0, 0, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'}))
|
||||||
Expect(f.MaxLength()).To(Equal(b.Len()))
|
})
|
||||||
})
|
|
||||||
|
It("has proper max length", func() {
|
||||||
|
b := &bytes.Buffer{}
|
||||||
|
f := &StreamFrame{
|
||||||
|
StreamID: 1,
|
||||||
|
Data: []byte("f"),
|
||||||
|
Offset: 1,
|
||||||
|
}
|
||||||
|
f.Write(b)
|
||||||
|
Expect(f.MaxLength()).To(Equal(b.Len()))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("splitting off earlier stream frames", func() {
|
||||||
|
It("splits off nothing", func() {
|
||||||
|
f := &StreamFrame{
|
||||||
|
StreamID: 1,
|
||||||
|
Data: []byte("bar"),
|
||||||
|
Offset: 3,
|
||||||
|
}
|
||||||
|
Expect(f.MaybeSplitOffFrame(1000)).To(BeNil())
|
||||||
|
Expect(f.Offset).To(Equal(uint64(3)))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("splits off initial frame", func() {
|
||||||
|
f := &StreamFrame{
|
||||||
|
StreamID: 1,
|
||||||
|
Data: []byte("foobar"),
|
||||||
|
Offset: 3,
|
||||||
|
FinBit: true,
|
||||||
|
}
|
||||||
|
previous := f.MaybeSplitOffFrame(f.MaxLength() - 1 + 3)
|
||||||
|
Expect(previous).ToNot(BeNil())
|
||||||
|
Expect(previous.StreamID).To(Equal(protocol.StreamID(1)))
|
||||||
|
Expect(previous.Data).To(Equal([]byte("foo")))
|
||||||
|
Expect(previous.Offset).To(Equal(uint64(3)))
|
||||||
|
Expect(previous.FinBit).To(BeFalse())
|
||||||
|
Expect(f.StreamID).To(Equal(protocol.StreamID(1)))
|
||||||
|
Expect(f.Data).To(Equal([]byte("bar")))
|
||||||
|
Expect(f.Offset).To(Equal(uint64(6)))
|
||||||
|
Expect(f.FinBit).To(BeTrue())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user