func (h *ResponseHeader) SetCookie(cookie *Cookie) {
	h.cookies = setArgBytes(h.cookies, cookie.Key(), cookie.Cookie())
}
SetCookie sets the given response cookie.
package fasthttp
import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"sync/atomic"
	"time"
)
type ResponseHeader struct {
	noCopy noCopy
	disableNormalizing bool
	noHTTP11           bool
	connectionClose    bool
	statusCode         int
	contentLength      int
	contentLengthBytes []byte
	contentType []byte
	server      []byte
	h     []argsKV
	bufKV argsKV
	cookies []argsKV
}
type RequestHeader struct {
	noCopy noCopy
	disableNormalizing bool
	noHTTP11           bool
	connectionClose    bool
	isGet              bool
	cookiesCollected bool
	rawHeadersParsed bool
	contentLength      int
	contentLengthBytes []byte
	method      []byte
	requestURI  []byte
	host        []byte
	contentType []byte
	userAgent   []byte
	h     []argsKV
	bufKV argsKV
	cookies []argsKV
	rawHeaders []byte
}
func (h *ResponseHeader) SetContentRange(startPos, endPos, contentLength int) {
	b := h.bufKV.value[:0]
	b = append(b, strBytes...)
	b = append(b, ' ')
	b = AppendUint(b, startPos)
	b = append(b, '-')
	b = AppendUint(b, endPos)
	b = append(b, '/')
	b = AppendUint(b, contentLength)
	h.bufKV.value = b
	h.SetCanonical(strContentRange, h.bufKV.value)
}
func (h *RequestHeader) SetByteRange(startPos, endPos int) {
	h.parseRawHeaders()
	b := h.bufKV.value[:0]
	b = append(b, strBytes...)
	b = append(b, '=')
	if startPos >= 0 {
		b = AppendUint(b, startPos)
	} else {
		endPos = -startPos
	}
	b = append(b, '-')
	if endPos >= 0 {
		b = AppendUint(b, endPos)
	}
	h.bufKV.value = b
	h.SetCanonical(strRange, h.bufKV.value)
}
func (h *ResponseHeader) StatusCode() int {
	return h.statusCode
}
func (h *ResponseHeader) SetStatusCode(statusCode int) {
	h.statusCode = statusCode
}
func (h *ResponseHeader) SetLastModified(t time.Time) {
	h.bufKV.value = AppendHTTPDate(h.bufKV.value[:0], t)
	h.SetCanonical(strLastModified, h.bufKV.value)
}
func (h *ResponseHeader) ConnectionClose() bool {
	return h.connectionClose
}
func (h *ResponseHeader) SetConnectionClose() {
	h.connectionClose = true
}
func (h *ResponseHeader) ResetConnectionClose() {
	if h.connectionClose {
		h.connectionClose = false
		h.h = delAllArgsBytes(h.h, strConnection)
	}
}
func (h *RequestHeader) ConnectionClose() bool {
	h.parseRawHeaders()
	return h.connectionClose
}
func (h *RequestHeader) connectionCloseFast() bool {
	return h.connectionClose
}
func (h *RequestHeader) SetConnectionClose() {
	h.connectionClose = true
}
func (h *RequestHeader) ResetConnectionClose() {
	h.parseRawHeaders()
	if h.connectionClose {
		h.connectionClose = false
		h.h = delAllArgsBytes(h.h, strConnection)
	}
}
func (h *ResponseHeader) ConnectionUpgrade() bool {
	return hasHeaderValue(h.Peek("Connection"), strUpgrade)
}
func (h *RequestHeader) ConnectionUpgrade() bool {
	h.parseRawHeaders()
	return hasHeaderValue(h.Peek("Connection"), strUpgrade)
}
func (h *ResponseHeader) ContentLength() int {
	return h.contentLength
}
func (h *ResponseHeader) SetContentLength(contentLength int) {
	if h.mustSkipContentLength() {
		return
	}
	h.contentLength = contentLength
	if contentLength >= 0 {
		h.contentLengthBytes = AppendUint(h.contentLengthBytes[:0], contentLength)
		h.h = delAllArgsBytes(h.h, strTransferEncoding)
	} else {
		h.contentLengthBytes = h.contentLengthBytes[:0]
		value := strChunked
		if contentLength == -2 {
			h.SetConnectionClose()
			value = strIdentity
		}
		h.h = setArgBytes(h.h, strTransferEncoding, value)
	}
}
func (h *ResponseHeader) mustSkipContentLength() bool {
	statusCode := h.StatusCode()
	if statusCode < 100 || statusCode == StatusOK {
		return false
	}
	return statusCode == StatusNotModified || statusCode == StatusNoContent || statusCode < 200
}
func (h *RequestHeader) ContentLength() int {
	if h.noBody() {
		return 0
	}
	h.parseRawHeaders()
	return h.contentLength
}
func (h *RequestHeader) SetContentLength(contentLength int) {
	h.parseRawHeaders()
	h.contentLength = contentLength
	if contentLength >= 0 {
		h.contentLengthBytes = AppendUint(h.contentLengthBytes[:0], contentLength)
		h.h = delAllArgsBytes(h.h, strTransferEncoding)
	} else {
		h.contentLengthBytes = h.contentLengthBytes[:0]
		h.h = setArgBytes(h.h, strTransferEncoding, strChunked)
	}
}
func (h *ResponseHeader) ContentType() []byte {
	contentType := h.contentType
	if len(h.contentType) == 0 {
		contentType = defaultContentType
	}
	return contentType
}
func (h *ResponseHeader) SetContentType(contentType string) {
	h.contentType = append(h.contentType[:0], contentType...)
}
func (h *ResponseHeader) SetContentTypeBytes(contentType []byte) {
	h.contentType = append(h.contentType[:0], contentType...)
}
func (h *ResponseHeader) Server() []byte {
	return h.server
}
func (h *ResponseHeader) SetServer(server string) {
	h.server = append(h.server[:0], server...)
}
func (h *ResponseHeader) SetServerBytes(server []byte) {
	h.server = append(h.server[:0], server...)
}
func (h *RequestHeader) ContentType() []byte {
	h.parseRawHeaders()
	return h.contentType
}
func (h *RequestHeader) SetContentType(contentType string) {
	h.parseRawHeaders()
	h.contentType = append(h.contentType[:0], contentType...)
}
func (h *RequestHeader) SetContentTypeBytes(contentType []byte) {
	h.parseRawHeaders()
	h.contentType = append(h.contentType[:0], contentType...)
}
func (h *RequestHeader) SetMultipartFormBoundary(boundary string) {
	h.parseRawHeaders()
	b := h.bufKV.value[:0]
	b = append(b, strMultipartFormData...)
	b = append(b, ';', ' ')
	b = append(b, strBoundary...)
	b = append(b, '=')
	b = append(b, boundary...)
	h.bufKV.value = b
	h.SetContentTypeBytes(h.bufKV.value)
}
func (h *RequestHeader) SetMultipartFormBoundaryBytes(boundary []byte) {
	h.parseRawHeaders()
	b := h.bufKV.value[:0]
	b = append(b, strMultipartFormData...)
	b = append(b, ';', ' ')
	b = append(b, strBoundary...)
	b = append(b, '=')
	b = append(b, boundary...)
	h.bufKV.value = b
	h.SetContentTypeBytes(h.bufKV.value)
}
func (h *RequestHeader) MultipartFormBoundary() []byte {
	b := h.ContentType()
	if !bytes.HasPrefix(b, strMultipartFormData) {
		return nil
	}
	b = b[len(strMultipartFormData):]
	if len(b) == 0 || b[0] != ';' {
		return nil
	}
	var n int
	for len(b) > 0 {
		n++
		for len(b) > n && b[n] == ' ' {
			n++
		}
		b = b[n:]
		if !bytes.HasPrefix(b, strBoundary) {
			if n = bytes.IndexByte(b, ';'); n < 0 {
				return nil
			}
			continue
		}
		b = b[len(strBoundary):]
		if len(b) == 0 || b[0] != '=' {
			return nil
		}
		b = b[1:]
		if n = bytes.IndexByte(b, ';'); n >= 0 {
			b = b[:n]
		}
		return b
	}
	return nil
}
func (h *RequestHeader) Host() []byte {
	if len(h.host) > 0 {
		return h.host
	}
	if !h.rawHeadersParsed {
		host := peekRawHeader(h.rawHeaders, strHost)
		if len(host) > 0 {
			h.host = append(h.host[:0], host...)
			return h.host
		}
	}
	h.parseRawHeaders()
	return h.host
}
func (h *RequestHeader) SetHost(host string) {
	h.parseRawHeaders()
	h.host = append(h.host[:0], host...)
}
func (h *RequestHeader) SetHostBytes(host []byte) {
	h.parseRawHeaders()
	h.host = append(h.host[:0], host...)
}
func (h *RequestHeader) UserAgent() []byte {
	h.parseRawHeaders()
	return h.userAgent
}
func (h *RequestHeader) SetUserAgent(userAgent string) {
	h.parseRawHeaders()
	h.userAgent = append(h.userAgent[:0], userAgent...)
}
func (h *RequestHeader) SetUserAgentBytes(userAgent []byte) {
	h.parseRawHeaders()
	h.userAgent = append(h.userAgent[:0], userAgent...)
}
func (h *RequestHeader) Referer() []byte {
	return h.PeekBytes(strReferer)
}
func (h *RequestHeader) SetReferer(referer string) {
	h.SetBytesK(strReferer, referer)
}
func (h *RequestHeader) SetRefererBytes(referer []byte) {
	h.SetCanonical(strReferer, referer)
}
func (h *RequestHeader) Method() []byte {
	if len(h.method) == 0 {
		return strGet
	}
	return h.method
}
func (h *RequestHeader) SetMethod(method string) {
	h.method = append(h.method, method...)
}
func (h *RequestHeader) SetMethodBytes(method []byte) {
	h.method = append(h.method[:0], method...)
}
func (h *RequestHeader) RequestURI() []byte {
	requestURI := h.requestURI
	if len(requestURI) == 0 {
		requestURI = strSlash
	}
	return requestURI
}
func (h *RequestHeader) SetRequestURI(requestURI string) {
	h.requestURI = append(h.requestURI[:0], requestURI...)
}
func (h *RequestHeader) SetRequestURIBytes(requestURI []byte) {
	h.requestURI = append(h.requestURI[:0], requestURI...)
}
func (h *RequestHeader) IsGet() bool {
	if !h.isGet {
		h.isGet = bytes.Equal(h.Method(), strGet)
	}
	return h.isGet
}
func (h *RequestHeader) IsPost() bool {
	return bytes.Equal(h.Method(), strPost)
}
func (h *RequestHeader) IsPut() bool {
	return bytes.Equal(h.Method(), strPut)
}
func (h *RequestHeader) IsHead() bool {
	if h.isGet {
		return false
	}
	return bytes.Equal(h.Method(), strHead)
}
func (h *RequestHeader) IsHTTP11() bool {
	return !h.noHTTP11
}
func (h *ResponseHeader) IsHTTP11() bool {
	return !h.noHTTP11
}
func (h *RequestHeader) HasAcceptEncoding(acceptEncoding string) bool {
	h.bufKV.value = append(h.bufKV.value[:0], acceptEncoding...)
	return h.HasAcceptEncodingBytes(h.bufKV.value)
}
func (h *RequestHeader) HasAcceptEncodingBytes(acceptEncoding []byte) bool {
	ae := h.peek(strAcceptEncoding)
	n := bytes.Index(ae, acceptEncoding)
	if n < 0 {
		return false
	}
	b := ae[n+len(acceptEncoding):]
	if len(b) > 0 && b[0] != ',' {
		return false
	}
	if n == 0 {
		return true
	}
	return ae[n-1] == ' '
}
func (h *ResponseHeader) Len() int {
	n := 0
	h.VisitAll(func(k, v []byte) { n++ })
	return n
}
func (h *RequestHeader) Len() int {
	n := 0
	h.VisitAll(func(k, v []byte) { n++ })
	return n
}
func (h *RequestHeader) DisableNormalizing() {
	h.disableNormalizing = true
}
func (h *ResponseHeader) DisableNormalizing() {
	h.disableNormalizing = true
}
func (h *ResponseHeader) Reset() {
	h.disableNormalizing = false
	h.resetSkipNormalize()
}
func (h *ResponseHeader) resetSkipNormalize() {
	h.noHTTP11 = false
	h.connectionClose = false
	h.statusCode = 0
	h.contentLength = 0
	h.contentLengthBytes = h.contentLengthBytes[:0]
	h.contentType = h.contentType[:0]
	h.server = h.server[:0]
	h.h = h.h[:0]
	h.cookies = h.cookies[:0]
}
func (h *RequestHeader) Reset() {
	h.disableNormalizing = false
	h.resetSkipNormalize()
}
func (h *RequestHeader) resetSkipNormalize() {
	h.noHTTP11 = false
	h.connectionClose = false
	h.isGet = false
	h.contentLength = 0
	h.contentLengthBytes = h.contentLengthBytes[:0]
	h.method = h.method[:0]
	h.requestURI = h.requestURI[:0]
	h.host = h.host[:0]
	h.contentType = h.contentType[:0]
	h.userAgent = h.userAgent[:0]
	h.h = h.h[:0]
	h.cookies = h.cookies[:0]
	h.cookiesCollected = false
	h.rawHeaders = h.rawHeaders[:0]
	h.rawHeadersParsed = false
}
func (h *ResponseHeader) CopyTo(dst *ResponseHeader) {
	dst.Reset()
	dst.disableNormalizing = h.disableNormalizing
	dst.noHTTP11 = h.noHTTP11
	dst.connectionClose = h.connectionClose
	dst.statusCode = h.statusCode
	dst.contentLength = h.contentLength
	dst.contentLengthBytes = append(dst.contentLengthBytes[:0], h.contentLengthBytes...)
	dst.contentType = append(dst.contentType[:0], h.contentType...)
	dst.server = append(dst.server[:0], h.server...)
	dst.h = copyArgs(dst.h, h.h)
	dst.cookies = copyArgs(dst.cookies, h.cookies)
}
func (h *RequestHeader) CopyTo(dst *RequestHeader) {
	dst.Reset()
	dst.disableNormalizing = h.disableNormalizing
	dst.noHTTP11 = h.noHTTP11
	dst.connectionClose = h.connectionClose
	dst.isGet = h.isGet
	dst.contentLength = h.contentLength
	dst.contentLengthBytes = append(dst.contentLengthBytes[:0], h.contentLengthBytes...)
	dst.method = append(dst.method[:0], h.method...)
	dst.requestURI = append(dst.requestURI[:0], h.requestURI...)
	dst.host = append(dst.host[:0], h.host...)
	dst.contentType = append(dst.contentType[:0], h.contentType...)
	dst.userAgent = append(dst.userAgent[:0], h.userAgent...)
	dst.h = copyArgs(dst.h, h.h)
	dst.cookies = copyArgs(dst.cookies, h.cookies)
	dst.cookiesCollected = h.cookiesCollected
	dst.rawHeaders = append(dst.rawHeaders[:0], h.rawHeaders...)
	dst.rawHeadersParsed = h.rawHeadersParsed
}
func (h *ResponseHeader) VisitAll(f func(key, value []byte)) {
	if len(h.contentLengthBytes) > 0 {
		f(strContentLength, h.contentLengthBytes)
	}
	contentType := h.ContentType()
	if len(contentType) > 0 {
		f(strContentType, contentType)
	}
	server := h.Server()
	if len(server) > 0 {
		f(strServer, server)
	}
	if len(h.cookies) > 0 {
		visitArgs(h.cookies, func(k, v []byte) {
			f(strSetCookie, v)
		})
	}
	visitArgs(h.h, f)
	if h.ConnectionClose() {
		f(strConnection, strClose)
	}
}
func (h *ResponseHeader) VisitAllCookie(f func(key, value []byte)) {
	visitArgs(h.cookies, f)
}
func (h *RequestHeader) VisitAllCookie(f func(key, value []byte)) {
	h.parseRawHeaders()
	h.collectCookies()
	visitArgs(h.cookies, f)
}
func (h *RequestHeader) VisitAll(f func(key, value []byte)) {
	h.parseRawHeaders()
	host := h.Host()
	if len(host) > 0 {
		f(strHost, host)
	}
	if len(h.contentLengthBytes) > 0 {
		f(strContentLength, h.contentLengthBytes)
	}
	contentType := h.ContentType()
	if len(contentType) > 0 {
		f(strContentType, contentType)
	}
	userAgent := h.UserAgent()
	if len(userAgent) > 0 {
		f(strUserAgent, userAgent)
	}
	h.collectCookies()
	if len(h.cookies) > 0 {
		h.bufKV.value = appendRequestCookieBytes(h.bufKV.value[:0], h.cookies)
		f(strCookie, h.bufKV.value)
	}
	visitArgs(h.h, f)
	if h.ConnectionClose() {
		f(strConnection, strClose)
	}
}
func (h *ResponseHeader) Del(key string) {
	k := getHeaderKeyBytes(&h.bufKV, key, h.disableNormalizing)
	h.del(k)
}
func (h *ResponseHeader) DelBytes(key []byte) {
	h.bufKV.key = append(h.bufKV.key[:0], key...)
	normalizeHeaderKey(h.bufKV.key, h.disableNormalizing)
	h.del(h.bufKV.key)
}
func (h *ResponseHeader) del(key []byte) {
	switch string(key) {
	case "Content-Type":
		h.contentType = h.contentType[:0]
	case "Server":
		h.server = h.server[:0]
	case "Set-Cookie":
		h.cookies = h.cookies[:0]
	case "Content-Length":
		h.contentLength = 0
		h.contentLengthBytes = h.contentLengthBytes[:0]
	case "Connection":
		h.connectionClose = false
	}
	h.h = delAllArgsBytes(h.h, key)
}
func (h *RequestHeader) Del(key string) {
	h.parseRawHeaders()
	k := getHeaderKeyBytes(&h.bufKV, key, h.disableNormalizing)
	h.del(k)
}
func (h *RequestHeader) DelBytes(key []byte) {
	h.parseRawHeaders()
	h.bufKV.key = append(h.bufKV.key[:0], key...)
	normalizeHeaderKey(h.bufKV.key, h.disableNormalizing)
	h.del(h.bufKV.key)
}
func (h *RequestHeader) del(key []byte) {
	switch string(key) {
	case "Host":
		h.host = h.host[:0]
	case "Content-Type":
		h.contentType = h.contentType[:0]
	case "User-Agent":
		h.userAgent = h.userAgent[:0]
	case "Cookie":
		h.cookies = h.cookies[:0]
	case "Content-Length":
		h.contentLength = 0
		h.contentLengthBytes = h.contentLengthBytes[:0]
	case "Connection":
		h.connectionClose = false
	}
	h.h = delAllArgsBytes(h.h, key)
}
func (h *ResponseHeader) Add(key, value string) {
	k := getHeaderKeyBytes(&h.bufKV, key, h.disableNormalizing)
	h.h = appendArg(h.h, b2s(k), value)
}
func (h *ResponseHeader) AddBytesK(key []byte, value string) {
	h.Add(b2s(key), value)
}
func (h *ResponseHeader) AddBytesV(key string, value []byte) {
	h.Add(key, b2s(value))
}
func (h *ResponseHeader) AddBytesKV(key, value []byte) {
	h.Add(b2s(key), b2s(value))
}
func (h *ResponseHeader) Set(key, value string) {
	initHeaderKV(&h.bufKV, key, value, h.disableNormalizing)
	h.SetCanonical(h.bufKV.key, h.bufKV.value)
}
func (h *ResponseHeader) SetBytesK(key []byte, value string) {
	h.bufKV.value = append(h.bufKV.value[:0], value...)
	h.SetBytesKV(key, h.bufKV.value)
}
func (h *ResponseHeader) SetBytesV(key string, value []byte) {
	k := getHeaderKeyBytes(&h.bufKV, key, h.disableNormalizing)
	h.SetCanonical(k, value)
}
func (h *ResponseHeader) SetBytesKV(key, value []byte) {
	h.bufKV.key = append(h.bufKV.key[:0], key...)
	normalizeHeaderKey(h.bufKV.key, h.disableNormalizing)
	h.SetCanonical(h.bufKV.key, value)
}
func (h *ResponseHeader) SetCanonical(key, value []byte) {
	switch string(key) {
	case "Content-Type":
		h.SetContentTypeBytes(value)
	case "Server":
		h.SetServerBytes(value)
	case "Set-Cookie":
		var kv *argsKV
		h.cookies, kv = allocArg(h.cookies)
		kv.key = getCookieKey(kv.key, value)
		kv.value = append(kv.value[:0], value...)
	case "Content-Length":
		if contentLength, err := parseContentLength(value); err == nil {
			h.contentLength = contentLength
			h.contentLengthBytes = append(h.contentLengthBytes[:0], value...)
		}
	case "Connection":
		if bytes.Equal(strClose, value) {
			h.SetConnectionClose()
		} else {
			h.ResetConnectionClose()
			h.h = setArgBytes(h.h, key, value)
		}
	case "Transfer-Encoding":
	case "Date":
	default:
		h.h = setArgBytes(h.h, key, value)
	}
}