Serialize HTTP1.x headers by base64-encoding each header name and value, and then joining them in the format of [key:value;]
(h1Headers http.Header)
| 67 | // Serialize HTTP1.x headers by base64-encoding each header name and value, |
| 68 | // and then joining them in the format of [key:value;] |
| 69 | func SerializeHeaders(h1Headers http.Header) string { |
| 70 | // compute size of the fully serialized value and largest temp buffer we will need |
| 71 | serializedLen := 0 |
| 72 | maxTempLen := 0 |
| 73 | for headerName, headerValues := range h1Headers { |
| 74 | for _, headerValue := range headerValues { |
| 75 | nameLen := headerEncoding.EncodedLen(len(headerName)) |
| 76 | valueLen := headerEncoding.EncodedLen(len(headerValue)) |
| 77 | const delims = 2 |
| 78 | serializedLen += delims + nameLen + valueLen |
| 79 | if nameLen > maxTempLen { |
| 80 | maxTempLen = nameLen |
| 81 | } |
| 82 | if valueLen > maxTempLen { |
| 83 | maxTempLen = valueLen |
| 84 | } |
| 85 | } |
| 86 | } |
| 87 | var buf strings.Builder |
| 88 | buf.Grow(serializedLen) |
| 89 | |
| 90 | temp := make([]byte, maxTempLen) |
| 91 | writeB64 := func(s string) { |
| 92 | n := headerEncoding.EncodedLen(len(s)) |
| 93 | if n > len(temp) { |
| 94 | temp = make([]byte, n) |
| 95 | } |
| 96 | headerEncoding.Encode(temp[:n], []byte(s)) |
| 97 | buf.Write(temp[:n]) |
| 98 | } |
| 99 | |
| 100 | for headerName, headerValues := range h1Headers { |
| 101 | for _, headerValue := range headerValues { |
| 102 | if buf.Len() > 0 { |
| 103 | buf.WriteByte(';') |
| 104 | } |
| 105 | writeB64(headerName) |
| 106 | buf.WriteByte(':') |
| 107 | writeB64(headerValue) |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | return buf.String() |
| 112 | } |
| 113 | |
| 114 | // Deserialize headers serialized by `SerializeHeader` |
| 115 | func DeserializeHeaders(serializedHeaders string) ([]HTTPHeader, error) { |