forked from quic-go/quic-go
implement marshalling of frames
This commit is contained in:
360
qlog/frame.go
Normal file
360
qlog/frame.go
Normal file
@@ -0,0 +1,360 @@
|
||||
package qlog
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/wire"
|
||||
)
|
||||
|
||||
type frame struct {
|
||||
Frame interface{}
|
||||
}
|
||||
|
||||
type streamType protocol.StreamType
|
||||
|
||||
func (s streamType) String() string {
|
||||
switch protocol.StreamType(s) {
|
||||
case protocol.StreamTypeUni:
|
||||
return "unidirectional"
|
||||
case protocol.StreamTypeBidi:
|
||||
return "bidirectional"
|
||||
default:
|
||||
panic("unknown stream type")
|
||||
}
|
||||
}
|
||||
|
||||
func escapeStr(str string) []byte { return []byte("\"" + str + "\"") }
|
||||
|
||||
type connectionID protocol.ConnectionID
|
||||
|
||||
func (c connectionID) MarshalJSON() ([]byte, error) {
|
||||
return escapeStr(fmt.Sprintf("%x", c)), nil
|
||||
}
|
||||
|
||||
type cryptoFrame struct {
|
||||
Offset protocol.ByteCount
|
||||
Length protocol.ByteCount
|
||||
}
|
||||
|
||||
type streamFrame struct {
|
||||
StreamID protocol.StreamID
|
||||
Offset protocol.ByteCount
|
||||
Length protocol.ByteCount
|
||||
FinBit bool
|
||||
}
|
||||
|
||||
func transformFrame(wf wire.Frame) *frame {
|
||||
// We don't want to store CRYPTO and STREAM frames, for multiple reasons:
|
||||
// * They both contain data, and we want to make this byte slice GC'able as soon as possible.
|
||||
// * STREAM frames use a slice from the buffer pool, which is released as soon as the frame is processed.
|
||||
switch f := wf.(type) {
|
||||
case *wire.CryptoFrame:
|
||||
return &frame{Frame: &cryptoFrame{
|
||||
Offset: f.Offset,
|
||||
Length: protocol.ByteCount(len(f.Data)),
|
||||
}}
|
||||
case *wire.StreamFrame:
|
||||
return &frame{Frame: &streamFrame{
|
||||
StreamID: f.StreamID,
|
||||
Offset: f.Offset,
|
||||
Length: f.DataLen(),
|
||||
FinBit: f.FinBit,
|
||||
}}
|
||||
default:
|
||||
return &frame{Frame: wf}
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON marshals to JSON
|
||||
func (f frame) MarshalJSON() ([]byte, error) {
|
||||
switch frame := f.Frame.(type) {
|
||||
case *wire.PingFrame:
|
||||
return marshalPingFrame(frame)
|
||||
case *wire.AckFrame:
|
||||
return marshalAckFrame(frame)
|
||||
case *wire.ResetStreamFrame:
|
||||
return marshalResetStreamFrame(frame)
|
||||
case *wire.StopSendingFrame:
|
||||
return marshalStopSendingFrame(frame)
|
||||
case *cryptoFrame:
|
||||
return marshalCryptoFrame(frame)
|
||||
case *wire.NewTokenFrame:
|
||||
return marshalNewTokenFrame(frame)
|
||||
case *streamFrame:
|
||||
return marshalStreamFrame(frame)
|
||||
case *wire.MaxDataFrame:
|
||||
return marshalMaxDataFrame(frame)
|
||||
case *wire.MaxStreamDataFrame:
|
||||
return marshalMaxStreamDataFrame(frame)
|
||||
case *wire.MaxStreamsFrame:
|
||||
return marshalMaxStreamsFrame(frame)
|
||||
case *wire.DataBlockedFrame:
|
||||
return marshalDataBlockedFrame(frame)
|
||||
case *wire.StreamDataBlockedFrame:
|
||||
return marshalStreamDataBlockedFrame(frame)
|
||||
case *wire.StreamsBlockedFrame:
|
||||
return marshalStreamsBlockedFrame(frame)
|
||||
case *wire.NewConnectionIDFrame:
|
||||
return marshalNewConnectionIDFrame(frame)
|
||||
case *wire.RetireConnectionIDFrame:
|
||||
return marshalRetireConnectionIDFrame(frame)
|
||||
case *wire.PathChallengeFrame:
|
||||
return marshalPathChallengeFrame(frame)
|
||||
case *wire.PathResponseFrame:
|
||||
return marshalPathResponseFrame(frame)
|
||||
case *wire.ConnectionCloseFrame:
|
||||
return marshalConnectionCloseFrame(frame)
|
||||
case *wire.HandshakeDoneFrame:
|
||||
return marshalHandshakeDoneFrame(frame)
|
||||
default:
|
||||
panic("unknown frame type")
|
||||
}
|
||||
}
|
||||
|
||||
func marshalPingFrame(_ *wire.PingFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
}{
|
||||
FrameType: "ping",
|
||||
})
|
||||
}
|
||||
|
||||
type ackRange struct {
|
||||
Smallest protocol.PacketNumber
|
||||
Largest protocol.PacketNumber
|
||||
}
|
||||
|
||||
func (ar ackRange) MarshalJSON() ([]byte, error) {
|
||||
if ar.Smallest == ar.Largest {
|
||||
return json.Marshal([]string{fmt.Sprintf("%d", ar.Smallest)})
|
||||
}
|
||||
return json.Marshal([]string{fmt.Sprintf("%d", ar.Smallest), fmt.Sprintf("%d", ar.Largest)})
|
||||
}
|
||||
|
||||
func marshalAckFrame(f *wire.AckFrame) ([]byte, error) {
|
||||
ranges := make([]ackRange, len(f.AckRanges))
|
||||
for i, r := range f.AckRanges {
|
||||
ranges[i] = ackRange{Smallest: r.Smallest, Largest: r.Largest}
|
||||
}
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
AckDelay int64 `json:"ack_delay,string,omitempty"`
|
||||
AckRanges []ackRange `json:"acked_ranges"`
|
||||
}{
|
||||
FrameType: "ack",
|
||||
AckDelay: f.DelayTime.Milliseconds(),
|
||||
AckRanges: ranges,
|
||||
})
|
||||
}
|
||||
|
||||
func marshalResetStreamFrame(f *wire.ResetStreamFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
StreamID protocol.StreamID `json:"stream_id,string"`
|
||||
ErrorCode protocol.ApplicationErrorCode `json:"error_code"`
|
||||
FinalSize protocol.ByteCount `json:"final_size,string"`
|
||||
}{
|
||||
FrameType: "reset_stream",
|
||||
StreamID: f.StreamID,
|
||||
ErrorCode: f.ErrorCode,
|
||||
FinalSize: f.ByteOffset,
|
||||
})
|
||||
}
|
||||
|
||||
func marshalStopSendingFrame(f *wire.StopSendingFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
StreamID protocol.StreamID `json:"stream_id,string"`
|
||||
ErrorCode protocol.ApplicationErrorCode `json:"error_code"`
|
||||
}{
|
||||
FrameType: "stop_sending",
|
||||
StreamID: f.StreamID,
|
||||
ErrorCode: f.ErrorCode,
|
||||
})
|
||||
}
|
||||
|
||||
func marshalCryptoFrame(f *cryptoFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
Offset protocol.ByteCount `json:"offset,string"`
|
||||
Length protocol.ByteCount `json:"length"`
|
||||
}{
|
||||
FrameType: "crypto",
|
||||
Offset: f.Offset,
|
||||
Length: f.Length,
|
||||
})
|
||||
}
|
||||
|
||||
func marshalNewTokenFrame(f *wire.NewTokenFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
Length int `json:"length"`
|
||||
Token string `json:"token"`
|
||||
}{
|
||||
FrameType: "new_token",
|
||||
Length: len(f.Token),
|
||||
Token: fmt.Sprintf("%x", f.Token),
|
||||
})
|
||||
}
|
||||
|
||||
func marshalStreamFrame(f *streamFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
StreamID protocol.StreamID `json:"stream_id,string"`
|
||||
Offset protocol.ByteCount `json:"offset,string"`
|
||||
Length protocol.ByteCount `json:"length"`
|
||||
Fin bool `json:"fin,omitempty"`
|
||||
}{
|
||||
FrameType: "stream",
|
||||
StreamID: f.StreamID,
|
||||
Offset: f.Offset,
|
||||
Length: f.Length,
|
||||
Fin: f.FinBit,
|
||||
})
|
||||
}
|
||||
|
||||
func marshalMaxDataFrame(f *wire.MaxDataFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
Maximum protocol.ByteCount `json:"maximum,string"`
|
||||
}{
|
||||
FrameType: "max_data",
|
||||
Maximum: f.ByteOffset,
|
||||
})
|
||||
}
|
||||
|
||||
func marshalMaxStreamDataFrame(f *wire.MaxStreamDataFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
StreamID protocol.StreamID `json:"stream_id,string"`
|
||||
Maximum protocol.ByteCount `json:"maximum,string"`
|
||||
}{
|
||||
FrameType: "max_stream_data",
|
||||
StreamID: f.StreamID,
|
||||
Maximum: f.ByteOffset,
|
||||
})
|
||||
}
|
||||
|
||||
func marshalMaxStreamsFrame(f *wire.MaxStreamsFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
StreamType string `json:"stream_type"`
|
||||
Maximum protocol.StreamNum `json:"maximum,string"`
|
||||
}{
|
||||
FrameType: "max_streams",
|
||||
StreamType: streamType(f.Type).String(),
|
||||
Maximum: f.MaxStreamNum,
|
||||
})
|
||||
}
|
||||
|
||||
func marshalDataBlockedFrame(f *wire.DataBlockedFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
Limit protocol.ByteCount `json:"limit,string"`
|
||||
}{
|
||||
FrameType: "data_blocked",
|
||||
Limit: f.DataLimit,
|
||||
})
|
||||
}
|
||||
|
||||
func marshalStreamDataBlockedFrame(f *wire.StreamDataBlockedFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
StreamID protocol.StreamID `json:"stream_id,string"`
|
||||
Limit protocol.ByteCount `json:"limit,string"`
|
||||
}{
|
||||
FrameType: "stream_data_blocked",
|
||||
StreamID: f.StreamID,
|
||||
Limit: f.DataLimit,
|
||||
})
|
||||
}
|
||||
|
||||
func marshalStreamsBlockedFrame(f *wire.StreamsBlockedFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
StreamType string `json:"stream_type"`
|
||||
Limit protocol.StreamNum `json:"limit,string"`
|
||||
}{
|
||||
FrameType: "streams_blocked",
|
||||
StreamType: streamType(f.Type).String(),
|
||||
Limit: f.StreamLimit,
|
||||
})
|
||||
}
|
||||
|
||||
func marshalNewConnectionIDFrame(f *wire.NewConnectionIDFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
SequenceNumber uint64 `json:"sequence_number,string"`
|
||||
RetirePriorTo uint64 `json:"retire_prior_to,string"`
|
||||
Length int `json:"length"`
|
||||
ConnectionID connectionID `json:"connection_id"`
|
||||
ResetToken string `json:"reset_token"`
|
||||
}{
|
||||
FrameType: "new_connection_id",
|
||||
SequenceNumber: f.SequenceNumber,
|
||||
RetirePriorTo: f.RetirePriorTo,
|
||||
Length: f.ConnectionID.Len(),
|
||||
ConnectionID: connectionID(f.ConnectionID),
|
||||
ResetToken: fmt.Sprintf("%x", f.StatelessResetToken),
|
||||
})
|
||||
}
|
||||
|
||||
func marshalRetireConnectionIDFrame(f *wire.RetireConnectionIDFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
SequenceNumber uint64 `json:"sequence_number,string"`
|
||||
}{
|
||||
FrameType: "retire_connection_id",
|
||||
SequenceNumber: f.SequenceNumber,
|
||||
})
|
||||
}
|
||||
|
||||
func marshalPathChallengeFrame(f *wire.PathChallengeFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
Data string `json:"data"`
|
||||
}{
|
||||
FrameType: "path_challenge",
|
||||
Data: fmt.Sprintf("%x", f.Data[:]),
|
||||
})
|
||||
}
|
||||
|
||||
func marshalPathResponseFrame(f *wire.PathResponseFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
Data string `json:"data"`
|
||||
}{
|
||||
FrameType: "path_response",
|
||||
Data: fmt.Sprintf("%x", f.Data[:]),
|
||||
})
|
||||
}
|
||||
|
||||
func marshalConnectionCloseFrame(f *wire.ConnectionCloseFrame) ([]byte, error) {
|
||||
errorSpace := "transport"
|
||||
if f.IsApplicationError {
|
||||
errorSpace = "application"
|
||||
}
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
ErrorSpace string `json:"error_space"`
|
||||
ErrorCode uint64 `json:"error_code"`
|
||||
RawErrorCode uint64 `json:"raw_error_code"`
|
||||
Reason string `json:"reason"`
|
||||
}{
|
||||
FrameType: "connection_close",
|
||||
ErrorSpace: errorSpace,
|
||||
ErrorCode: uint64(f.ErrorCode),
|
||||
RawErrorCode: uint64(f.ErrorCode),
|
||||
Reason: f.ReasonPhrase,
|
||||
})
|
||||
}
|
||||
|
||||
func marshalHandshakeDoneFrame(_ *wire.HandshakeDoneFrame) ([]byte, error) {
|
||||
return json.Marshal(struct {
|
||||
FrameType string `json:"frame_type"`
|
||||
}{
|
||||
FrameType: "handshake_done",
|
||||
})
|
||||
}
|
||||
367
qlog/frame_test.go
Normal file
367
qlog/frame_test.go
Normal file
@@ -0,0 +1,367 @@
|
||||
package qlog
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/wire"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Frames", func() {
|
||||
// marshal the frame
|
||||
check := func(f wire.Frame, expected map[string]interface{}) {
|
||||
data, err := transformFrame(f).MarshalJSON()
|
||||
ExpectWithOffset(1, err).ToNot(HaveOccurred())
|
||||
ExpectWithOffset(1, json.Valid(data)).To(BeTrue())
|
||||
// unmarshal the frame
|
||||
m := make(map[string](interface{}))
|
||||
ExpectWithOffset(1, json.Unmarshal(data, &m)).To(Succeed())
|
||||
ExpectWithOffset(1, m).To(HaveLen(len(expected)))
|
||||
for key, value := range expected {
|
||||
switch value.(type) {
|
||||
case string:
|
||||
ExpectWithOffset(1, m).To(HaveKeyWithValue(key, value))
|
||||
case int:
|
||||
ExpectWithOffset(1, m).To(HaveKeyWithValue(key, float64(value.(int))))
|
||||
case bool:
|
||||
ExpectWithOffset(1, m).To(HaveKeyWithValue(key, value.(bool)))
|
||||
case [][]string: // used in the ACK frame
|
||||
ExpectWithOffset(1, m).To(HaveKey(key))
|
||||
for i, l := range value.([][]string) {
|
||||
for j, s := range l {
|
||||
ExpectWithOffset(1, m[key].([]interface{})[i].([]interface{})[j].(string)).To(Equal(s))
|
||||
}
|
||||
}
|
||||
default:
|
||||
Fail("unexpected type")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
It("marshals PING frames", func() {
|
||||
check(
|
||||
&wire.PingFrame{},
|
||||
map[string]interface{}{
|
||||
"frame_type": "ping",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals ACK frames with a range acknowledging a single packet", func() {
|
||||
check(
|
||||
&wire.AckFrame{
|
||||
DelayTime: 86 * time.Millisecond,
|
||||
AckRanges: []wire.AckRange{{Smallest: 120, Largest: 120}},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "ack",
|
||||
"ack_delay": "86",
|
||||
"acked_ranges": [][]string{[]string{"120"}},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals ACK frames without a delay", func() {
|
||||
check(
|
||||
&wire.AckFrame{
|
||||
AckRanges: []wire.AckRange{{Smallest: 120, Largest: 120}},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "ack",
|
||||
"acked_ranges": [][]string{[]string{"120"}},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals ACK frames with a range acknowledging ranges of packets", func() {
|
||||
check(
|
||||
&wire.AckFrame{
|
||||
DelayTime: 86 * time.Millisecond,
|
||||
AckRanges: []wire.AckRange{
|
||||
{Smallest: 5, Largest: 50},
|
||||
{Smallest: 100, Largest: 120},
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "ack",
|
||||
"ack_delay": "86",
|
||||
"acked_ranges": [][]string{
|
||||
[]string{"5", "50"},
|
||||
[]string{"100", "120"},
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals RESET_STREAM frames", func() {
|
||||
check(
|
||||
&wire.ResetStreamFrame{
|
||||
StreamID: 987,
|
||||
ByteOffset: 1234,
|
||||
ErrorCode: 42,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "reset_stream",
|
||||
"stream_id": "987",
|
||||
"error_code": 42,
|
||||
"final_size": "1234",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals STOP_SENDING frames", func() {
|
||||
check(
|
||||
&wire.StopSendingFrame{
|
||||
StreamID: 987,
|
||||
ErrorCode: 42,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "stop_sending",
|
||||
"stream_id": "987",
|
||||
"error_code": 42,
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals CRYPTO frames", func() {
|
||||
check(
|
||||
&wire.CryptoFrame{
|
||||
Offset: 1337,
|
||||
Data: []byte("foobar"),
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "crypto",
|
||||
"offset": "1337",
|
||||
"length": 6,
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals NEW_TOKEN frames", func() {
|
||||
check(
|
||||
&wire.NewTokenFrame{
|
||||
Token: []byte{0xde, 0xad, 0xbe, 0xef},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "new_token",
|
||||
"length": 4,
|
||||
"token": "deadbeef",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals STREAM frames with FIN", func() {
|
||||
check(
|
||||
&wire.StreamFrame{
|
||||
StreamID: 42,
|
||||
Offset: 1337,
|
||||
FinBit: true,
|
||||
Data: []byte("foobar"),
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "stream",
|
||||
"stream_id": "42",
|
||||
"offset": "1337",
|
||||
"fin": true,
|
||||
"length": 6,
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals STREAM frames without FIN", func() {
|
||||
check(
|
||||
&wire.StreamFrame{
|
||||
StreamID: 42,
|
||||
Offset: 1337,
|
||||
Data: []byte("foo"),
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "stream",
|
||||
"stream_id": "42",
|
||||
"offset": "1337",
|
||||
"length": 3,
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals MAX_DATA frames", func() {
|
||||
check(
|
||||
&wire.MaxDataFrame{
|
||||
ByteOffset: 1337,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "max_data",
|
||||
"maximum": "1337",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals MAX_STREAM_DATA frames", func() {
|
||||
check(
|
||||
&wire.MaxStreamDataFrame{
|
||||
StreamID: 1234,
|
||||
ByteOffset: 1337,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "max_stream_data",
|
||||
"stream_id": "1234",
|
||||
"maximum": "1337",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals MAX_STREAMS frames", func() {
|
||||
check(
|
||||
&wire.MaxStreamsFrame{
|
||||
Type: protocol.StreamTypeBidi,
|
||||
MaxStreamNum: 42,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "max_streams",
|
||||
"stream_type": "bidirectional",
|
||||
"maximum": "42",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals DATA_BLOCKED frames", func() {
|
||||
check(
|
||||
&wire.DataBlockedFrame{
|
||||
DataLimit: 1337,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "data_blocked",
|
||||
"limit": "1337",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals STREAM_DATA_BLOCKED frames", func() {
|
||||
check(
|
||||
&wire.StreamDataBlockedFrame{
|
||||
StreamID: 42,
|
||||
DataLimit: 1337,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "stream_data_blocked",
|
||||
"stream_id": "42",
|
||||
"limit": "1337",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals STREAMS_BLOCKED frames", func() {
|
||||
check(
|
||||
&wire.StreamsBlockedFrame{
|
||||
Type: protocol.StreamTypeUni,
|
||||
StreamLimit: 123,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "streams_blocked",
|
||||
"stream_type": "unidirectional",
|
||||
"limit": "123",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals NEW_CONNECTION_ID frames", func() {
|
||||
check(
|
||||
&wire.NewConnectionIDFrame{
|
||||
SequenceNumber: 42,
|
||||
RetirePriorTo: 24,
|
||||
ConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef},
|
||||
StatelessResetToken: [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "new_connection_id",
|
||||
"sequence_number": "42",
|
||||
"retire_prior_to": "24",
|
||||
"length": 4,
|
||||
"connection_id": "deadbeef",
|
||||
"reset_token": "000102030405060708090a0b0c0d0e0f",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals RETIRE_CONNECTION_ID frames", func() {
|
||||
check(
|
||||
&wire.RetireConnectionIDFrame{
|
||||
SequenceNumber: 1337,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "retire_connection_id",
|
||||
"sequence_number": "1337",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals PATH_CHALLENGE frames", func() {
|
||||
check(
|
||||
&wire.PathChallengeFrame{
|
||||
Data: [8]byte{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xc0, 0x01},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "path_challenge",
|
||||
"data": "deadbeefcafec001",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals PATH_RESPONSE frames", func() {
|
||||
check(
|
||||
&wire.PathResponseFrame{
|
||||
Data: [8]byte{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xc0, 0x01},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "path_response",
|
||||
"data": "deadbeefcafec001",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals CONNECTION_CLOSE frames, for application error codes", func() {
|
||||
check(
|
||||
&wire.ConnectionCloseFrame{
|
||||
IsApplicationError: true,
|
||||
ErrorCode: 1337,
|
||||
ReasonPhrase: "lorem ipsum",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "connection_close",
|
||||
"error_space": "application",
|
||||
"error_code": 1337,
|
||||
"raw_error_code": 1337,
|
||||
"reason": "lorem ipsum",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals CONNECTION_CLOSE frames, for transport error codes", func() {
|
||||
check(
|
||||
&wire.ConnectionCloseFrame{
|
||||
ErrorCode: 1337,
|
||||
ReasonPhrase: "lorem ipsum",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"frame_type": "connection_close",
|
||||
"error_space": "transport",
|
||||
"error_code": 1337,
|
||||
"raw_error_code": 1337,
|
||||
"reason": "lorem ipsum",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals HANDSHAKE_DONE frames", func() {
|
||||
check(
|
||||
&wire.HandshakeDoneFrame{},
|
||||
map[string]interface{}{
|
||||
"frame_type": "handshake_done",
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
13
qlog/qlog_suite_test.go
Normal file
13
qlog/qlog_suite_test.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package qlog
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestQlog(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "qlog Suite")
|
||||
}
|
||||
Reference in New Issue
Block a user