File: interop_test.go

package info (click to toggle)
golang-github-marten-seemann-qpack 0.2.1%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 192 kB
  • sloc: sh: 63; makefile: 3
file content (92 lines) | stat: -rw-r--r-- 2,391 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package interop

import (
	"encoding/binary"
	"fmt"
	"io"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/marten-seemann/qpack"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

func currentDir() string {
	_, filename, _, ok := runtime.Caller(0)
	if !ok {
		panic("Failed to get current frame")
	}
	return path.Dir(filename)
}

var _ = Describe("Interop", func() {
	// find all encoded files with a dynamic table size of 0
	findFiles := func() []string {
		var files []string
		encodedDir := currentDir() + "/qifs/encoded/qpack-06/"
		filepath.Walk(encodedDir, func(path string, info os.FileInfo, err error) error {
			if info.IsDir() {
				return nil
			}
			_, file := filepath.Split(path)
			split := strings.Split(file, ".")
			tableSize := split[len(split)-3]
			if tableSize == "0" {
				files = append(files, path)
			}
			return nil
		})
		return files
	}

	parseInput := func(r io.Reader) (uint64 /* stream ID */, []byte) {
		prefix := make([]byte, 12)
		_, err := io.ReadFull(r, prefix)
		Expect(err).ToNot(HaveOccurred())
		streamID := binary.BigEndian.Uint64(prefix[:8])
		length := binary.BigEndian.Uint32(prefix[8:12])
		if length > (1 << 15) { // DoS prevention
			Fail("input too long")
		}
		data := make([]byte, int(length))
		_, err = io.ReadFull(r, data)
		Expect(err).ToNot(HaveOccurred())
		return streamID, data
	}

	filenames := findFiles()
	for i := range filenames {
		path := filenames[i]
		fpath, filename := filepath.Split(path)
		prettyPath := path[len(filepath.Dir(filepath.Dir(filepath.Dir(fpath))))+1:]

		It(fmt.Sprintf("using %s", prettyPath), func() {
			qif, ok := qifs[strings.Split(filename, ".")[0]]
			Expect(ok).To(BeTrue())

			file, err := os.Open(path)
			var headers []qpack.HeaderField
			decoder := qpack.NewDecoder(func(hf qpack.HeaderField) {
				headers = append(headers, hf)
			})
			var numRequests, numHeaderFields int
			Expect(qif.requests).ToNot(BeEmpty())
			for _, req := range qif.requests {
				Expect(err).ToNot(HaveOccurred())
				_, data := parseInput(file)
				_, err = decoder.Write(data)
				Expect(err).ToNot(HaveOccurred())
				Expect(headers).To(Equal(req.headers))
				numRequests++
				numHeaderFields += len(headers)
				headers = nil
				decoder.Close()
			}
			fmt.Fprintf(GinkgoWriter, "Decoded %d requests containing %d header fields.\n", len(qif.requests), numHeaderFields)
		})
	}
})