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 {
|
||||
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() {
|
||||
Context("stream frames", func() {
|
||||
Context("when parsing", func() {
|
||||
It("accepts sample frame", func() {
|
||||
b := bytes.NewReader([]byte{0xa0, 0x1, 0x06, 0x00, '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")))
|
||||
})
|
||||
|
||||
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 parsing", func() {
|
||||
It("accepts sample frame", func() {
|
||||
b := bytes.NewReader([]byte{0xa0, 0x1, 0x06, 0x00, '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("writes sample frame", func() {
|
||||
b := &bytes.Buffer{}
|
||||
(&StreamFrame{
|
||||
StreamID: 1,
|
||||
Data: []byte("foobar"),
|
||||
}).Write(b)
|
||||
Expect(b.Bytes()).To(Equal([]byte{0xa3, 0x1, 0, 0, 0, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'}))
|
||||
})
|
||||
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")))
|
||||
})
|
||||
})
|
||||
|
||||
It("writes offsets", func() {
|
||||
b := &bytes.Buffer{}
|
||||
(&StreamFrame{
|
||||
StreamID: 1,
|
||||
Offset: 16,
|
||||
Data: []byte("foobar"),
|
||||
}).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'}))
|
||||
})
|
||||
Context("when writing", func() {
|
||||
It("writes sample frame", func() {
|
||||
b := &bytes.Buffer{}
|
||||
(&StreamFrame{
|
||||
StreamID: 1,
|
||||
Data: []byte("foobar"),
|
||||
}).Write(b)
|
||||
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() {
|
||||
b := &bytes.Buffer{}
|
||||
f := &StreamFrame{
|
||||
StreamID: 1,
|
||||
Data: []byte("f"),
|
||||
Offset: 1,
|
||||
}
|
||||
f.Write(b)
|
||||
Expect(f.MaxLength()).To(Equal(b.Len()))
|
||||
})
|
||||
It("writes offsets", func() {
|
||||
b := &bytes.Buffer{}
|
||||
(&StreamFrame{
|
||||
StreamID: 1,
|
||||
Offset: 16,
|
||||
Data: []byte("foobar"),
|
||||
}).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'}))
|
||||
})
|
||||
|
||||
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