canonicalMIMEHeaderKey is like CanonicalMIMEHeaderKey but is allowed to mutate the provided byte slice before returning the string. For invalid inputs (if a contains spaces or non-token bytes), a is unchanged and a string copy is returned. ok is true if the header key contains only valid character
(a []byte)
| 378 | // ReadMIMEHeader accepts header keys containing spaces, but does not |
| 379 | // canonicalize them. |
| 380 | func canonicalMIMEHeaderKey(a []byte) (_ string, ok bool) { |
| 381 | if len(a) == 0 { |
| 382 | return "", false |
| 383 | } |
| 384 | |
| 385 | // See if a looks like a header key. If not, return it unchanged. |
| 386 | noCanon := false |
| 387 | for _, c := range a { |
| 388 | if validHeaderFieldByte(c) { |
| 389 | continue |
| 390 | } |
| 391 | // Don't canonicalize. |
| 392 | if c == ' ' { |
| 393 | // We accept invalid headers with a space before the |
| 394 | // colon, but must not canonicalize them. |
| 395 | // See https://go.dev/issue/34540. |
| 396 | noCanon = true |
| 397 | continue |
| 398 | } |
| 399 | return string(a), false |
| 400 | } |
| 401 | if noCanon { |
| 402 | return string(a), true |
| 403 | } |
| 404 | |
| 405 | upper := true |
| 406 | for i, c := range a { |
| 407 | // Canonicalize: first letter upper case |
| 408 | // and upper case after each dash. |
| 409 | // (Host, User-Agent, If-Modified-Since). |
| 410 | // MIME headers are ASCII only, so no Unicode issues. |
| 411 | if upper && 'a' <= c && c <= 'z' { |
| 412 | c -= toLower |
| 413 | } else if !upper && 'A' <= c && c <= 'Z' { |
| 414 | c += toLower |
| 415 | } |
| 416 | a[i] = c |
| 417 | upper = c == '-' // for next time |
| 418 | } |
| 419 | commonHeaderOnce.Do(initCommonHeader) |
| 420 | // The compiler recognizes m[string(byteSlice)] as a special |
| 421 | // case, so a copy of a's bytes into a new string does not |
| 422 | // happen in this map lookup: |
| 423 | if v := commonHeader[string(a)]; v != "" { |
| 424 | return v, true |
| 425 | } |
| 426 | return string(a), true |
| 427 | } |
| 428 | |
| 429 | // validHeaderValueByte reports whether c is a valid byte in a header |
| 430 | // field value. RFC 7230 says: |
no test coverage detected
searching dependent graphs…