forked from quic-go/quic-go
implement marshalling of packet headers
This commit is contained in:
@@ -12,34 +12,11 @@ import (
|
||||
)
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
checkEncoding(data, expected)
|
||||
}
|
||||
|
||||
It("marshals PING frames", func() {
|
||||
|
||||
54
qlog/packet_header.go
Normal file
54
qlog/packet_header.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package qlog
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/internal/protocol"
|
||||
"github.com/lucas-clemente/quic-go/internal/wire"
|
||||
)
|
||||
|
||||
type versionNumber protocol.VersionNumber
|
||||
|
||||
func (v versionNumber) MarshalJSON() ([]byte, error) {
|
||||
return escapeStr(fmt.Sprintf("%x", v)), nil
|
||||
}
|
||||
|
||||
func transformHeader(hdr *wire.ExtendedHeader) *packetHeader {
|
||||
return &packetHeader{
|
||||
PacketNumber: hdr.PacketNumber,
|
||||
PayloadLength: hdr.Length,
|
||||
SrcConnectionID: hdr.SrcConnectionID,
|
||||
DestConnectionID: hdr.DestConnectionID,
|
||||
Version: hdr.Version,
|
||||
}
|
||||
}
|
||||
|
||||
type packetHeader struct {
|
||||
PacketNumber protocol.PacketNumber `json:"packet_number,string"`
|
||||
PacketSize protocol.ByteCount `json:"packet_size,omitempty"`
|
||||
PayloadLength protocol.ByteCount `json:"payload_length,omitempty"`
|
||||
|
||||
Version protocol.VersionNumber `json:"version,omitempty"`
|
||||
SrcConnectionID protocol.ConnectionID `json:"scid,string,omitempty"`
|
||||
DestConnectionID protocol.ConnectionID `json:"dcid,string,omitempty"`
|
||||
}
|
||||
|
||||
func (h packetHeader) MarshalJSON() ([]byte, error) {
|
||||
type Alias packetHeader
|
||||
return json.Marshal(&struct {
|
||||
SrcConnectionIDLen int `json:"scil,string,omitempty"`
|
||||
SrcConnectionID connectionID `json:"scid,string,omitempty"`
|
||||
DestConnectionIDLen int `json:"dcil,string,omitempty"`
|
||||
DestConnectionID connectionID `json:"dcid,string,omitempty"`
|
||||
Version versionNumber `json:"version,omitempty"`
|
||||
Alias
|
||||
}{
|
||||
Alias: (Alias)(h),
|
||||
SrcConnectionIDLen: h.SrcConnectionID.Len(),
|
||||
SrcConnectionID: connectionID(h.SrcConnectionID),
|
||||
DestConnectionIDLen: h.DestConnectionID.Len(),
|
||||
DestConnectionID: connectionID(h.DestConnectionID),
|
||||
Version: versionNumber(h.Version),
|
||||
})
|
||||
}
|
||||
85
qlog/packet_header_test.go
Normal file
85
qlog/packet_header_test.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package qlog
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"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("Packet Header", func() {
|
||||
check := func(hdr *wire.ExtendedHeader, expected map[string]interface{}) {
|
||||
data, err := json.Marshal(transformHeader(hdr))
|
||||
ExpectWithOffset(1, err).ToNot(HaveOccurred())
|
||||
ExpectWithOffset(1, json.Valid(data)).To(BeTrue())
|
||||
checkEncoding(data, expected)
|
||||
}
|
||||
|
||||
It("marshals a header", func() {
|
||||
check(
|
||||
&wire.ExtendedHeader{PacketNumber: 42},
|
||||
map[string]interface{}{
|
||||
"packet_number": "42",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals a header with a payload length", func() {
|
||||
check(
|
||||
&wire.ExtendedHeader{
|
||||
PacketNumber: 42,
|
||||
Header: wire.Header{Length: 123},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"packet_number": "42",
|
||||
"payload_length": 123,
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals a header with a source connection ID", func() {
|
||||
check(
|
||||
&wire.ExtendedHeader{
|
||||
PacketNumber: 42,
|
||||
Header: wire.Header{
|
||||
SrcConnectionID: protocol.ConnectionID{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
|
||||
},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"packet_number": "42",
|
||||
"scil": "16",
|
||||
"scid": "00112233445566778899aabbccddeeff",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals a header with a destination connection ID", func() {
|
||||
check(
|
||||
&wire.ExtendedHeader{
|
||||
PacketNumber: 42,
|
||||
Header: wire.Header{DestConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"packet_number": "42",
|
||||
"dcil": "4",
|
||||
"dcid": "deadbeef",
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
It("marshals a header with a version number", func() {
|
||||
check(
|
||||
&wire.ExtendedHeader{
|
||||
PacketNumber: 42,
|
||||
Header: wire.Header{Version: protocol.VersionNumber(0xdecafbad)},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"packet_number": "42",
|
||||
"version": "decafbad",
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -1,6 +1,7 @@
|
||||
package qlog
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
@@ -11,3 +12,29 @@ func TestQlog(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "qlog Suite")
|
||||
}
|
||||
|
||||
func checkEncoding(data []byte, expected map[string](interface{})) {
|
||||
// unmarshal the data
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user