forked from quic-go/quic-go
implement parsing and writing of the NEW_TOKEN frame
This commit is contained in:
@@ -44,7 +44,8 @@ func parseFrame(r *bytes.Reader, typeByte byte, v protocol.VersionNumber) (Frame
|
||||
frame, err = parseStopSendingFrame(r, v)
|
||||
case 0x6:
|
||||
frame, err = parseCryptoFrame(r, v)
|
||||
// TODO: implement the NEW_TOKEN frame
|
||||
case 0x7:
|
||||
frame, err = parseNewTokenFrame(r, v)
|
||||
case 0x10:
|
||||
frame, err = parseMaxDataFrame(r, v)
|
||||
case 0x11:
|
||||
|
||||
@@ -85,6 +85,16 @@ var _ = Describe("Frame parsing", func() {
|
||||
Expect(frame).To(Equal(f))
|
||||
})
|
||||
|
||||
It("unpacks NEW_TOKEN frames", func() {
|
||||
f := &NewTokenFrame{Token: []byte("foobar")}
|
||||
err := f.Write(buf, versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
frame, err := ParseNextFrame(bytes.NewReader(buf.Bytes()), versionIETFFrames)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(frame).ToNot(BeNil())
|
||||
Expect(frame).To(Equal(f))
|
||||
})
|
||||
|
||||
It("unpacks STREAM frames", func() {
|
||||
f := &StreamFrame{
|
||||
StreamID: 0x42,
|
||||
|
||||
44
internal/wire/new_token_frame.go
Normal file
44
internal/wire/new_token_frame.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package wire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
)
|
||||
|
||||
// A NewTokenFrame is a NEW_TOKEN frame
|
||||
type NewTokenFrame struct {
|
||||
Token []byte
|
||||
}
|
||||
|
||||
func parseNewTokenFrame(r *bytes.Reader, _ protocol.VersionNumber) (*NewTokenFrame, error) {
|
||||
if _, err := r.ReadByte(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tokenLen, err := utils.ReadVarInt(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if uint64(r.Len()) < tokenLen {
|
||||
return nil, io.EOF
|
||||
}
|
||||
token := make([]byte, int(tokenLen))
|
||||
if _, err := io.ReadFull(r, token); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &NewTokenFrame{Token: token}, nil
|
||||
}
|
||||
|
||||
func (f *NewTokenFrame) Write(b *bytes.Buffer, _ protocol.VersionNumber) error {
|
||||
b.WriteByte(0x7)
|
||||
utils.WriteVarInt(b, uint64(len(f.Token)))
|
||||
b.Write(f.Token)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Length of a written frame
|
||||
func (f *NewTokenFrame) Length(protocol.VersionNumber) protocol.ByteCount {
|
||||
return 1 + utils.VarIntLen(uint64(len(f.Token))) + protocol.ByteCount(len(f.Token))
|
||||
}
|
||||
58
internal/wire/new_token_frame_test.go
Normal file
58
internal/wire/new_token_frame_test.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package wire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/utils"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("NEW_TOKEN frame", func() {
|
||||
Context("parsing", func() {
|
||||
It("accepts a sample frame", func() {
|
||||
token := "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
|
||||
data := []byte{0x7}
|
||||
data = append(data, encodeVarInt(uint64(len(token)))...)
|
||||
data = append(data, token...)
|
||||
b := bytes.NewReader(data)
|
||||
f, err := parseNewTokenFrame(b, protocol.VersionWhatever)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(string(f.Token)).To(Equal(token))
|
||||
Expect(b.Len()).To(BeZero())
|
||||
})
|
||||
|
||||
It("errors on EOFs", func() {
|
||||
token := "Lorem ipsum dolor sit amet, consectetur adipiscing elit"
|
||||
data := []byte{0x7}
|
||||
data = append(data, encodeVarInt(uint64(len(token)))...)
|
||||
data = append(data, token...)
|
||||
_, err := parseNewTokenFrame(bytes.NewReader(data), protocol.VersionWhatever)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
for i := range data {
|
||||
_, err := parseNewTokenFrame(bytes.NewReader(data[0:i]), protocol.VersionWhatever)
|
||||
Expect(err).To(HaveOccurred())
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
Context("writing", func() {
|
||||
It("writes a sample frame", func() {
|
||||
token := "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
|
||||
f := &NewTokenFrame{Token: []byte(token)}
|
||||
b := &bytes.Buffer{}
|
||||
Expect(f.Write(b, protocol.VersionWhatever)).To(Succeed())
|
||||
expected := []byte{0x7}
|
||||
expected = append(expected, encodeVarInt(uint64(len(token)))...)
|
||||
expected = append(expected, token...)
|
||||
Expect(b.Bytes()).To(Equal(expected))
|
||||
})
|
||||
|
||||
It("has the correct min length", func() {
|
||||
frame := &NewTokenFrame{Token: []byte("foobar")}
|
||||
Expect(frame.Length(protocol.VersionWhatever)).To(Equal(1 + utils.VarIntLen(6) + 6))
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -578,6 +578,7 @@ func (s *session) handleFrames(fs []wire.Frame, encLevel protocol.EncryptionLeve
|
||||
case *wire.PathResponseFrame:
|
||||
// since we don't send PATH_CHALLENGEs, we don't expect PATH_RESPONSEs
|
||||
err = errors.New("unexpected PATH_RESPONSE frame")
|
||||
case *wire.NewTokenFrame:
|
||||
default:
|
||||
return errors.New("Session BUG: unexpected frame type")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user