@@ -82,6 +82,14 @@ type RequestHeader struct {
8282 userAgent []byte
8383 mulHeader [][]byte
8484
85+ explicitHost bool
86+ explicitUserAgent bool
87+ explicitContentType bool
88+ explicitContentLength bool
89+ explicitCookies bool
90+ explicitTrailer bool
91+ explicitConnection bool
92+
8593 h []argsKV
8694 trailer []argsKV
8795 bufKV argsKV
@@ -1134,33 +1142,47 @@ func (h *RequestHeader) VisitAllCookie(f func(key, value []byte)) {
11341142//
11351143// To get the headers in order they were received use VisitAllInOrder.
11361144func (h * RequestHeader ) VisitAll (f func (key , value []byte )) {
1137- host := h .Host ()
1138- if len (host ) > 0 {
1139- f (strHost , host )
1145+ if ! h .explicitHost {
1146+ host := h .Host ()
1147+ if len (host ) > 0 {
1148+ f (strHost , host )
1149+ }
11401150 }
1141- if len (h .contentLengthBytes ) > 0 {
1142- f (strContentLength , h .contentLengthBytes )
1151+ if ! h .explicitContentLength {
1152+ if len (h .contentLengthBytes ) > 0 {
1153+ f (strContentLength , h .contentLengthBytes )
1154+ }
11431155 }
1144- contentType := h .ContentType ()
1145- if len (contentType ) > 0 {
1146- f (strContentType , contentType )
1156+ if ! h .explicitContentType {
1157+ contentType := h .ContentType ()
1158+ if len (contentType ) > 0 {
1159+ f (strContentType , contentType )
1160+ }
11471161 }
1148- userAgent := h .UserAgent ()
1149- if len (userAgent ) > 0 {
1150- f (strUserAgent , userAgent )
1162+ if ! h .explicitUserAgent {
1163+ userAgent := h .UserAgent ()
1164+ if len (userAgent ) > 0 {
1165+ f (strUserAgent , userAgent )
1166+ }
11511167 }
1152- if len (h .trailer ) > 0 {
1153- f (strTrailer , appendArgsKeyBytes (nil , h .trailer , strCommaSpace ))
1168+ if ! h .explicitTrailer {
1169+ if len (h .trailer ) > 0 {
1170+ f (strTrailer , appendArgsKeyBytes (nil , h .trailer , strCommaSpace ))
1171+ }
11541172 }
11551173
1156- h .collectCookies ()
1157- if len (h .cookies ) > 0 {
1158- h .bufKV .value = appendRequestCookieBytes (h .bufKV .value [:0 ], h .cookies )
1159- f (strCookie , h .bufKV .value )
1174+ if ! h .explicitCookies {
1175+ h .collectCookies ()
1176+ if len (h .cookies ) > 0 {
1177+ h .bufKV .value = appendRequestCookieBytes (h .bufKV .value [:0 ], h .cookies )
1178+ f (strCookie , h .bufKV .value )
1179+ }
11601180 }
11611181 visitArgs (h .h , f )
1162- if h .ConnectionClose () {
1163- f (strConnection , strClose )
1182+ if ! h .explicitConnection {
1183+ if h .ConnectionClose () {
1184+ f (strConnection , strClose )
1185+ }
11641186 }
11651187}
11661188
@@ -1233,24 +1255,31 @@ func (h *RequestHeader) del(key []byte) {
12331255 switch string (key ) {
12341256 case HeaderHost :
12351257 h .host = h .host [:0 ]
1258+ h .explicitHost = false
12361259 case HeaderContentType :
12371260 h .contentType = h .contentType [:0 ]
1261+ h .explicitContentType = false
12381262 case HeaderUserAgent :
12391263 h .userAgent = h .userAgent [:0 ]
1264+ h .explicitUserAgent = false
12401265 case HeaderCookie :
12411266 h .cookies = h .cookies [:0 ]
1267+ h .explicitCookies = false
12421268 case HeaderContentLength :
12431269 h .contentLength = 0
12441270 h .contentLengthBytes = h .contentLengthBytes [:0 ]
1271+ h .explicitContentLength = false
12451272 case HeaderConnection :
12461273 h .connectionClose = false
1274+ h .explicitConnection = false
12471275 case HeaderTrailer :
12481276 h .trailer = h .trailer [:0 ]
1277+ h .explicitTrailer = false
12491278 }
12501279 h .h = delAllArgsBytes (h .h , key )
12511280}
12521281
1253- // setSpecialHeader handles special headers and return true when a header is processed .
1282+ // setSpecialHeader handles special headers.
12541283func (h * ResponseHeader ) setSpecialHeader (key , value []byte ) bool {
12551284 if len (key ) == 0 {
12561285 return false
@@ -1314,56 +1343,61 @@ func (h *ResponseHeader) setNonSpecial(key []byte, value []byte) {
13141343}
13151344
13161345// setSpecialHeader handles special headers and return true when a header is processed.
1317- func (h * RequestHeader ) setSpecialHeader (key , value []byte ) bool {
1346+ func (h * RequestHeader ) setSpecialHeader (key , value []byte ) {
13181347 if len (key ) == 0 {
1319- return false
1348+ return
13201349 }
13211350
13221351 switch key [0 ] | 0x20 {
13231352 case 'c' :
13241353 if caseInsensitiveCompare (strContentType , key ) {
13251354 h .SetContentTypeBytes (value )
1326- return true
1355+ h .explicitContentType = true
1356+ return
13271357 } else if caseInsensitiveCompare (strContentLength , key ) {
13281358 if contentLength , err := parseContentLength (value ); err == nil {
13291359 h .contentLength = contentLength
13301360 h .contentLengthBytes = append (h .contentLengthBytes [:0 ], value ... )
1361+ h .explicitContentLength = true
13311362 }
1332- return true
1363+ return
13331364 } else if caseInsensitiveCompare (strConnection , key ) {
13341365 if bytes .Equal (strClose , value ) {
13351366 h .SetConnectionClose ()
13361367 } else {
13371368 h .ResetConnectionClose ()
13381369 h .setNonSpecial (key , value )
13391370 }
1340- return true
1371+ h .explicitConnection = true
1372+ return
13411373 } else if caseInsensitiveCompare (strCookie , key ) {
13421374 h .collectCookies ()
13431375 h .cookies = parseRequestCookies (h .cookies , value )
1344- return true
1376+ h .explicitCookies = true
1377+ return
13451378 }
13461379 case 't' :
13471380 if caseInsensitiveCompare (strTransferEncoding , key ) {
13481381 // Transfer-Encoding is managed automatically.
1349- return true
1382+ return
13501383 } else if caseInsensitiveCompare (strTrailer , key ) {
13511384 _ = h .SetTrailerBytes (value )
1352- return true
1385+ h .explicitTrailer = true
1386+ return
13531387 }
13541388 case 'h' :
13551389 if caseInsensitiveCompare (strHost , key ) {
13561390 h .SetHostBytes (value )
1357- return true
1391+ h .explicitHost = true
1392+ return
13581393 }
13591394 case 'u' :
13601395 if caseInsensitiveCompare (strUserAgent , key ) {
13611396 h .SetUserAgentBytes (value )
1362- return true
1397+ h .explicitUserAgent = true
1398+ return
13631399 }
13641400 }
1365-
1366- return false
13671401}
13681402
13691403// setNonSpecial directly put into map i.e. not a basic header
@@ -1639,10 +1673,7 @@ func (h *RequestHeader) AddBytesV(key string, value []byte) {
16391673// If the header is set as a Trailer (forbidden trailers will not be set, see AddTrailer for more details),
16401674// it will be sent after the chunked request body.
16411675func (h * RequestHeader ) AddBytesKV (key , value []byte ) {
1642- if h .setSpecialHeader (key , value ) {
1643- return
1644- }
1645-
1676+ h .setSpecialHeader (key , value )
16461677 k := getHeaderKeyBytes (& h .bufKV , b2s (key ), h .disableNormalizing )
16471678 h .h = appendArgBytes (h .h , k , value , argsHasValue )
16481679}
@@ -1698,9 +1729,7 @@ func (h *RequestHeader) SetBytesKV(key, value []byte) {
16981729// If the header is set as a Trailer (forbidden trailers will not be set, see SetTrailer for more details),
16991730// it will be sent after the chunked request body.
17001731func (h * RequestHeader ) SetCanonical (key , value []byte ) {
1701- if h .setSpecialHeader (key , value ) {
1702- return
1703- }
1732+ h .setSpecialHeader (key , value )
17041733 h .setNonSpecial (key , value )
17051734}
17061735
@@ -2469,25 +2498,33 @@ func (h *RequestHeader) AppendBytes(dst []byte) []byte {
24692498 dst = append (dst , h .Protocol ()... )
24702499 dst = append (dst , strCRLF ... )
24712500
2472- userAgent := h .UserAgent ()
2473- if len (userAgent ) > 0 {
2474- dst = appendHeaderLine (dst , strUserAgent , userAgent )
2501+ if ! h .explicitUserAgent {
2502+ userAgent := h .UserAgent ()
2503+ if len (userAgent ) > 0 {
2504+ dst = appendHeaderLine (dst , strUserAgent , userAgent )
2505+ }
24752506 }
24762507
2477- host := h .Host ()
2478- if len (host ) > 0 {
2479- dst = appendHeaderLine (dst , strHost , host )
2508+ if ! h .explicitHost {
2509+ host := h .Host ()
2510+ if len (host ) > 0 {
2511+ dst = appendHeaderLine (dst , strHost , host )
2512+ }
24802513 }
24812514
2482- contentType := h .ContentType ()
2483- if ! h .noDefaultContentType && len (contentType ) == 0 && ! h .ignoreBody () {
2484- contentType = strDefaultContentType
2485- }
2486- if len (contentType ) > 0 {
2487- dst = appendHeaderLine (dst , strContentType , contentType )
2515+ if ! h .explicitContentType {
2516+ contentType := h .ContentType ()
2517+ if ! h .noDefaultContentType && len (contentType ) == 0 && ! h .ignoreBody () {
2518+ contentType = strDefaultContentType
2519+ }
2520+ if len (contentType ) > 0 {
2521+ dst = appendHeaderLine (dst , strContentType , contentType )
2522+ }
24882523 }
2489- if len (h .contentLengthBytes ) > 0 {
2490- dst = appendHeaderLine (dst , strContentLength , h .contentLengthBytes )
2524+ if ! h .explicitContentLength {
2525+ if len (h .contentLengthBytes ) > 0 {
2526+ dst = appendHeaderLine (dst , strContentLength , h .contentLengthBytes )
2527+ }
24912528 }
24922529
24932530 for i , n := 0 , len (h .h ); i < n ; i ++ {
@@ -2505,22 +2542,28 @@ func (h *RequestHeader) AppendBytes(dst []byte) []byte {
25052542 }
25062543 }
25072544
2508- if len (h .trailer ) > 0 {
2509- dst = appendHeaderLine (dst , strTrailer , appendArgsKeyBytes (nil , h .trailer , strCommaSpace ))
2545+ if ! h .explicitTrailer {
2546+ if len (h .trailer ) > 0 {
2547+ dst = appendHeaderLine (dst , strTrailer , appendArgsKeyBytes (nil , h .trailer , strCommaSpace ))
2548+ }
25102549 }
25112550
2512- // there is no need in h.collectCookies() here, since if cookies aren't collected yet,
2513- // they all are located in h.h.
2514- n := len (h .cookies )
2515- if n > 0 {
2516- dst = append (dst , strCookie ... )
2517- dst = append (dst , strColonSpace ... )
2518- dst = appendRequestCookieBytes (dst , h .cookies )
2519- dst = append (dst , strCRLF ... )
2551+ if ! h .explicitCookies {
2552+ // there is no need in h.collectCookies() here, since if cookies aren't collected yet,
2553+ // they all are located in h.h.
2554+ n := len (h .cookies )
2555+ if n > 0 {
2556+ dst = append (dst , strCookie ... )
2557+ dst = append (dst , strColonSpace ... )
2558+ dst = appendRequestCookieBytes (dst , h .cookies )
2559+ dst = append (dst , strCRLF ... )
2560+ }
25202561 }
25212562
2522- if h .ConnectionClose () {
2523- dst = appendHeaderLine (dst , strConnection , strClose )
2563+ if ! h .explicitConnection {
2564+ if h .ConnectionClose () {
2565+ dst = appendHeaderLine (dst , strConnection , strClose )
2566+ }
25242567 }
25252568
25262569 return append (dst , strCRLF ... )
0 commit comments