github.com/searKing/golang/go@v1.2.117/net/http/warn.go (about) 1 // Copyright 2023 The searKing Author. 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 package http 6 7 import ( 8 "fmt" 9 "io" 10 "net/http" 11 "strconv" 12 "strings" 13 "time" 14 ) 15 16 // HTTP warn codes as registered with IANA. 17 // See: https://www.iana.org/assignments/http-warn-codes/http-warn-codes.xhtml 18 // See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Warning#warning_codes 19 // Deprecated: The "Warning" header field was used to carry additional information about 20 // the status or transformation of a message that might not be reflected in the status code. 21 // This specification obsoletes it, as it is not widely generated or surfaced to users. 22 // The information it carried can be gleaned from examining other header fields, such as Age. 23 // See: https://www.rfc-editor.org/rfc/rfc9111.html#name-warning 24 const ( 25 WarnResponseIsStale = 110 // RFC 7234, 5.5.1 26 WarnRevalidationFailed = 111 // RFC 7234, 5.5.2 27 WarnDisconnectedOperation = 112 // RFC 7234, 5.5.3 28 WarnHeuristicExpiration = 113 // RFC 7234, 5.5.4 29 WarnMiscellaneousWarning = 199 // RFC 7234, 5.5.5 30 WarnTransformationApplied = 214 // RFC 7234, 5.5.6 31 WarnMiscellaneousPersistentWarning = 299 // RFC 7234, 5.5.7 32 ) 33 34 // WarnText returns a text for the HTTP warn code. It returns the empty 35 // string if the code is unknown. 36 func WarnText(code int) string { 37 switch code { 38 case WarnResponseIsStale: 39 return "Response is Stale" 40 case WarnRevalidationFailed: 41 return "Revalidation Failed" 42 case WarnDisconnectedOperation: 43 return "Disconnected Operation" 44 case WarnHeuristicExpiration: 45 return "Heuristic Expiration" 46 case WarnMiscellaneousWarning: 47 return "Miscellaneous Warning" 48 case WarnTransformationApplied: 49 return "Transformation Applied" 50 case WarnMiscellaneousPersistentWarning: 51 return "Miscellaneous Persistent Warning" 52 default: 53 return "" 54 } 55 } 56 57 type Warn struct { 58 Warn string // e.g. "200 OK" 59 WarnCode int // e.g. 200 60 Agent string // e.g. "-" 61 Date time.Time 62 } 63 64 func (r Warn) String() string { 65 var buf strings.Builder 66 _ = r.Write(&buf) 67 return buf.String() 68 } 69 70 func (r Warn) Write(w io.Writer) error { 71 // Status line 72 text := r.Warn 73 if text == "" { 74 text = WarnText(r.WarnCode) 75 if text == "" { 76 text = "warn code " + strconv.Itoa(r.WarnCode) 77 } 78 } else { 79 // Just to reduce stutter, if user set w.Warn to "112 Disconnected Operation" and WarnCode to 112. 80 // Not important. 81 text = strings.TrimPrefix(text, strconv.Itoa(r.WarnCode)+" ") 82 } 83 84 agent := r.Agent 85 if agent == "" { 86 agent = "-" 87 } 88 89 // See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Warning#syntax 90 // Warning: <warn-code> <warn-agent> <warn-text> [<warn-date>] 91 // Warning: 110 anderson/1.3.37 "Response is stale" 92 // Date: Wed, 21 Oct 2015 07:28:00 GMT 93 // Warning: 112 - "cache down" "Wed, 21 Oct 2015 07:28:00 GMT" 94 if _, err := fmt.Fprintf(w, "%03d %s %q", r.WarnCode, agent, text); err != nil { 95 return err 96 } 97 r.Date.IsZero() 98 if !r.Date.IsZero() { 99 if _, err := fmt.Fprintf(w, " %q", r.Date.UTC().Format(http.TimeFormat)); err != nil { 100 return err 101 } 102 } 103 return nil 104 }