github.com/cloudwego/hertz@v0.9.3/pkg/protocol/header.go (about) 1 /* 2 * Copyright 2022 CloudWeGo Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 * The MIT License (MIT) 17 * 18 * Copyright (c) 2015-present Aliaksandr Valialkin, VertaMedia, Kirill Danshin, Erik Dubbelboer, FastHTTP Authors 19 * 20 * Permission is hereby granted, free of charge, to any person obtaining a copy 21 * of this software and associated documentation files (the "Software"), to deal 22 * in the Software without restriction, including without limitation the rights 23 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 24 * copies of the Software, and to permit persons to whom the Software is 25 * furnished to do so, subject to the following conditions: 26 * 27 * The above copyright notice and this permission notice shall be included in 28 * all copies or substantial portions of the Software. 29 * 30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 31 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 32 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 33 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 34 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 35 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 36 * THE SOFTWARE. 37 * 38 * This file may have been modified by CloudWeGo authors. All CloudWeGo 39 * Modifications are Copyright 2022 CloudWeGo Authors. 40 */ 41 42 package protocol 43 44 import ( 45 "bytes" 46 "net/http" 47 "sync" 48 "sync/atomic" 49 "time" 50 51 "github.com/cloudwego/hertz/internal/bytesconv" 52 "github.com/cloudwego/hertz/internal/bytestr" 53 "github.com/cloudwego/hertz/internal/nocopy" 54 errs "github.com/cloudwego/hertz/pkg/common/errors" 55 "github.com/cloudwego/hertz/pkg/common/hlog" 56 "github.com/cloudwego/hertz/pkg/common/utils" 57 "github.com/cloudwego/hertz/pkg/protocol/consts" 58 ) 59 60 var ( 61 ServerDate atomic.Value 62 ServerDateOnce sync.Once // serverDateOnce.Do(updateServerDate) 63 ) 64 65 type RequestHeader struct { 66 noCopy nocopy.NoCopy //lint:ignore U1000 until noCopy is used 67 68 disableNormalizing bool 69 connectionClose bool 70 noDefaultContentType bool 71 72 // These two fields have been moved close to other bool fields 73 // for reducing RequestHeader object size. 74 cookiesCollected bool 75 76 contentLength int 77 contentLengthBytes []byte 78 79 method []byte 80 requestURI []byte 81 host []byte 82 contentType []byte 83 84 userAgent []byte 85 mulHeader [][]byte 86 protocol string 87 88 h []argsKV 89 bufKV argsKV 90 trailer *Trailer 91 92 cookies []argsKV 93 94 // stores an immutable copy of headers as they were received from the 95 // wire. 96 rawHeaders []byte 97 } 98 99 func (h *RequestHeader) SetRawHeaders(r []byte) { 100 h.rawHeaders = r 101 } 102 103 // ResponseHeader represents HTTP response header. 104 // 105 // It is forbidden copying ResponseHeader instances. 106 // Create new instances instead and use CopyTo. 107 // 108 // ResponseHeader instance MUST NOT be used from concurrently running 109 // goroutines. 110 type ResponseHeader struct { 111 noCopy nocopy.NoCopy //lint:ignore U1000 until noCopy is used 112 113 disableNormalizing bool 114 connectionClose bool 115 noDefaultContentType bool 116 noDefaultDate bool 117 118 statusCode int 119 contentLength int 120 contentLengthBytes []byte 121 contentEncoding []byte 122 123 contentType []byte 124 server []byte 125 mulHeader [][]byte 126 protocol string 127 128 h []argsKV 129 bufKV argsKV 130 trailer *Trailer 131 132 cookies []argsKV 133 134 headerLength int 135 } 136 137 // SetHeaderLength sets the size of header for tracer. 138 func (h *ResponseHeader) SetHeaderLength(length int) { 139 h.headerLength = length 140 } 141 142 // GetHeaderLength gets the size of header for tracer. 143 func (h *ResponseHeader) GetHeaderLength() int { 144 return h.headerLength 145 } 146 147 // SetContentRange sets 'Content-Range: bytes startPos-endPos/contentLength' 148 // header. 149 func (h *ResponseHeader) SetContentRange(startPos, endPos, contentLength int) { 150 b := h.bufKV.value[:0] 151 b = append(b, bytestr.StrBytes...) 152 b = append(b, ' ') 153 b = bytesconv.AppendUint(b, startPos) 154 b = append(b, '-') 155 b = bytesconv.AppendUint(b, endPos) 156 b = append(b, '/') 157 b = bytesconv.AppendUint(b, contentLength) 158 h.bufKV.value = b 159 160 h.SetCanonical(bytestr.StrContentRange, h.bufKV.value) 161 } 162 163 func (h *ResponseHeader) NoDefaultContentType() bool { 164 return h.noDefaultContentType 165 } 166 167 // SetConnectionClose sets 'Connection: close' header. 168 func (h *ResponseHeader) SetConnectionClose(close bool) { 169 h.connectionClose = close 170 } 171 172 func (h *ResponseHeader) PeekArgBytes(key []byte) []byte { 173 return peekArgBytes(h.h, key) 174 } 175 176 // Deprecated: Use ResponseHeader.SetProtocol(consts.HTTP11) instead 177 // 178 // Now SetNoHTTP11(true) equal to SetProtocol(consts.HTTP10) 179 // SetNoHTTP11(false) equal to SetProtocol(consts.HTTP11) 180 func (h *ResponseHeader) SetNoHTTP11(b bool) { 181 if b { 182 h.protocol = consts.HTTP10 183 return 184 } 185 186 h.protocol = consts.HTTP11 187 } 188 189 // Cookie fills cookie for the given cookie.Key. 190 // 191 // Returns false if cookie with the given cookie.Key is missing. 192 func (h *ResponseHeader) Cookie(cookie *Cookie) bool { 193 v := peekArgBytes(h.cookies, cookie.Key()) 194 if v == nil { 195 return false 196 } 197 cookie.ParseBytes(v) //nolint:errcheck 198 return true 199 } 200 201 // FullCookie returns complete cookie bytes 202 func (h *ResponseHeader) FullCookie() []byte { 203 return h.Peek(consts.HeaderSetCookie) 204 } 205 206 // IsHTTP11 returns true if the response is HTTP/1.1. 207 func (h *ResponseHeader) IsHTTP11() bool { 208 return h.protocol == consts.HTTP11 209 } 210 211 // SetContentType sets Content-Type header value. 212 func (h *ResponseHeader) SetContentType(contentType string) { 213 h.contentType = append(h.contentType[:0], contentType...) 214 } 215 216 func (h *ResponseHeader) GetHeaders() []argsKV { 217 return h.h 218 } 219 220 // Reset clears response header. 221 func (h *ResponseHeader) Reset() { 222 h.disableNormalizing = false 223 h.Trailer().disableNormalizing = false 224 h.noDefaultContentType = false 225 h.noDefaultDate = false 226 h.ResetSkipNormalize() 227 } 228 229 // CopyTo copies all the headers to dst. 230 func (h *ResponseHeader) CopyTo(dst *ResponseHeader) { 231 dst.Reset() 232 233 dst.disableNormalizing = h.disableNormalizing 234 dst.connectionClose = h.connectionClose 235 dst.noDefaultContentType = h.noDefaultContentType 236 dst.noDefaultDate = h.noDefaultDate 237 238 dst.statusCode = h.statusCode 239 dst.contentLength = h.contentLength 240 dst.contentLengthBytes = append(dst.contentLengthBytes[:0], h.contentLengthBytes...) 241 dst.contentEncoding = append(dst.contentEncoding[:0], h.contentEncoding...) 242 dst.contentType = append(dst.contentType[:0], h.contentType...) 243 dst.server = append(dst.server[:0], h.server...) 244 dst.h = copyArgs(dst.h, h.h) 245 dst.cookies = copyArgs(dst.cookies, h.cookies) 246 dst.protocol = h.protocol 247 dst.headerLength = h.headerLength 248 h.Trailer().CopyTo(dst.Trailer()) 249 } 250 251 // Multiple headers with the same key may be added with this function. 252 // Use Set for setting a single header for the given key. 253 // 254 // the Content-Type, Content-Length, Connection, Cookie, 255 // Transfer-Encoding, Host and User-Agent headers can only be set once 256 // and will overwrite the previous value. 257 func (h *RequestHeader) Add(key, value string) { 258 if h.setSpecialHeader(bytesconv.S2b(key), bytesconv.S2b(value)) { 259 return 260 } 261 262 k := getHeaderKeyBytes(&h.bufKV, key, h.disableNormalizing) 263 h.h = appendArg(h.h, bytesconv.B2s(k), value, ArgsHasValue) 264 } 265 266 // VisitAll calls f for each header. 267 // 268 // f must not retain references to key and/or value after returning. 269 // Copy key and/or value contents before returning if you need retaining them. 270 func (h *ResponseHeader) VisitAll(f func(key, value []byte)) { 271 if len(h.contentLengthBytes) > 0 { 272 f(bytestr.StrContentLength, h.contentLengthBytes) 273 } 274 contentType := h.ContentType() 275 if len(contentType) > 0 { 276 f(bytestr.StrContentType, contentType) 277 } 278 contentEncoding := h.ContentEncoding() 279 if len(contentEncoding) > 0 { 280 f(bytestr.StrContentEncoding, contentEncoding) 281 } 282 server := h.Server() 283 if len(server) > 0 { 284 f(bytestr.StrServer, server) 285 } 286 if len(h.cookies) > 0 { 287 visitArgs(h.cookies, func(k, v []byte) { 288 f(bytestr.StrSetCookie, v) 289 }) 290 } 291 if !h.Trailer().Empty() { 292 f(bytestr.StrTrailer, h.Trailer().GetBytes()) 293 } 294 visitArgs(h.h, f) 295 if h.ConnectionClose() { 296 f(bytestr.StrConnection, bytestr.StrClose) 297 } 298 } 299 300 // IsHTTP11 returns true if the request is HTTP/1.1. 301 func (h *RequestHeader) IsHTTP11() bool { 302 return h.protocol == consts.HTTP11 303 } 304 305 func (h *RequestHeader) SetProtocol(p string) { 306 h.protocol = p 307 } 308 309 func (h *RequestHeader) GetProtocol() string { 310 return h.protocol 311 } 312 313 // Deprecated: Use RequestHeader.SetProtocol(consts.HTTP11) instead 314 // 315 // Now SetNoHTTP11(true) equal to SetProtocol(consts.HTTP10) 316 // SetNoHTTP11(false) equal to SetProtocol(consts.HTTP11) 317 func (h *RequestHeader) SetNoHTTP11(b bool) { 318 if b { 319 h.protocol = consts.HTTP10 320 return 321 } 322 323 h.protocol = consts.HTTP11 324 } 325 326 func (h *RequestHeader) InitBufValue(size int) { 327 if size > cap(h.bufKV.value) { 328 h.bufKV.value = make([]byte, 0, size) 329 } 330 } 331 332 func (h *RequestHeader) GetBufValue() []byte { 333 return h.bufKV.value 334 } 335 336 // HasAcceptEncodingBytes returns true if the header contains 337 // the given Accept-Encoding value. 338 func (h *RequestHeader) HasAcceptEncodingBytes(acceptEncoding []byte) bool { 339 ae := h.peek(bytestr.StrAcceptEncoding) 340 n := bytes.Index(ae, acceptEncoding) 341 if n < 0 { 342 return false 343 } 344 b := ae[n+len(acceptEncoding):] 345 if len(b) > 0 && b[0] != ',' { 346 return false 347 } 348 if n == 0 { 349 return true 350 } 351 return ae[n-1] == ' ' 352 } 353 354 func (h *RequestHeader) PeekIfModifiedSinceBytes() []byte { 355 return h.peek(bytestr.StrIfModifiedSince) 356 } 357 358 // RequestURI returns RequestURI from the first HTTP request line. 359 func (h *RequestHeader) RequestURI() []byte { 360 requestURI := h.requestURI 361 if len(requestURI) == 0 { 362 requestURI = bytestr.StrSlash 363 } 364 return requestURI 365 } 366 367 func (h *RequestHeader) PeekArgBytes(key []byte) []byte { 368 return peekArgBytes(h.h, key) 369 } 370 371 // RawHeaders returns raw header key/value bytes. 372 // 373 // Depending on server configuration, header keys may be normalized to 374 // capital-case in place. 375 // 376 // This copy is set aside during parsing, so empty slice is returned for all 377 // cases where parsing did not happen. Similarly, request line is not stored 378 // during parsing and can not be returned. 379 // 380 // The slice is not safe to use after the handler returns. 381 func (h *RequestHeader) RawHeaders() []byte { 382 return h.rawHeaders 383 } 384 385 // AppendBytes appends request header representation to dst and returns 386 // the extended dst. 387 func (h *RequestHeader) AppendBytes(dst []byte) []byte { 388 dst = append(dst, h.Method()...) 389 dst = append(dst, ' ') 390 dst = append(dst, h.RequestURI()...) 391 dst = append(dst, ' ') 392 dst = append(dst, bytestr.StrHTTP11...) 393 dst = append(dst, bytestr.StrCRLF...) 394 395 userAgent := h.UserAgent() 396 if len(userAgent) > 0 { 397 dst = appendHeaderLine(dst, bytestr.StrUserAgent, userAgent) 398 } 399 400 host := h.Host() 401 if len(host) > 0 { 402 dst = appendHeaderLine(dst, bytestr.StrHost, host) 403 } 404 405 contentType := h.ContentType() 406 if len(contentType) == 0 && !h.IgnoreBody() && !h.noDefaultContentType { 407 contentType = bytestr.StrPostArgsContentType 408 } 409 if len(contentType) > 0 { 410 dst = appendHeaderLine(dst, bytestr.StrContentType, contentType) 411 } 412 if len(h.contentLengthBytes) > 0 { 413 dst = appendHeaderLine(dst, bytestr.StrContentLength, h.contentLengthBytes) 414 } 415 416 for i, n := 0, len(h.h); i < n; i++ { 417 kv := &h.h[i] 418 dst = appendHeaderLine(dst, kv.key, kv.value) 419 } 420 421 if !h.Trailer().Empty() { 422 dst = appendHeaderLine(dst, bytestr.StrTrailer, h.Trailer().GetBytes()) 423 } 424 425 // there is no need in h.collectCookies() here, since if cookies aren't collected yet, 426 // they all are located in h.h. 427 n := len(h.cookies) 428 if n > 0 { 429 dst = append(dst, bytestr.StrCookie...) 430 dst = append(dst, bytestr.StrColonSpace...) 431 dst = appendRequestCookieBytes(dst, h.cookies) 432 dst = append(dst, bytestr.StrCRLF...) 433 } 434 435 if h.ConnectionClose() { 436 dst = appendHeaderLine(dst, bytestr.StrConnection, bytestr.StrClose) 437 } 438 439 return append(dst, bytestr.StrCRLF...) 440 } 441 442 // Header returns request header representation. 443 // 444 // The returned representation is valid until the next call to RequestHeader methods. 445 func (h *RequestHeader) Header() []byte { 446 h.bufKV.value = h.AppendBytes(h.bufKV.value[:0]) 447 return h.bufKV.value 448 } 449 450 // IsPut returns true if request method is PUT. 451 func (h *RequestHeader) IsPut() bool { 452 return bytes.Equal(h.Method(), bytestr.StrPut) 453 } 454 455 // IsHead returns true if request method is HEAD. 456 func (h *RequestHeader) IsHead() bool { 457 return bytes.Equal(h.Method(), bytestr.StrHead) 458 } 459 460 // IsPost returns true if request method is POST. 461 func (h *RequestHeader) IsPost() bool { 462 return bytes.Equal(h.Method(), bytestr.StrPost) 463 } 464 465 // IsDelete returns true if request method is DELETE. 466 func (h *RequestHeader) IsDelete() bool { 467 return bytes.Equal(h.Method(), bytestr.StrDelete) 468 } 469 470 // IsConnect returns true if request method is CONNECT. 471 func (h *RequestHeader) IsConnect() bool { 472 return bytes.Equal(h.Method(), bytestr.StrConnect) 473 } 474 475 func (h *RequestHeader) IgnoreBody() bool { 476 return h.IsGet() || h.IsHead() 477 } 478 479 // ContentLength returns Content-Length header value. 480 // 481 // It may be negative: 482 // -1 means Transfer-Encoding: chunked. 483 func (h *RequestHeader) ContentLength() int { 484 return h.contentLength 485 } 486 487 // SetHost sets Host header value. 488 func (h *RequestHeader) SetHost(host string) { 489 h.host = append(h.host[:0], host...) 490 } 491 492 // SetStatusCode sets response status code. 493 func (h *ResponseHeader) SetStatusCode(statusCode int) { 494 checkWriteHeaderCode(statusCode) 495 h.statusCode = statusCode 496 } 497 498 func checkWriteHeaderCode(code int) { 499 // For now, we only emit a warning for bad codes. 500 // In the future we might block things over 599 or under 100 501 if code < 100 || code > 599 { 502 hlog.SystemLogger().Warnf("Invalid StatusCode code %v, status code should not be under 100 or over 599.\n"+ 503 "For more info: https://www.rfc-editor.org/rfc/rfc9110.html#name-status-codes", code) 504 } 505 } 506 507 func (h *ResponseHeader) ResetSkipNormalize() { 508 h.protocol = "" 509 h.connectionClose = false 510 511 h.statusCode = 0 512 h.contentLength = 0 513 h.contentLengthBytes = h.contentLengthBytes[:0] 514 h.contentEncoding = h.contentEncoding[:0] 515 516 h.contentType = h.contentType[:0] 517 h.server = h.server[:0] 518 519 h.h = h.h[:0] 520 h.cookies = h.cookies[:0] 521 h.Trailer().ResetSkipNormalize() 522 h.mulHeader = h.mulHeader[:0] 523 } 524 525 // ContentLength returns Content-Length header value. 526 // 527 // It may be negative: 528 // -1 means Transfer-Encoding: chunked. 529 // -2 means Transfer-Encoding: identity. 530 func (h *ResponseHeader) ContentLength() int { 531 return h.contentLength 532 } 533 534 // Set sets the given 'key: value' header. 535 // 536 // Use Add for setting multiple header values under the same key. 537 func (h *ResponseHeader) Set(key, value string) { 538 initHeaderKV(&h.bufKV, key, value, h.disableNormalizing) 539 h.SetCanonical(h.bufKV.key, h.bufKV.value) 540 } 541 542 // Add adds the given 'key: value' header. 543 // 544 // Multiple headers with the same key may be added with this function. 545 // Use Set for setting a single header for the given key. 546 // 547 // the Content-Type, Content-Length, Connection, Server, Set-Cookie, 548 // Transfer-Encoding and Date headers can only be set once and will 549 // overwrite the previous value. 550 func (h *ResponseHeader) Add(key, value string) { 551 if h.setSpecialHeader(bytesconv.S2b(key), bytesconv.S2b(value)) { 552 return 553 } 554 555 k := getHeaderKeyBytes(&h.bufKV, key, h.disableNormalizing) 556 h.h = appendArg(h.h, bytesconv.B2s(k), value, ArgsHasValue) 557 } 558 559 // SetContentLength sets Content-Length header value. 560 // 561 // Content-Length may be negative: 562 // -1 means Transfer-Encoding: chunked. 563 // -2 means Transfer-Encoding: identity. 564 func (h *ResponseHeader) SetContentLength(contentLength int) { 565 if h.MustSkipContentLength() { 566 return 567 } 568 h.contentLength = contentLength 569 if contentLength >= 0 { 570 h.contentLengthBytes = bytesconv.AppendUint(h.contentLengthBytes[:0], contentLength) 571 h.h = delAllArgsBytes(h.h, bytestr.StrTransferEncoding) 572 } else { 573 h.contentLengthBytes = h.contentLengthBytes[:0] 574 value := bytestr.StrChunked 575 if contentLength == -2 { 576 h.SetConnectionClose(true) 577 value = bytestr.StrIdentity 578 } 579 h.h = setArgBytes(h.h, bytestr.StrTransferEncoding, value, ArgsHasValue) 580 } 581 } 582 583 func (h *ResponseHeader) ContentLengthBytes() []byte { 584 return h.contentLengthBytes 585 } 586 587 func (h *ResponseHeader) InitContentLengthWithValue(contentLength int) { 588 h.contentLength = contentLength 589 } 590 591 // VisitAllCookie calls f for each response cookie. 592 // 593 // Cookie name is passed in key and the whole Set-Cookie header value 594 // is passed in value on each f invocation. Value may be parsed 595 // with Cookie.ParseBytes(). 596 // 597 // f must not retain references to key and/or value after returning. 598 func (h *ResponseHeader) VisitAllCookie(f func(key, value []byte)) { 599 visitArgs(h.cookies, f) 600 } 601 602 // DelAllCookies removes all the cookies from response headers. 603 func (h *ResponseHeader) DelAllCookies() { 604 h.cookies = h.cookies[:0] 605 } 606 607 // DelCookie removes cookie under the given key from response header. 608 // 609 // Note that DelCookie doesn't remove the cookie from the client. 610 // Use DelClientCookie instead. 611 func (h *ResponseHeader) DelCookie(key string) { 612 h.cookies = delAllArgs(h.cookies, key) 613 } 614 615 // DelCookieBytes removes cookie under the given key from response header. 616 // 617 // Note that DelCookieBytes doesn't remove the cookie from the client. 618 // Use DelClientCookieBytes instead. 619 func (h *ResponseHeader) DelCookieBytes(key []byte) { 620 h.DelCookie(bytesconv.B2s(key)) 621 } 622 623 // DelBytes deletes header with the given key. 624 func (h *ResponseHeader) DelBytes(key []byte) { 625 h.bufKV.key = append(h.bufKV.key[:0], key...) 626 utils.NormalizeHeaderKey(h.bufKV.key, h.disableNormalizing) 627 h.del(h.bufKV.key) 628 } 629 630 // Header returns response header representation. 631 // 632 // The returned value is valid until the next call to ResponseHeader methods. 633 func (h *ResponseHeader) Header() []byte { 634 h.bufKV.value = h.AppendBytes(h.bufKV.value[:0]) 635 return h.bufKV.value 636 } 637 638 func (h *ResponseHeader) PeekLocation() []byte { 639 return h.peek(bytestr.StrLocation) 640 } 641 642 // DelClientCookie instructs the client to remove the given cookie. 643 // This doesn't work for a cookie with specific domain or path, 644 // you should delete it manually like: 645 // 646 // c := AcquireCookie() 647 // c.SetKey(key) 648 // c.SetDomain("example.com") 649 // c.SetPath("/path") 650 // c.SetExpire(CookieExpireDelete) 651 // h.SetCookie(c) 652 // ReleaseCookie(c) 653 // 654 // Use DelCookie if you want just removing the cookie from response header. 655 func (h *ResponseHeader) DelClientCookie(key string) { 656 h.DelCookie(key) 657 658 c := AcquireCookie() 659 c.SetKey(key) 660 c.SetExpire(CookieExpireDelete) 661 h.SetCookie(c) 662 ReleaseCookie(c) 663 } 664 665 // DelClientCookieBytes instructs the client to remove the given cookie. 666 // This doesn't work for a cookie with specific domain or path, 667 // you should delete it manually like: 668 // 669 // c := AcquireCookie() 670 // c.SetKey(key) 671 // c.SetDomain("example.com") 672 // c.SetPath("/path") 673 // c.SetExpire(CookieExpireDelete) 674 // h.SetCookie(c) 675 // ReleaseCookie(c) 676 // 677 // Use DelCookieBytes if you want just removing the cookie from response header. 678 func (h *ResponseHeader) DelClientCookieBytes(key []byte) { 679 h.DelClientCookie(bytesconv.B2s(key)) 680 } 681 682 // Peek returns header value for the given key. 683 // 684 // Returned value is valid until the next call to ResponseHeader. 685 // Do not store references to returned value. Make copies instead. 686 func (h *ResponseHeader) Peek(key string) []byte { 687 k := getHeaderKeyBytes(&h.bufKV, key, h.disableNormalizing) 688 return h.peek(k) 689 } 690 691 func (h *ResponseHeader) IsDisableNormalizing() bool { 692 return h.disableNormalizing 693 } 694 695 func (h *ResponseHeader) ParseSetCookie(value []byte) { 696 var kv *argsKV 697 h.cookies, kv = allocArg(h.cookies) 698 kv.key = getCookieKey(kv.key, value) 699 kv.value = append(kv.value[:0], value...) 700 } 701 702 func (h *ResponseHeader) peek(key []byte) []byte { 703 switch string(key) { 704 case consts.HeaderContentType: 705 return h.ContentType() 706 case consts.HeaderContentEncoding: 707 return h.ContentEncoding() 708 case consts.HeaderServer: 709 return h.Server() 710 case consts.HeaderConnection: 711 if h.ConnectionClose() { 712 return bytestr.StrClose 713 } 714 return peekArgBytes(h.h, key) 715 case consts.HeaderContentLength: 716 return h.contentLengthBytes 717 case consts.HeaderSetCookie: 718 return appendResponseCookieBytes(nil, h.cookies) 719 case consts.HeaderTrailer: 720 return h.Trailer().GetBytes() 721 default: 722 return peekArgBytes(h.h, key) 723 } 724 } 725 726 // PeekAll returns all header value for the given key. 727 // 728 // The returned value is valid until the request is released, 729 // either though ReleaseResponse or your request handler returning. 730 // Any future calls to the Peek* will modify the returned value. 731 // Do not store references to returned value. Use ResponseHeader.GetAll(key) instead. 732 func (h *ResponseHeader) PeekAll(key string) [][]byte { 733 k := getHeaderKeyBytes(&h.bufKV, key, h.disableNormalizing) 734 return h.peekAll(k) 735 } 736 737 func (h *ResponseHeader) peekAll(key []byte) [][]byte { 738 h.mulHeader = h.mulHeader[:0] 739 switch string(key) { 740 case consts.HeaderContentType: 741 if contentType := h.ContentType(); len(contentType) > 0 { 742 h.mulHeader = append(h.mulHeader, contentType) 743 } 744 case consts.HeaderContentEncoding: 745 if contentEncoding := h.ContentEncoding(); len(contentEncoding) > 0 { 746 h.mulHeader = append(h.mulHeader, contentEncoding) 747 } 748 case consts.HeaderServer: 749 if server := h.Server(); len(server) > 0 { 750 h.mulHeader = append(h.mulHeader, server) 751 } 752 case consts.HeaderConnection: 753 if h.ConnectionClose() { 754 h.mulHeader = append(h.mulHeader, bytestr.StrClose) 755 } else { 756 h.mulHeader = peekAllArgBytesToDst(h.mulHeader, h.h, key) 757 } 758 case consts.HeaderContentLength: 759 h.mulHeader = append(h.mulHeader, h.contentLengthBytes) 760 case consts.HeaderSetCookie: 761 h.mulHeader = append(h.mulHeader, appendResponseCookieBytes(nil, h.cookies)) 762 default: 763 h.mulHeader = peekAllArgBytesToDst(h.mulHeader, h.h, key) 764 } 765 return h.mulHeader 766 } 767 768 // PeekAll returns all header value for the given key. 769 // 770 // The returned value is valid until the request is released, 771 // either though ReleaseRequest or your request handler returning. 772 // Any future calls to the Peek* will modify the returned value. 773 // Do not store references to returned value. Use RequestHeader.GetAll(key) instead. 774 func (h *RequestHeader) PeekAll(key string) [][]byte { 775 k := getHeaderKeyBytes(&h.bufKV, key, h.disableNormalizing) 776 return h.peekAll(k) 777 } 778 779 func (h *RequestHeader) peekAll(key []byte) [][]byte { 780 h.mulHeader = h.mulHeader[:0] 781 switch string(key) { 782 case consts.HeaderHost: 783 if host := h.Host(); len(host) > 0 { 784 h.mulHeader = append(h.mulHeader, host) 785 } 786 case consts.HeaderContentType: 787 if contentType := h.ContentType(); len(contentType) > 0 { 788 h.mulHeader = append(h.mulHeader, contentType) 789 } 790 case consts.HeaderUserAgent: 791 if ua := h.UserAgent(); len(ua) > 0 { 792 h.mulHeader = append(h.mulHeader, ua) 793 } 794 case consts.HeaderConnection: 795 if h.ConnectionClose() { 796 h.mulHeader = append(h.mulHeader, bytestr.StrClose) 797 } else { 798 h.mulHeader = peekAllArgBytesToDst(h.mulHeader, h.h, key) 799 } 800 case consts.HeaderContentLength: 801 h.mulHeader = append(h.mulHeader, h.contentLengthBytes) 802 case consts.HeaderCookie: 803 if h.cookiesCollected { 804 h.mulHeader = append(h.mulHeader, appendRequestCookieBytes(nil, h.cookies)) 805 } else { 806 h.mulHeader = peekAllArgBytesToDst(h.mulHeader, h.h, key) 807 } 808 default: 809 h.mulHeader = peekAllArgBytesToDst(h.mulHeader, h.h, key) 810 } 811 return h.mulHeader 812 } 813 814 // SetContentTypeBytes sets Content-Type header value. 815 func (h *ResponseHeader) SetContentTypeBytes(contentType []byte) { 816 h.contentType = append(h.contentType[:0], contentType...) 817 } 818 819 // ContentEncoding returns Content-Encoding header value. 820 func (h *ResponseHeader) ContentEncoding() []byte { 821 return h.contentEncoding 822 } 823 824 // SetContentEncoding sets Content-Encoding header value. 825 func (h *ResponseHeader) SetContentEncoding(contentEncoding string) { 826 h.contentEncoding = append(h.contentEncoding[:0], contentEncoding...) 827 } 828 829 // SetContentEncodingBytes sets Content-Encoding header value. 830 func (h *ResponseHeader) SetContentEncodingBytes(contentEncoding []byte) { 831 h.contentEncoding = append(h.contentEncoding[:0], contentEncoding...) 832 } 833 834 func (h *ResponseHeader) SetContentLengthBytes(contentLength []byte) { 835 h.contentLengthBytes = append(h.contentLengthBytes[:0], contentLength...) 836 } 837 838 // SetCanonical sets the given 'key: value' header assuming that 839 // key is in canonical form. 840 func (h *ResponseHeader) SetCanonical(key, value []byte) { 841 if h.setSpecialHeader(key, value) { 842 return 843 } 844 845 h.h = setArgBytes(h.h, key, value, ArgsHasValue) 846 } 847 848 // ResetConnectionClose clears 'Connection: close' header if it exists. 849 func (h *ResponseHeader) ResetConnectionClose() { 850 if h.connectionClose { 851 h.connectionClose = false 852 h.h = delAllArgsBytes(h.h, bytestr.StrConnection) 853 } 854 } 855 856 // Server returns Server header value. 857 func (h *ResponseHeader) Server() []byte { 858 return h.server 859 } 860 861 func (h *ResponseHeader) AddArgBytes(key, value []byte, noValue bool) { 862 h.h = appendArgBytes(h.h, key, value, noValue) 863 } 864 865 func (h *ResponseHeader) SetArgBytes(key, value []byte, noValue bool) { 866 h.h = setArgBytes(h.h, key, value, noValue) 867 } 868 869 // AppendBytes appends response header representation to dst and returns 870 // the extended dst. 871 func (h *ResponseHeader) AppendBytes(dst []byte) []byte { 872 statusCode := h.StatusCode() 873 if statusCode < 0 { 874 statusCode = consts.StatusOK 875 } 876 dst = append(dst, consts.StatusLine(statusCode)...) 877 878 server := h.Server() 879 if len(server) != 0 { 880 dst = appendHeaderLine(dst, bytestr.StrServer, server) 881 } 882 883 if !h.noDefaultDate { 884 ServerDateOnce.Do(UpdateServerDate) 885 dst = appendHeaderLine(dst, bytestr.StrDate, ServerDate.Load().([]byte)) 886 } 887 888 // Append Content-Type only for non-zero responses 889 // or if it is explicitly set. 890 if h.ContentLength() != 0 || len(h.contentType) > 0 { 891 contentType := h.ContentType() 892 if len(contentType) > 0 { 893 dst = appendHeaderLine(dst, bytestr.StrContentType, contentType) 894 } 895 } 896 contentEncoding := h.ContentEncoding() 897 if len(contentEncoding) > 0 { 898 dst = appendHeaderLine(dst, bytestr.StrContentEncoding, contentEncoding) 899 } 900 if len(h.contentLengthBytes) > 0 { 901 dst = appendHeaderLine(dst, bytestr.StrContentLength, h.contentLengthBytes) 902 } 903 904 for i, n := 0, len(h.h); i < n; i++ { 905 kv := &h.h[i] 906 if h.noDefaultDate || !bytes.Equal(kv.key, bytestr.StrDate) { 907 dst = appendHeaderLine(dst, kv.key, kv.value) 908 } 909 } 910 911 if !h.Trailer().Empty() { 912 dst = appendHeaderLine(dst, bytestr.StrTrailer, h.Trailer().GetBytes()) 913 } 914 915 n := len(h.cookies) 916 if n > 0 { 917 for i := 0; i < n; i++ { 918 kv := &h.cookies[i] 919 dst = appendHeaderLine(dst, bytestr.StrSetCookie, kv.value) 920 } 921 } 922 923 if h.ConnectionClose() { 924 dst = appendHeaderLine(dst, bytestr.StrConnection, bytestr.StrClose) 925 } 926 927 return append(dst, bytestr.StrCRLF...) 928 } 929 930 // ConnectionClose returns true if 'Connection: close' header is set. 931 func (h *ResponseHeader) ConnectionClose() bool { 932 return h.connectionClose 933 } 934 935 func (h *ResponseHeader) GetCookies() []argsKV { 936 return h.cookies 937 } 938 939 // ContentType returns Content-Type header value. 940 func (h *ResponseHeader) ContentType() []byte { 941 contentType := h.contentType 942 if !h.noDefaultContentType && len(h.contentType) == 0 { 943 contentType = bytestr.DefaultContentType 944 } 945 return contentType 946 } 947 948 // SetNoDefaultContentType set noDefaultContentType value of ResponseHeader. 949 func (h *ResponseHeader) SetNoDefaultContentType(b bool) { 950 h.noDefaultContentType = b 951 } 952 953 // SetNoDefaultDate set noDefaultDate value of ResponseHeader. 954 func (h *ResponseHeader) SetNoDefaultDate(b bool) { 955 h.noDefaultDate = b 956 } 957 958 // SetServerBytes sets Server header value. 959 func (h *ResponseHeader) SetServerBytes(server []byte) { 960 h.server = append(h.server[:0], server...) 961 } 962 963 func (h *ResponseHeader) MustSkipContentLength() bool { 964 // From http/1.1 specs: 965 // All 1xx (informational), 204 (no content), and 304 (not modified) responses MUST NOT include a message-body 966 statusCode := h.StatusCode() 967 968 // Fast path. 969 if statusCode < 100 || statusCode == consts.StatusOK { 970 return false 971 } 972 973 // Slow path. 974 return statusCode == consts.StatusNotModified || statusCode == consts.StatusNoContent || statusCode < 200 975 } 976 977 // StatusCode returns response status code. 978 func (h *ResponseHeader) StatusCode() int { 979 if h.statusCode == 0 { 980 return consts.StatusOK 981 } 982 return h.statusCode 983 } 984 985 // Del deletes header with the given key. 986 func (h *ResponseHeader) Del(key string) { 987 k := getHeaderKeyBytes(&h.bufKV, key, h.disableNormalizing) 988 h.del(k) 989 } 990 991 func (h *ResponseHeader) del(key []byte) { 992 switch string(key) { 993 case consts.HeaderContentType: 994 h.contentType = h.contentType[:0] 995 case consts.HeaderContentEncoding: 996 h.contentEncoding = h.contentEncoding[:0] 997 case consts.HeaderServer: 998 h.server = h.server[:0] 999 case consts.HeaderSetCookie: 1000 h.cookies = h.cookies[:0] 1001 case consts.HeaderContentLength: 1002 h.contentLength = 0 1003 h.contentLengthBytes = h.contentLengthBytes[:0] 1004 case consts.HeaderConnection: 1005 h.connectionClose = false 1006 case consts.HeaderTrailer: 1007 h.Trailer().ResetSkipNormalize() 1008 } 1009 h.h = delAllArgsBytes(h.h, key) 1010 } 1011 1012 // SetBytesV sets the given 'key: value' header. 1013 // 1014 // Use AddBytesV for setting multiple header values under the same key. 1015 func (h *ResponseHeader) SetBytesV(key string, value []byte) { 1016 k := getHeaderKeyBytes(&h.bufKV, key, h.disableNormalizing) 1017 h.SetCanonical(k, value) 1018 } 1019 1020 // Len returns the number of headers set, 1021 // i.e. the number of times f is called in VisitAll. 1022 func (h *ResponseHeader) Len() int { 1023 n := 0 1024 h.VisitAll(func(k, v []byte) { n++ }) 1025 return n 1026 } 1027 1028 // Len returns the number of headers set, 1029 // i.e. the number of times f is called in VisitAll. 1030 func (h *RequestHeader) Len() int { 1031 n := 0 1032 h.VisitAll(func(k, v []byte) { n++ }) 1033 return n 1034 } 1035 1036 // Reset clears request header. 1037 func (h *RequestHeader) Reset() { 1038 h.disableNormalizing = false 1039 h.Trailer().disableNormalizing = false 1040 h.ResetSkipNormalize() 1041 } 1042 1043 // SetByteRange sets 'Range: bytes=startPos-endPos' header. 1044 // 1045 // - If startPos is negative, then 'bytes=-startPos' value is set. 1046 // - If endPos is negative, then 'bytes=startPos-' value is set. 1047 func (h *RequestHeader) SetByteRange(startPos, endPos int) { 1048 b := h.bufKV.value[:0] 1049 b = append(b, bytestr.StrBytes...) 1050 b = append(b, '=') 1051 if startPos >= 0 { 1052 b = bytesconv.AppendUint(b, startPos) 1053 } else { 1054 endPos = -startPos 1055 } 1056 b = append(b, '-') 1057 if endPos >= 0 { 1058 b = bytesconv.AppendUint(b, endPos) 1059 } 1060 h.bufKV.value = b 1061 1062 h.SetCanonical(bytestr.StrRange, h.bufKV.value) 1063 } 1064 1065 // DelBytes deletes header with the given key. 1066 func (h *RequestHeader) DelBytes(key []byte) { 1067 h.bufKV.key = append(h.bufKV.key[:0], key...) 1068 utils.NormalizeHeaderKey(h.bufKV.key, h.disableNormalizing) 1069 h.del(h.bufKV.key) 1070 } 1071 1072 // Del deletes header with the given key. 1073 func (h *RequestHeader) Del(key string) { 1074 k := getHeaderKeyBytes(&h.bufKV, key, h.disableNormalizing) 1075 h.del(k) 1076 } 1077 1078 func (h *RequestHeader) SetArgBytes(key, value []byte, noValue bool) { 1079 h.h = setArgBytes(h.h, key, value, noValue) 1080 } 1081 1082 func (h *RequestHeader) del(key []byte) { 1083 switch string(key) { 1084 case consts.HeaderHost: 1085 h.host = h.host[:0] 1086 case consts.HeaderContentType: 1087 h.contentType = h.contentType[:0] 1088 case consts.HeaderUserAgent: 1089 h.userAgent = h.userAgent[:0] 1090 case consts.HeaderCookie: 1091 h.cookies = h.cookies[:0] 1092 case consts.HeaderContentLength: 1093 h.contentLength = 0 1094 h.contentLengthBytes = h.contentLengthBytes[:0] 1095 case consts.HeaderConnection: 1096 h.connectionClose = false 1097 case consts.HeaderTrailer: 1098 h.Trailer().ResetSkipNormalize() 1099 } 1100 h.h = delAllArgsBytes(h.h, key) 1101 } 1102 1103 // CopyTo copies all the headers to dst. 1104 func (h *RequestHeader) CopyTo(dst *RequestHeader) { 1105 dst.Reset() 1106 1107 dst.disableNormalizing = h.disableNormalizing 1108 dst.connectionClose = h.connectionClose 1109 dst.noDefaultContentType = h.noDefaultContentType 1110 1111 dst.contentLength = h.contentLength 1112 dst.contentLengthBytes = append(dst.contentLengthBytes[:0], h.contentLengthBytes...) 1113 dst.method = append(dst.method[:0], h.method...) 1114 dst.requestURI = append(dst.requestURI[:0], h.requestURI...) 1115 dst.host = append(dst.host[:0], h.host...) 1116 dst.contentType = append(dst.contentType[:0], h.contentType...) 1117 dst.userAgent = append(dst.userAgent[:0], h.userAgent...) 1118 h.Trailer().CopyTo(dst.Trailer()) 1119 dst.h = copyArgs(dst.h, h.h) 1120 dst.cookies = copyArgs(dst.cookies, h.cookies) 1121 dst.cookiesCollected = h.cookiesCollected 1122 dst.rawHeaders = append(dst.rawHeaders[:0], h.rawHeaders...) 1123 dst.protocol = h.protocol 1124 } 1125 1126 // Peek returns header value for the given key. 1127 // 1128 // Returned value is valid until the next call to RequestHeader. 1129 // Do not store references to returned value. Make copies instead. 1130 func (h *RequestHeader) Peek(key string) []byte { 1131 k := getHeaderKeyBytes(&h.bufKV, key, h.disableNormalizing) 1132 return h.peek(k) 1133 } 1134 1135 // SetMultipartFormBoundary sets the following Content-Type: 1136 // 'multipart/form-data; boundary=...' 1137 // where ... is substituted by the given boundary. 1138 func (h *RequestHeader) SetMultipartFormBoundary(boundary string) { 1139 b := h.bufKV.value[:0] 1140 b = append(b, bytestr.StrMultipartFormData...) 1141 b = append(b, ';', ' ') 1142 b = append(b, bytestr.StrBoundary...) 1143 b = append(b, '=') 1144 b = append(b, boundary...) 1145 h.bufKV.value = b 1146 1147 h.SetContentTypeBytes(h.bufKV.value) 1148 } 1149 1150 func (h *RequestHeader) ContentLengthBytes() []byte { 1151 return h.contentLengthBytes 1152 } 1153 1154 func (h *RequestHeader) SetContentLengthBytes(contentLength []byte) { 1155 h.contentLengthBytes = append(h.contentLengthBytes[:0], contentLength...) 1156 } 1157 1158 // SetContentTypeBytes sets Content-Type header value. 1159 func (h *RequestHeader) SetContentTypeBytes(contentType []byte) { 1160 h.contentType = append(h.contentType[:0], contentType...) 1161 } 1162 1163 // ContentType returns Content-Type header value. 1164 func (h *RequestHeader) ContentType() []byte { 1165 return h.contentType 1166 } 1167 1168 // SetNoDefaultContentType controls the default Content-Type header behaviour. 1169 // 1170 // When set to false, the Content-Type header is sent with a default value if no Content-Type value is specified. 1171 // When set to true, no Content-Type header is sent if no Content-Type value is specified. 1172 func (h *RequestHeader) SetNoDefaultContentType(b bool) { 1173 h.noDefaultContentType = b 1174 } 1175 1176 // SetContentLength sets Content-Length header value. 1177 // 1178 // Negative content-length sets 'Transfer-Encoding: chunked' header. 1179 func (h *RequestHeader) SetContentLength(contentLength int) { 1180 h.contentLength = contentLength 1181 if contentLength >= 0 { 1182 h.contentLengthBytes = bytesconv.AppendUint(h.contentLengthBytes[:0], contentLength) 1183 h.h = delAllArgsBytes(h.h, bytestr.StrTransferEncoding) 1184 } else { 1185 h.contentLengthBytes = h.contentLengthBytes[:0] 1186 h.h = setArgBytes(h.h, bytestr.StrTransferEncoding, bytestr.StrChunked, ArgsHasValue) 1187 } 1188 } 1189 1190 func (h *RequestHeader) InitContentLengthWithValue(contentLength int) { 1191 h.contentLength = contentLength 1192 } 1193 1194 // MultipartFormBoundary returns boundary part 1195 // from 'multipart/form-data; boundary=...' Content-Type. 1196 func (h *RequestHeader) MultipartFormBoundary() []byte { 1197 b := h.ContentType() 1198 if !bytes.HasPrefix(b, bytestr.StrMultipartFormData) { 1199 return nil 1200 } 1201 b = b[len(bytestr.StrMultipartFormData):] 1202 if len(b) == 0 || b[0] != ';' { 1203 return nil 1204 } 1205 1206 var n int 1207 for len(b) > 0 { 1208 n++ 1209 for len(b) > n && b[n] == ' ' { 1210 n++ 1211 } 1212 b = b[n:] 1213 if !bytes.HasPrefix(b, bytestr.StrBoundary) { 1214 if n = bytes.IndexByte(b, ';'); n < 0 { 1215 return nil 1216 } 1217 continue 1218 } 1219 1220 b = b[len(bytestr.StrBoundary):] 1221 if len(b) == 0 || b[0] != '=' { 1222 return nil 1223 } 1224 b = b[1:] 1225 if n = bytes.IndexByte(b, ';'); n >= 0 { 1226 b = b[:n] 1227 } 1228 if len(b) > 1 && b[0] == '"' && b[len(b)-1] == '"' { 1229 b = b[1 : len(b)-1] 1230 } 1231 return b 1232 } 1233 return nil 1234 } 1235 1236 // ConnectionClose returns true if 'Connection: close' header is set. 1237 func (h *RequestHeader) ConnectionClose() bool { 1238 return h.connectionClose 1239 } 1240 1241 // Method returns HTTP request method. 1242 func (h *RequestHeader) Method() []byte { 1243 if len(h.method) == 0 { 1244 return bytestr.StrGet 1245 } 1246 return h.method 1247 } 1248 1249 // IsGet returns true if request method is GET. 1250 func (h *RequestHeader) IsGet() bool { 1251 return bytes.Equal(h.Method(), bytestr.StrGet) 1252 } 1253 1254 // IsOptions returns true if request method is Options. 1255 func (h *RequestHeader) IsOptions() bool { 1256 return bytes.Equal(h.Method(), bytestr.StrOptions) 1257 } 1258 1259 // IsTrace returns true if request method is Trace. 1260 func (h *RequestHeader) IsTrace() bool { 1261 return bytes.Equal(h.Method(), bytestr.StrTrace) 1262 } 1263 1264 // SetHostBytes sets Host header value. 1265 func (h *RequestHeader) SetHostBytes(host []byte) { 1266 h.host = append(h.host[:0], host...) 1267 } 1268 1269 // SetRequestURIBytes sets RequestURI for the first HTTP request line. 1270 // RequestURI must be properly encoded. 1271 // Use URI.RequestURI for constructing proper RequestURI if unsure. 1272 func (h *RequestHeader) SetRequestURIBytes(requestURI []byte) { 1273 h.requestURI = append(h.requestURI[:0], requestURI...) 1274 } 1275 1276 // SetBytesKV sets the given 'key: value' header. 1277 // 1278 // Use AddBytesKV for setting multiple header values under the same key. 1279 func (h *RequestHeader) SetBytesKV(key, value []byte) { 1280 h.bufKV.key = append(h.bufKV.key[:0], key...) 1281 utils.NormalizeHeaderKey(h.bufKV.key, h.disableNormalizing) 1282 h.SetCanonical(h.bufKV.key, value) 1283 } 1284 1285 func (h *RequestHeader) AddArgBytes(key, value []byte, noValue bool) { 1286 h.h = appendArgBytes(h.h, key, value, noValue) 1287 } 1288 1289 // SetUserAgentBytes sets User-Agent header value. 1290 func (h *RequestHeader) SetUserAgentBytes(userAgent []byte) { 1291 h.userAgent = append(h.userAgent[:0], userAgent...) 1292 } 1293 1294 // SetCookie sets 'key: value' cookies. 1295 func (h *RequestHeader) SetCookie(key, value string) { 1296 h.collectCookies() 1297 h.cookies = setArg(h.cookies, key, value, ArgsHasValue) 1298 } 1299 1300 // SetCookie sets the given response cookie. 1301 // It is save re-using the cookie after the function returns. 1302 func (h *ResponseHeader) SetCookie(cookie *Cookie) { 1303 h.cookies = setArgBytes(h.cookies, cookie.Key(), cookie.Cookie(), ArgsHasValue) 1304 } 1305 1306 // Cookie returns cookie for the given key. 1307 func (h *RequestHeader) Cookie(key string) []byte { 1308 h.collectCookies() 1309 return peekArgStr(h.cookies, key) 1310 } 1311 1312 // Cookies returns all the request cookies. 1313 // 1314 // It's a good idea to call protocol.ReleaseCookie to reduce GC load after the cookie used. 1315 func (h *RequestHeader) Cookies() []*Cookie { 1316 var cookies []*Cookie 1317 h.VisitAllCookie(func(key, value []byte) { 1318 cookie := AcquireCookie() 1319 cookie.SetKeyBytes(key) 1320 cookie.SetValueBytes(value) 1321 cookies = append(cookies, cookie) 1322 }) 1323 return cookies 1324 } 1325 1326 func (h *RequestHeader) PeekRange() []byte { 1327 return h.peek(bytestr.StrRange) 1328 } 1329 1330 func (h *RequestHeader) PeekContentEncoding() []byte { 1331 return h.peek(bytestr.StrContentEncoding) 1332 } 1333 1334 // FullCookie returns complete cookie bytes 1335 func (h *RequestHeader) FullCookie() []byte { 1336 return h.Peek(consts.HeaderCookie) 1337 } 1338 1339 // DelCookie removes cookie under the given key. 1340 func (h *RequestHeader) DelCookie(key string) { 1341 h.collectCookies() 1342 h.cookies = delAllArgs(h.cookies, key) 1343 } 1344 1345 // DelAllCookies removes all the cookies from request headers. 1346 func (h *RequestHeader) DelAllCookies() { 1347 h.collectCookies() 1348 h.cookies = h.cookies[:0] 1349 } 1350 1351 // VisitAllCookie calls f for each request cookie. 1352 // 1353 // f must not retain references to key and/or value after returning. 1354 func (h *RequestHeader) VisitAllCookie(f func(key, value []byte)) { 1355 h.collectCookies() 1356 visitArgs(h.cookies, f) 1357 } 1358 1359 func (h *RequestHeader) collectCookies() { 1360 if h.cookiesCollected { 1361 return 1362 } 1363 1364 for i, n := 0, len(h.h); i < n; i++ { 1365 kv := &h.h[i] 1366 if bytes.Equal(kv.key, bytestr.StrCookie) { 1367 h.cookies = parseRequestCookies(h.cookies, kv.value) 1368 tmp := *kv 1369 copy(h.h[i:], h.h[i+1:]) 1370 n-- 1371 i-- 1372 h.h[n] = tmp 1373 h.h = h.h[:n] 1374 } 1375 } 1376 h.cookiesCollected = true 1377 } 1378 1379 func (h *RequestHeader) SetConnectionClose(close bool) { 1380 h.connectionClose = close 1381 } 1382 1383 // ResetConnectionClose clears 'Connection: close' header if it exists. 1384 func (h *RequestHeader) ResetConnectionClose() { 1385 if h.connectionClose { 1386 h.connectionClose = false 1387 h.h = delAllArgsBytes(h.h, bytestr.StrConnection) 1388 } 1389 } 1390 1391 // SetMethod sets HTTP request method. 1392 func (h *RequestHeader) SetMethod(method string) { 1393 h.method = append(h.method[:0], method...) 1394 } 1395 1396 // SetRequestURI sets RequestURI for the first HTTP request line. 1397 // RequestURI must be properly encoded. 1398 // Use URI.RequestURI for constructing proper RequestURI if unsure. 1399 func (h *RequestHeader) SetRequestURI(requestURI string) { 1400 h.requestURI = append(h.requestURI[:0], requestURI...) 1401 } 1402 1403 // Set sets the given 'key: value' header. 1404 // 1405 // Use Add for setting multiple header values under the same key. 1406 func (h *RequestHeader) Set(key, value string) { 1407 initHeaderKV(&h.bufKV, key, value, h.disableNormalizing) 1408 h.SetCanonical(h.bufKV.key, h.bufKV.value) 1409 } 1410 1411 func initHeaderKV(kv *argsKV, key, value string, disableNormalizing bool) { 1412 kv.key = getHeaderKeyBytes(kv, key, disableNormalizing) 1413 kv.value = append(kv.value[:0], value...) 1414 } 1415 1416 // SetCanonical sets the given 'key: value' header assuming that 1417 // key is in canonical form. 1418 func (h *RequestHeader) SetCanonical(key, value []byte) { 1419 if h.setSpecialHeader(key, value) { 1420 return 1421 } 1422 1423 h.h = setArgBytes(h.h, key, value, ArgsHasValue) 1424 } 1425 1426 func (h *RequestHeader) ResetSkipNormalize() { 1427 h.connectionClose = false 1428 h.protocol = "" 1429 h.noDefaultContentType = false 1430 1431 h.contentLength = 0 1432 h.contentLengthBytes = h.contentLengthBytes[:0] 1433 1434 h.method = h.method[:0] 1435 h.requestURI = h.requestURI[:0] 1436 h.host = h.host[:0] 1437 h.contentType = h.contentType[:0] 1438 h.userAgent = h.userAgent[:0] 1439 1440 h.h = h.h[:0] 1441 h.cookies = h.cookies[:0] 1442 h.cookiesCollected = false 1443 1444 h.rawHeaders = h.rawHeaders[:0] 1445 h.mulHeader = h.mulHeader[:0] 1446 h.Trailer().ResetSkipNormalize() 1447 } 1448 1449 func peekRawHeader(buf, key []byte) []byte { 1450 n := bytes.Index(buf, key) 1451 if n < 0 { 1452 return nil 1453 } 1454 if n > 0 && buf[n-1] != '\n' { 1455 return nil 1456 } 1457 n += len(key) 1458 if n >= len(buf) { 1459 return nil 1460 } 1461 if buf[n] != ':' { 1462 return nil 1463 } 1464 n++ 1465 if buf[n] != ' ' { 1466 return nil 1467 } 1468 n++ 1469 buf = buf[n:] 1470 n = bytes.IndexByte(buf, '\n') 1471 if n < 0 { 1472 return nil 1473 } 1474 if n > 0 && buf[n-1] == '\r' { 1475 n-- 1476 } 1477 return buf[:n] 1478 } 1479 1480 // Host returns Host header value. 1481 func (h *RequestHeader) Host() []byte { 1482 return h.host 1483 } 1484 1485 // UserAgent returns User-Agent header value. 1486 func (h *RequestHeader) UserAgent() []byte { 1487 return h.userAgent 1488 } 1489 1490 // DisableNormalizing disables header names' normalization. 1491 // 1492 // By default all the header names are normalized by uppercasing 1493 // the first letter and all the first letters following dashes, 1494 // while lowercasing all the other letters. 1495 // Examples: 1496 // 1497 // - CONNECTION -> Connection 1498 // - conteNT-tYPE -> Content-Type 1499 // - foo-bar-baz -> Foo-Bar-Baz 1500 // 1501 // Disable header names' normalization only if you know what are you doing. 1502 func (h *RequestHeader) DisableNormalizing() { 1503 h.disableNormalizing = true 1504 h.Trailer().DisableNormalizing() 1505 } 1506 1507 func (h *RequestHeader) IsDisableNormalizing() bool { 1508 return h.disableNormalizing 1509 } 1510 1511 // String returns request header representation. 1512 func (h *RequestHeader) String() string { 1513 return string(h.Header()) 1514 } 1515 1516 // VisitAll calls f for each header. 1517 // 1518 // f must not retain references to key and/or value after returning. 1519 // Copy key and/or value contents before returning if you need retaining them. 1520 // 1521 // To get the headers in order they were received use VisitAllInOrder. 1522 func (h *RequestHeader) VisitAll(f func(key, value []byte)) { 1523 host := h.Host() 1524 if len(host) > 0 { 1525 f(bytestr.StrHost, host) 1526 } 1527 if len(h.contentLengthBytes) > 0 { 1528 f(bytestr.StrContentLength, h.contentLengthBytes) 1529 } 1530 contentType := h.ContentType() 1531 if len(contentType) > 0 { 1532 f(bytestr.StrContentType, contentType) 1533 } 1534 userAgent := h.UserAgent() 1535 if len(userAgent) > 0 { 1536 f(bytestr.StrUserAgent, userAgent) 1537 } 1538 if !h.Trailer().Empty() { 1539 f(bytestr.StrTrailer, h.Trailer().GetBytes()) 1540 } 1541 1542 h.collectCookies() 1543 if len(h.cookies) > 0 { 1544 h.bufKV.value = appendRequestCookieBytes(h.bufKV.value[:0], h.cookies) 1545 f(bytestr.StrCookie, h.bufKV.value) 1546 } 1547 visitArgs(h.h, f) 1548 if h.ConnectionClose() { 1549 f(bytestr.StrConnection, bytestr.StrClose) 1550 } 1551 } 1552 1553 // VisitAllCustomHeader calls f for each header in header.h which contains all headers 1554 // except cookie, host, content-length, content-type, user-agent and connection. 1555 // 1556 // f must not retain references to key and/or value after returning. 1557 // Copy key and/or value contents before returning if you need retaining them. 1558 // 1559 // To get the headers in order they were received use VisitAllInOrder. 1560 func (h *RequestHeader) VisitAllCustomHeader(f func(key, value []byte)) { 1561 visitArgs(h.h, f) 1562 } 1563 1564 func ParseContentLength(b []byte) (int, error) { 1565 v, n, err := bytesconv.ParseUintBuf(b) 1566 if err != nil { 1567 return -1, err 1568 } 1569 if n != len(b) { 1570 return -1, errs.NewPublic("non-numeric chars at the end of Content-Length") 1571 } 1572 return v, nil 1573 } 1574 1575 func appendArgBytes(args []argsKV, key, value []byte, noValue bool) []argsKV { 1576 var kv *argsKV 1577 args, kv = allocArg(args) 1578 kv.key = append(kv.key[:0], key...) 1579 if noValue { 1580 kv.value = kv.value[:0] 1581 } else { 1582 kv.value = append(kv.value[:0], value...) 1583 } 1584 kv.noValue = noValue 1585 return args 1586 } 1587 1588 func appendArg(args []argsKV, key, value string, noValue bool) []argsKV { 1589 var kv *argsKV 1590 args, kv = allocArg(args) 1591 kv.key = append(kv.key[:0], key...) 1592 if noValue { 1593 kv.value = kv.value[:0] 1594 } else { 1595 kv.value = append(kv.value[:0], value...) 1596 } 1597 kv.noValue = noValue 1598 return args 1599 } 1600 1601 func (h *RequestHeader) peek(key []byte) []byte { 1602 switch string(key) { 1603 case consts.HeaderHost: 1604 return h.Host() 1605 case consts.HeaderContentType: 1606 return h.ContentType() 1607 case consts.HeaderUserAgent: 1608 return h.UserAgent() 1609 case consts.HeaderConnection: 1610 if h.ConnectionClose() { 1611 return bytestr.StrClose 1612 } 1613 return peekArgBytes(h.h, key) 1614 case consts.HeaderContentLength: 1615 return h.contentLengthBytes 1616 case consts.HeaderCookie: 1617 if h.cookiesCollected { 1618 return appendRequestCookieBytes(nil, h.cookies) 1619 } 1620 return peekArgBytes(h.h, key) 1621 case consts.HeaderTrailer: 1622 return h.Trailer().GetBytes() 1623 default: 1624 return peekArgBytes(h.h, key) 1625 } 1626 } 1627 1628 func (h *RequestHeader) Get(key string) string { 1629 return string(h.Peek(key)) 1630 } 1631 1632 func (h *ResponseHeader) Get(key string) string { 1633 return string(h.Peek(key)) 1634 } 1635 1636 // GetAll returns all header value for the given key 1637 // it is concurrent safety and long lifetime. 1638 func (h *RequestHeader) GetAll(key string) []string { 1639 res := make([]string, 0) 1640 headers := h.PeekAll(key) 1641 for _, header := range headers { 1642 res = append(res, string(header)) 1643 } 1644 return res 1645 } 1646 1647 // GetAll returns all header value for the given key and is concurrent safety. 1648 // it is concurrent safety and long lifetime. 1649 func (h *ResponseHeader) GetAll(key string) []string { 1650 res := make([]string, 0) 1651 headers := h.PeekAll(key) 1652 for _, header := range headers { 1653 res = append(res, string(header)) 1654 } 1655 return res 1656 } 1657 1658 func appendHeaderLine(dst, key, value []byte) []byte { 1659 for _, k := range key { 1660 // if header field contains invalid key, just skip it. 1661 if bytesconv.ValidHeaderFieldNameTable[k] == 0 { 1662 return dst 1663 } 1664 } 1665 dst = append(dst, key...) 1666 dst = append(dst, bytestr.StrColonSpace...) 1667 dst = append(dst, newlineToSpace(value)...) 1668 return append(dst, bytestr.StrCRLF...) 1669 } 1670 1671 // newlineToSpace will return a copy of the original byte slice. 1672 func newlineToSpace(val []byte) []byte { 1673 filteredVal := make([]byte, len(val)) 1674 copy(filteredVal, val) 1675 for i := 0; i < len(filteredVal); i++ { 1676 filteredVal[i] = bytesconv.NewlineToSpaceTable[filteredVal[i]] 1677 } 1678 return filteredVal 1679 } 1680 1681 func UpdateServerDate() { 1682 refreshServerDate() 1683 go func() { 1684 for { 1685 time.Sleep(time.Second) 1686 refreshServerDate() 1687 } 1688 }() 1689 } 1690 1691 func refreshServerDate() { 1692 b := bytesconv.AppendHTTPDate(make([]byte, 0, len(http.TimeFormat)), time.Now()) 1693 ServerDate.Store(b) 1694 } 1695 1696 func getHeaderKeyBytes(kv *argsKV, key string, disableNormalizing bool) []byte { 1697 kv.key = append(kv.key[:0], key...) 1698 utils.NormalizeHeaderKey(kv.key, disableNormalizing) 1699 return kv.key 1700 } 1701 1702 // SetMethodBytes sets HTTP request method. 1703 func (h *RequestHeader) SetMethodBytes(method []byte) { 1704 h.method = append(h.method[:0], method...) 1705 } 1706 1707 // DisableNormalizing disables header names' normalization. 1708 // 1709 // By default all the header names are normalized by uppercasing 1710 // the first letter and all the first letters following dashes, 1711 // while lowercasing all the other letters. 1712 // Examples: 1713 // 1714 // - CONNECTION -> Connection 1715 // - conteNT-tYPE -> Content-Type 1716 // - foo-bar-baz -> Foo-Bar-Baz 1717 // 1718 // Disable header names' normalization only if you know what are you doing. 1719 func (h *ResponseHeader) DisableNormalizing() { 1720 h.disableNormalizing = true 1721 h.Trailer().DisableNormalizing() 1722 } 1723 1724 // setSpecialHeader handles special headers and return true when a header is processed. 1725 func (h *ResponseHeader) setSpecialHeader(key, value []byte) bool { 1726 if len(key) == 0 { 1727 return false 1728 } 1729 1730 switch key[0] | 0x20 { 1731 case 'c': 1732 if utils.CaseInsensitiveCompare(bytestr.StrContentType, key) { 1733 h.SetContentTypeBytes(value) 1734 return true 1735 } else if utils.CaseInsensitiveCompare(bytestr.StrContentLength, key) { 1736 if contentLength, err := ParseContentLength(value); err == nil { 1737 h.contentLength = contentLength 1738 h.contentLengthBytes = append(h.contentLengthBytes[:0], value...) 1739 } 1740 return true 1741 } else if utils.CaseInsensitiveCompare(bytestr.StrContentEncoding, key) { 1742 h.SetContentEncodingBytes(value) 1743 return true 1744 } else if utils.CaseInsensitiveCompare(bytestr.StrConnection, key) { 1745 if bytes.Equal(bytestr.StrClose, value) { 1746 h.SetConnectionClose(true) 1747 } else { 1748 h.ResetConnectionClose() 1749 h.h = setArgBytes(h.h, key, value, ArgsHasValue) 1750 } 1751 return true 1752 } 1753 case 's': 1754 if utils.CaseInsensitiveCompare(bytestr.StrServer, key) { 1755 h.SetServerBytes(value) 1756 return true 1757 } else if utils.CaseInsensitiveCompare(bytestr.StrSetCookie, key) { 1758 var kv *argsKV 1759 h.cookies, kv = allocArg(h.cookies) 1760 kv.key = getCookieKey(kv.key, value) 1761 kv.value = append(kv.value[:0], value...) 1762 return true 1763 } 1764 case 't': 1765 if utils.CaseInsensitiveCompare(bytestr.StrTransferEncoding, key) { 1766 // Transfer-Encoding is managed automatically. 1767 return true 1768 } else if utils.CaseInsensitiveCompare(bytestr.StrTrailer, key) { 1769 // copy value to avoid panic 1770 value = append(h.bufKV.value[:0], value...) 1771 h.Trailer().SetTrailers(value) 1772 return true 1773 } 1774 case 'd': 1775 if utils.CaseInsensitiveCompare(bytestr.StrDate, key) { 1776 // Date is managed automatically. 1777 return true 1778 } 1779 } 1780 1781 return false 1782 } 1783 1784 // setSpecialHeader handles special headers and return true when a header is processed. 1785 func (h *RequestHeader) setSpecialHeader(key, value []byte) bool { 1786 if len(key) == 0 { 1787 return false 1788 } 1789 1790 switch key[0] | 0x20 { 1791 case 'c': 1792 if utils.CaseInsensitiveCompare(bytestr.StrContentType, key) { 1793 h.SetContentTypeBytes(value) 1794 return true 1795 } else if utils.CaseInsensitiveCompare(bytestr.StrContentLength, key) { 1796 if contentLength, err := ParseContentLength(value); err == nil { 1797 h.contentLength = contentLength 1798 h.contentLengthBytes = append(h.contentLengthBytes[:0], value...) 1799 } 1800 return true 1801 } else if utils.CaseInsensitiveCompare(bytestr.StrConnection, key) { 1802 if bytes.Equal(bytestr.StrClose, value) { 1803 h.SetConnectionClose(true) 1804 } else { 1805 h.ResetConnectionClose() 1806 h.h = setArgBytes(h.h, key, value, ArgsHasValue) 1807 } 1808 return true 1809 } else if utils.CaseInsensitiveCompare(bytestr.StrCookie, key) { 1810 h.collectCookies() 1811 h.cookies = parseRequestCookies(h.cookies, value) 1812 return true 1813 } 1814 case 't': 1815 if utils.CaseInsensitiveCompare(bytestr.StrTransferEncoding, key) { 1816 // Transfer-Encoding is managed automatically. 1817 return true 1818 } else if utils.CaseInsensitiveCompare(bytestr.StrTrailer, key) { 1819 // copy value to avoid panic 1820 value = append(h.bufKV.value[:0], value...) 1821 h.Trailer().SetTrailers(value) 1822 return true 1823 } 1824 case 'h': 1825 if utils.CaseInsensitiveCompare(bytestr.StrHost, key) { 1826 h.SetHostBytes(value) 1827 return true 1828 } 1829 case 'u': 1830 if utils.CaseInsensitiveCompare(bytestr.StrUserAgent, key) { 1831 h.SetUserAgentBytes(value) 1832 return true 1833 } 1834 } 1835 1836 return false 1837 } 1838 1839 // Trailer returns the Trailer of HTTP Header. 1840 func (h *ResponseHeader) Trailer() *Trailer { 1841 if h.trailer == nil { 1842 h.trailer = new(Trailer) 1843 } 1844 return h.trailer 1845 } 1846 1847 // Trailer returns the Trailer of HTTP Header. 1848 func (h *RequestHeader) Trailer() *Trailer { 1849 if h.trailer == nil { 1850 h.trailer = new(Trailer) 1851 } 1852 return h.trailer 1853 } 1854 1855 func (h *ResponseHeader) SetProtocol(p string) { 1856 h.protocol = p 1857 } 1858 1859 func (h *ResponseHeader) GetProtocol() string { 1860 return h.protocol 1861 }