[mirror] Scalable static site server for Git forges (like GitHub Pages)

Rename HTTP negotiation items. NFC

+23 -21
+15 -15
src/http.go
··· 8 "strings" 9 ) 10 11 - var httpAcceptEncodingRegexp = regexp.MustCompile(`` + 12 // token optionally prefixed by whitespace 13 `^[ \t]*([a-zA-Z0-9$!#$%&'*+.^_\x60|~-]+)` + 14 // quality value prefixed by a semicolon optionally surrounded by whitespace ··· 17 `[ \t]*(?:,|$)`, 18 ) 19 20 - type httpEncoding struct { 21 code string 22 qval float64 23 } 24 25 - type httpEncodings struct { 26 - encodings []httpEncoding 27 } 28 29 - func parseHTTPEncodings(headerValue string) (result httpEncodings) { 30 for headerValue != "" { 31 - matches := httpAcceptEncodingRegexp.FindStringSubmatch(headerValue) 32 if matches == nil { 33 - return httpEncodings{} 34 } 35 - enc := httpEncoding{strings.ToLower(matches[1]), 1.0} 36 if matches[2] != "" { 37 enc.qval, _ = strconv.ParseFloat(matches[2], 64) 38 } ··· 51 52 // Negotiate returns the most preferred encoding that is acceptable by the 53 // client, or an empty string if no encodings are acceptable. 54 - func (e *httpEncodings) Negotiate(codes ...string) string { 55 - prefs := make(map[string]float64, len(codes)) 56 - for _, code := range codes { 57 prefs[code] = 0 58 } 59 implicitIdentity := true ··· 73 if _, ok := prefs["identity"]; ok && implicitIdentity { 74 prefs["identity"] = -1 // sort last 75 } 76 - encs := make([]httpEncoding, len(codes)) 77 - for idx, code := range codes { 78 - encs[idx] = httpEncoding{code, prefs[code]} 79 } 80 - slices.SortStableFunc(encs, func(a, b httpEncoding) int { 81 return -cmp.Compare(a.qval, b.qval) 82 }) 83 for _, enc := range encs {
··· 8 "strings" 9 ) 10 11 + var httpAcceptRegexp = regexp.MustCompile(`` + 12 // token optionally prefixed by whitespace 13 `^[ \t]*([a-zA-Z0-9$!#$%&'*+.^_\x60|~-]+)` + 14 // quality value prefixed by a semicolon optionally surrounded by whitespace ··· 17 `[ \t]*(?:,|$)`, 18 ) 19 20 + type httpAcceptOffer struct { 21 code string 22 qval float64 23 } 24 25 + type HTTPEncodings struct { 26 + encodings []httpAcceptOffer 27 } 28 29 + func ParseHTTPAcceptEncoding(headerValue string) (result HTTPEncodings) { 30 for headerValue != "" { 31 + matches := httpAcceptRegexp.FindStringSubmatch(headerValue) 32 if matches == nil { 33 + return HTTPEncodings{} 34 } 35 + enc := httpAcceptOffer{strings.ToLower(matches[1]), 1.0} 36 if matches[2] != "" { 37 enc.qval, _ = strconv.ParseFloat(matches[2], 64) 38 } ··· 51 52 // Negotiate returns the most preferred encoding that is acceptable by the 53 // client, or an empty string if no encodings are acceptable. 54 + func (e *HTTPEncodings) Negotiate(offers ...string) string { 55 + prefs := make(map[string]float64, len(offers)) 56 + for _, code := range offers { 57 prefs[code] = 0 58 } 59 implicitIdentity := true ··· 73 if _, ok := prefs["identity"]; ok && implicitIdentity { 74 prefs["identity"] = -1 // sort last 75 } 76 + encs := make([]httpAcceptOffer, len(offers)) 77 + for idx, code := range offers { 78 + encs[idx] = httpAcceptOffer{code, prefs[code]} 79 } 80 + slices.SortStableFunc(encs, func(a, b httpAcceptOffer) int { 81 return -cmp.Compare(a.qval, b.qval) 82 }) 83 for _, enc := range encs {
+8 -6
src/pages.go
··· 214 215 // we only offer `/.git-pages/archive.tar` and not the `.tar.gz`/`.tar.zst` variants 216 // because HTTP can already request compression using the `Content-Encoding` mechanism 217 - acceptedEncodings := parseHTTPEncodings(r.Header.Get("Accept-Encoding")) 218 negotiated := acceptedEncodings.Negotiate("zstd", "gzip", "identity") 219 if negotiated != "" { 220 w.Header().Set("Content-Encoding", negotiated) ··· 322 defer closer.Close() 323 } 324 325 - acceptedEncodings := parseHTTPEncodings(r.Header.Get("Accept-Encoding")) 326 negotiatedEncoding := true 327 switch entry.GetTransform() { 328 case Transform_Identity: 329 - switch acceptedEncodings.Negotiate("identity") { 330 case "identity": 331 serveEncodingCount. 332 With(prometheus.Labels{"transform": "identity", "negotiated": "identity"}). ··· 338 Inc() 339 } 340 case Transform_Zstd: 341 - supported := []string{"zstd", "identity"} 342 if entry.ContentType == nil { 343 // If Content-Type is unset, `http.ServeContent` will try to sniff 344 // the file contents. That won't work if it's compressed. 345 - supported = []string{"identity"} 346 } 347 - switch acceptedEncodings.Negotiate(supported...) { 348 case "zstd": 349 // Set Content-Length ourselves since `http.ServeContent` only sets 350 // it if Content-Encoding is unset or if it's a range request.
··· 214 215 // we only offer `/.git-pages/archive.tar` and not the `.tar.gz`/`.tar.zst` variants 216 // because HTTP can already request compression using the `Content-Encoding` mechanism 217 + acceptedEncodings := ParseHTTPAcceptEncoding(r.Header.Get("Accept-Encoding")) 218 negotiated := acceptedEncodings.Negotiate("zstd", "gzip", "identity") 219 if negotiated != "" { 220 w.Header().Set("Content-Encoding", negotiated) ··· 322 defer closer.Close() 323 } 324 325 + offeredEncodings := []string{} 326 + acceptedEncodings := ParseHTTPAcceptEncoding(r.Header.Get("Accept-Encoding")) 327 negotiatedEncoding := true 328 switch entry.GetTransform() { 329 case Transform_Identity: 330 + offeredEncodings = []string{"identity"} 331 + switch acceptedEncodings.Negotiate(offeredEncodings...) { 332 case "identity": 333 serveEncodingCount. 334 With(prometheus.Labels{"transform": "identity", "negotiated": "identity"}). ··· 340 Inc() 341 } 342 case Transform_Zstd: 343 + offeredEncodings = []string{"zstd", "identity"} 344 if entry.ContentType == nil { 345 // If Content-Type is unset, `http.ServeContent` will try to sniff 346 // the file contents. That won't work if it's compressed. 347 + offeredEncodings = []string{"identity"} 348 } 349 + switch acceptedEncodings.Negotiate(offeredEncodings...) { 350 case "zstd": 351 // Set Content-Length ourselves since `http.ServeContent` only sets 352 // it if Content-Encoding is unset or if it's a range request.