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