blob: 0efa8e558cf565a1512b6f36b450ff93857eaf4a [file] [log] [blame]
Tomasz Jezierski84c13af2022-09-26 23:18:22 +02001// Copyright 2022 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build ignore
Tomasz Jezierski84c13af2022-09-26 23:18:22 +02006
7package main
8
9import (
10 "bytes"
11 "fmt"
12 "go/format"
Tomasz Jezierski84c13af2022-09-26 23:18:22 +020013 "os"
14 "sort"
15
16 "golang.org/x/net/http2/hpack"
17)
18
19// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B
20var staticTableEntries = [...]hpack.HeaderField{
21 {Name: ":authority"},
22 {Name: ":method", Value: "GET"},
23 {Name: ":method", Value: "POST"},
24 {Name: ":path", Value: "/"},
25 {Name: ":path", Value: "/index.html"},
26 {Name: ":scheme", Value: "http"},
27 {Name: ":scheme", Value: "https"},
28 {Name: ":status", Value: "200"},
29 {Name: ":status", Value: "204"},
30 {Name: ":status", Value: "206"},
31 {Name: ":status", Value: "304"},
32 {Name: ":status", Value: "400"},
33 {Name: ":status", Value: "404"},
34 {Name: ":status", Value: "500"},
35 {Name: "accept-charset"},
36 {Name: "accept-encoding", Value: "gzip, deflate"},
37 {Name: "accept-language"},
38 {Name: "accept-ranges"},
39 {Name: "accept"},
40 {Name: "access-control-allow-origin"},
41 {Name: "age"},
42 {Name: "allow"},
43 {Name: "authorization"},
44 {Name: "cache-control"},
45 {Name: "content-disposition"},
46 {Name: "content-encoding"},
47 {Name: "content-language"},
48 {Name: "content-length"},
49 {Name: "content-location"},
50 {Name: "content-range"},
51 {Name: "content-type"},
52 {Name: "cookie"},
53 {Name: "date"},
54 {Name: "etag"},
55 {Name: "expect"},
56 {Name: "expires"},
57 {Name: "from"},
58 {Name: "host"},
59 {Name: "if-match"},
60 {Name: "if-modified-since"},
61 {Name: "if-none-match"},
62 {Name: "if-range"},
63 {Name: "if-unmodified-since"},
64 {Name: "last-modified"},
65 {Name: "link"},
66 {Name: "location"},
67 {Name: "max-forwards"},
68 {Name: "proxy-authenticate"},
69 {Name: "proxy-authorization"},
70 {Name: "range"},
71 {Name: "referer"},
72 {Name: "refresh"},
73 {Name: "retry-after"},
74 {Name: "server"},
75 {Name: "set-cookie"},
76 {Name: "strict-transport-security"},
77 {Name: "transfer-encoding"},
78 {Name: "user-agent"},
79 {Name: "vary"},
80 {Name: "via"},
81 {Name: "www-authenticate"},
82}
83
84type pairNameValue struct {
85 name, value string
86}
87
88type byNameItem struct {
89 name string
90 id uint64
91}
92
93type byNameValueItem struct {
94 pairNameValue
95 id uint64
96}
97
98func headerFieldToString(f hpack.HeaderField) string {
99 return fmt.Sprintf("{Name: \"%s\", Value:\"%s\", Sensitive: %t}", f.Name, f.Value, f.Sensitive)
100}
101
102func pairNameValueToString(v pairNameValue) string {
103 return fmt.Sprintf("{name: \"%s\", value:\"%s\"}", v.name, v.value)
104}
105
106const header = `
107// go generate gen.go
108// Code generated by the command above; DO NOT EDIT.
109
110package hpack
111
112var staticTable = &headerFieldTable{
113 evictCount: 0,
114 byName: map[string]uint64{
115`
116
117//go:generate go run gen.go
118func main() {
119 var bb bytes.Buffer
120 fmt.Fprintf(&bb, header)
121 byName := make(map[string]uint64)
122 byNameValue := make(map[pairNameValue]uint64)
123 for index, entry := range staticTableEntries {
124 id := uint64(index) + 1
125 byName[entry.Name] = id
126 byNameValue[pairNameValue{entry.Name, entry.Value}] = id
127 }
128 // Sort maps for deterministic generation.
129 byNameItems := sortByName(byName)
130 byNameValueItems := sortByNameValue(byNameValue)
131
132 for _, item := range byNameItems {
133 fmt.Fprintf(&bb, "\"%s\":%d,\n", item.name, item.id)
134 }
135 fmt.Fprintf(&bb, "},\n")
136 fmt.Fprintf(&bb, "byNameValue: map[pairNameValue]uint64{\n")
137 for _, item := range byNameValueItems {
138 fmt.Fprintf(&bb, "%s:%d,\n", pairNameValueToString(item.pairNameValue), item.id)
139 }
140 fmt.Fprintf(&bb, "},\n")
141 fmt.Fprintf(&bb, "ents: []HeaderField{\n")
142 for _, value := range staticTableEntries {
143 fmt.Fprintf(&bb, "%s,\n", headerFieldToString(value))
144 }
145 fmt.Fprintf(&bb, "},\n")
146 fmt.Fprintf(&bb, "}\n")
147 genFile("static_table.go", &bb)
148}
149
150func sortByNameValue(byNameValue map[pairNameValue]uint64) []byNameValueItem {
151 var byNameValueItems []byNameValueItem
152 for k, v := range byNameValue {
153 byNameValueItems = append(byNameValueItems, byNameValueItem{k, v})
154 }
155 sort.Slice(byNameValueItems, func(i, j int) bool {
156 return byNameValueItems[i].id < byNameValueItems[j].id
157 })
158 return byNameValueItems
159}
160
161func sortByName(byName map[string]uint64) []byNameItem {
162 var byNameItems []byNameItem
163 for k, v := range byName {
164 byNameItems = append(byNameItems, byNameItem{k, v})
165 }
166 sort.Slice(byNameItems, func(i, j int) bool {
167 return byNameItems[i].id < byNameItems[j].id
168 })
169 return byNameItems
170}
171
172func genFile(name string, buf *bytes.Buffer) {
173 b, err := format.Source(buf.Bytes())
174 if err != nil {
175 fmt.Fprintln(os.Stderr, err)
176 os.Exit(1)
177 }
Damien Neilc1f58332024-05-18 08:16:13 -0700178 if err := os.WriteFile(name, b, 0644); err != nil {
Tomasz Jezierski84c13af2022-09-26 23:18:22 +0200179 fmt.Fprintln(os.Stderr, err)
180 os.Exit(1)
181 }
182}