forked from quic-go/quic-go
add option to write StreamFrames without Data length field
work towards #77
This commit is contained in:
@@ -16,6 +16,7 @@ type StreamFrame struct {
|
|||||||
streamIDLen protocol.ByteCount
|
streamIDLen protocol.ByteCount
|
||||||
Offset protocol.ByteCount
|
Offset protocol.ByteCount
|
||||||
Data []byte
|
Data []byte
|
||||||
|
DataLenPresent bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -33,7 +34,7 @@ func ParseStreamFrame(r *bytes.Reader) (*StreamFrame, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
frame.FinBit = typeByte&0x40 > 0
|
frame.FinBit = typeByte&0x40 > 0
|
||||||
dataLenPresent := typeByte&0x20 > 0
|
frame.DataLenPresent = typeByte&0x20 > 0
|
||||||
offsetLen := typeByte & 0x1C >> 2
|
offsetLen := typeByte & 0x1C >> 2
|
||||||
if offsetLen != 0 {
|
if offsetLen != 0 {
|
||||||
offsetLen++
|
offsetLen++
|
||||||
@@ -53,7 +54,7 @@ func ParseStreamFrame(r *bytes.Reader) (*StreamFrame, error) {
|
|||||||
frame.Offset = protocol.ByteCount(offset)
|
frame.Offset = protocol.ByteCount(offset)
|
||||||
|
|
||||||
var dataLen uint16
|
var dataLen uint16
|
||||||
if dataLenPresent {
|
if frame.DataLenPresent {
|
||||||
dataLen, err = utils.ReadUint16(r)
|
dataLen, err = utils.ReadUint16(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -79,10 +80,14 @@ func ParseStreamFrame(r *bytes.Reader) (*StreamFrame, error) {
|
|||||||
// WriteStreamFrame writes a stream frame.
|
// WriteStreamFrame writes a stream frame.
|
||||||
func (f *StreamFrame) Write(b *bytes.Buffer, packetNumber protocol.PacketNumber, packetNumberLen protocol.PacketNumberLen, version protocol.VersionNumber) error {
|
func (f *StreamFrame) Write(b *bytes.Buffer, packetNumber protocol.PacketNumber, packetNumberLen protocol.PacketNumberLen, version protocol.VersionNumber) error {
|
||||||
typeByte := uint8(0x80) // sets the leftmost bit to 1
|
typeByte := uint8(0x80) // sets the leftmost bit to 1
|
||||||
|
|
||||||
if f.FinBit {
|
if f.FinBit {
|
||||||
typeByte ^= 0x40
|
typeByte ^= 0x40
|
||||||
}
|
}
|
||||||
typeByte ^= 0x20 // dataLenPresent
|
|
||||||
|
if f.DataLenPresent {
|
||||||
|
typeByte ^= 0x20
|
||||||
|
}
|
||||||
|
|
||||||
offsetLength := f.getOffsetLength()
|
offsetLength := f.getOffsetLength()
|
||||||
|
|
||||||
@@ -130,8 +135,12 @@ func (f *StreamFrame) Write(b *bytes.Buffer, packetNumber protocol.PacketNumber,
|
|||||||
return errInvalidOffsetLen
|
return errInvalidOffsetLen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if f.DataLenPresent {
|
||||||
utils.WriteUint16(b, uint16(len(f.Data)))
|
utils.WriteUint16(b, uint16(len(f.Data)))
|
||||||
|
}
|
||||||
|
|
||||||
b.Write(f.Data)
|
b.Write(f.Data)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +187,12 @@ func (f *StreamFrame) MinLength() protocol.ByteCount {
|
|||||||
f.calculateStreamIDLength()
|
f.calculateStreamIDLength()
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1 + f.streamIDLen + f.getOffsetLength() + 2 + 1
|
length := protocol.ByteCount(1) + f.streamIDLen + f.getOffsetLength()
|
||||||
|
if f.DataLenPresent {
|
||||||
|
length += 2
|
||||||
|
}
|
||||||
|
|
||||||
|
return length + 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.
|
// MaybeSplitOffFrame removes the first n bytes and returns them as a separate frame. If n >= len(n), nil is returned and nothing is modified.
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ var _ = Describe("StreamFrame", func() {
|
|||||||
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.DataLenPresent).To(BeTrue())
|
||||||
Expect(frame.Data).To(Equal([]byte("foobar")))
|
Expect(frame.Data).To(Equal([]byte("foobar")))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -27,6 +28,7 @@ var _ = Describe("StreamFrame", func() {
|
|||||||
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.DataLenPresent).To(BeFalse())
|
||||||
Expect(frame.Data).To(Equal([]byte("foobar")))
|
Expect(frame.Data).To(Equal([]byte("foobar")))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -37,6 +39,7 @@ var _ = Describe("StreamFrame", func() {
|
|||||||
(&StreamFrame{
|
(&StreamFrame{
|
||||||
StreamID: 1,
|
StreamID: 1,
|
||||||
Data: []byte("foobar"),
|
Data: []byte("foobar"),
|
||||||
|
DataLenPresent: true,
|
||||||
}).Write(b, 1, protocol.PacketNumberLen6, 0)
|
}).Write(b, 1, protocol.PacketNumberLen6, 0)
|
||||||
Expect(b.Bytes()).To(Equal([]byte{0xa0, 0x1, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'}))
|
Expect(b.Bytes()).To(Equal([]byte{0xa0, 0x1, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'}))
|
||||||
})
|
})
|
||||||
@@ -63,6 +66,52 @@ var _ = Describe("StreamFrame", func() {
|
|||||||
Expect(f.MinLength()).To(Equal(protocol.ByteCount(b.Len())))
|
Expect(f.MinLength()).To(Equal(protocol.ByteCount(b.Len())))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Context("data length field", func() {
|
||||||
|
It("writes the data length", func() {
|
||||||
|
dataLen := 0x1337
|
||||||
|
b := &bytes.Buffer{}
|
||||||
|
f := &StreamFrame{
|
||||||
|
StreamID: 1,
|
||||||
|
Data: bytes.Repeat([]byte{'f'}, dataLen),
|
||||||
|
DataLenPresent: true,
|
||||||
|
Offset: 0,
|
||||||
|
}
|
||||||
|
f.Write(b, 1, protocol.PacketNumberLen6, 0)
|
||||||
|
headerLength := f.MinLength() - 1
|
||||||
|
Expect(b.Bytes()[0] & 0x20).To(Equal(uint8(0x20)))
|
||||||
|
Expect(b.Bytes()[headerLength-2 : headerLength]).To(Equal([]byte{0x37, 0x13}))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("omits the data length field", func() {
|
||||||
|
dataLen := 0x1337
|
||||||
|
b := &bytes.Buffer{}
|
||||||
|
f := &StreamFrame{
|
||||||
|
StreamID: 1,
|
||||||
|
Data: bytes.Repeat([]byte{'f'}, dataLen),
|
||||||
|
DataLenPresent: false,
|
||||||
|
Offset: 0,
|
||||||
|
}
|
||||||
|
f.Write(b, 1, protocol.PacketNumberLen6, 0)
|
||||||
|
Expect(b.Bytes()[0] & 0x20).To(Equal(uint8(0)))
|
||||||
|
Expect(b.Bytes()[1 : b.Len()-dataLen]).ToNot(ContainSubstring(string([]byte{0x37, 0x13})))
|
||||||
|
minLength := f.MinLength()
|
||||||
|
f.DataLenPresent = true
|
||||||
|
Expect(minLength).To(Equal(f.MinLength() - 2))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("calculates the correcct min-length", func() {
|
||||||
|
f := &StreamFrame{
|
||||||
|
StreamID: 0xCAFE,
|
||||||
|
Data: []byte("foobar"),
|
||||||
|
DataLenPresent: false,
|
||||||
|
Offset: 0xDEADBEEF,
|
||||||
|
}
|
||||||
|
minLengthWithoutDataLen := f.MinLength()
|
||||||
|
f.DataLenPresent = true
|
||||||
|
Expect(f.MinLength()).To(Equal(minLengthWithoutDataLen + 2))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
Context("offset lengths", func() {
|
Context("offset lengths", func() {
|
||||||
It("does not write an offset if the offset is 0", func() {
|
It("does not write an offset if the offset is 0", func() {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
|
|||||||
@@ -420,7 +420,7 @@ var _ = Describe("Session", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("should call OnSent", func() {
|
It("should call OnSent", func() {
|
||||||
session.QueueStreamFrame(&frames.StreamFrame{StreamID: 5})
|
session.QueueStreamFrame(&frames.StreamFrame{StreamID: 5, DataLenPresent: true})
|
||||||
session.sendPacket()
|
session.sendPacket()
|
||||||
Expect(cong.nCalls).To(Equal(2)) // OnPacketSent + GetCongestionWindow
|
Expect(cong.nCalls).To(Equal(2)) // OnPacketSent + GetCongestionWindow
|
||||||
Expect(cong.argsOnPacketSent[1]).To(Equal(protocol.ByteCount(27)))
|
Expect(cong.argsOnPacketSent[1]).To(Equal(protocol.ByteCount(27)))
|
||||||
|
|||||||
Reference in New Issue
Block a user