Repository: valyala/fasthttp
Pull request #581 (2019-05-28 09:16:40)

Support SameSite value "None" cookie attribute
As you may have heard Google recently announced changes coming to Chrome with the release of version 76 in July 2019. This change will directly impact the handling of 3rd party cookies.

For Chrome, set the cookie attribute “SameSite = None”, so that your cookie will be sent in the third party context. Leaving the attribute of “SameSite” unspecified would result in your cookie not being sent in case the user enables the “same-site-by-default-cookies” setting in their browser.
Set "SameSite = None"  is required is this case alongside "Secure"

You can find more detailed information here: 
https://tools.ietf.org/html/draft-west-cookie-incrementalism-00
https://blog.chromium.org/2019/05/improving-privacy-and-security-on-web.html


RemiSirdata: Mike West (Chrome security team) indicate default value to Lax have been suggest for 77 (September) for not approved yet, Secure bit either.

Patch:
diff --git a/cookie.go b/cookie.go
index 8137643..fb6618a 100644
--- a/cookie.go
+++ b/cookie.go
@@ -31,6 +31,9 @@ const (
 	CookieSameSiteLaxMode
 	// CookieSameSiteStrictMode sets the SameSite flag with the "Strict" parameter
 	CookieSameSiteStrictMode
+	// CookieSameSiteNoneMode sets the SameSite flag with the "None" parameter
+	// see https://tools.ietf.org/html/draft-west-cookie-incrementalism-00
+	CookieSameSiteNoneMode
 )
 
 // AcquireCookie returns an empty Cookie object from the pool.
@@ -119,8 +122,12 @@ func (c *Cookie) SameSite() CookieSameSite {
 }
 
 // SetSameSite sets the cookie's SameSite flag to the given value.
+// set value CookieSameSiteNoneMode will set Secure to true also to avoid browser rejection
 func (c *Cookie) SetSameSite(mode CookieSameSite) {
 	c.sameSite = mode
+	if mode == CookieSameSiteNoneMode {
+		c.SetSecure(true)
+	}
 }
 
 // Path returns cookie path.
@@ -288,6 +295,11 @@ func (c *Cookie) AppendBytes(dst []byte) []byte {
 		dst = append(dst, strCookieSameSite...)
 		dst = append(dst, '=')
 		dst = append(dst, strCookieSameSiteStrict...)
+	case CookieSameSiteNoneMode:
+		dst = append(dst, ';', ' ')
+		dst = append(dst, strCookieSameSite...)
+		dst = append(dst, '=')
+		dst = append(dst, strCookieSameSiteNone...)
 	}
 	return dst
 }
@@ -386,6 +398,10 @@ func (c *Cookie) ParseBytes(src []byte) error {
 						if caseInsensitiveCompare(strCookieSameSiteStrict, kv.value) {
 							c.sameSite = CookieSameSiteStrictMode
 						}
+					case 'n': // "none"
+						if caseInsensitiveCompare(strCookieSameSiteNone, kv.value) {
+							c.sameSite = CookieSameSiteNoneMode
+						}
 					}
 				}
 			}
diff --git a/header.go b/header.go
index 190ac32..85f9809 100644
--- a/header.go
+++ b/header.go
@@ -178,13 +178,13 @@ func (h *RequestHeader) ResetConnectionClose() {
 
 // ConnectionUpgrade returns true if 'Connection: Upgrade' header is set.
 func (h *ResponseHeader) ConnectionUpgrade() bool {
-	return hasHeaderValue(h.Peek("Connection"), strUpgrade)
+	return hasHeaderValue(h.Peek(HeaderConnection), strUpgrade)
 }
 
 // ConnectionUpgrade returns true if 'Connection: Upgrade' header is set.
 func (h *RequestHeader) ConnectionUpgrade() bool {
 	h.parseRawHeaders()
-	return hasHeaderValue(h.Peek("Connection"), strUpgrade)
+	return hasHeaderValue(h.Peek(HeaderConnection), strUpgrade)
 }
 
 // PeekCookie is able to returns cookie by a given key from response.
@@ -845,16 +845,16 @@ func (h *ResponseHeader) DelBytes(key []byte) {
 
 func (h *ResponseHeader) del(key []byte) {
 	switch string(key) {
-	case "Content-Type":
+	case HeaderContentType:
 		h.contentType = h.contentType[:0]
-	case "Server":
+	case HeaderServer:
 		h.server = h.server[:0]
-	case "Set-Cookie":
+	case HeaderSetCookie:
 		h.cookies = h.cookies[:0]
-	case "Content-Length":
+	case HeaderContentLength:
 		h.contentLength = 0
 		h.contentLengthBytes = h.contentLengthBytes[:0]
-	case "Connection":
+	case HeaderConnection:
 		h.connectionClose = false
 	}
 	h.h = delAllArgsBytes(h.h, key)
@@ -877,18 +877,18 @@ func (h *RequestHeader) DelBytes(key []byte) {
 
 func (h *RequestHeader) del(key []byte) {
 	switch string(key) {
-	case "Host":
+	case HeaderHost:
 		h.host = h.host[:0]
-	case "Content-Type":
+	case HeaderContentType:
 		h.contentType = h.contentType[:0]
-	case "User-Agent":
+	case HeaderUserAgent:
 		h.userAgent = h.userAgent[:0]
-	case "Cookie":
+	case HeaderCookie:
 		h.cookies = h.cookies[:0]
-	case "Content-Length":
+	case HeaderContentLength:
 		h.contentLength = 0
 		h.contentLengthBytes = h.contentLengthBytes[:0]
-	case "Connection":
+	case HeaderConnection:
 		h.connectionClose = false
 	}
 	h.h = delAllArgsBytes(h.h, key)
@@ -964,30 +964,30 @@ func (h *ResponseHeader) SetBytesKV(key, value []byte) {
 // key is in canonical form.
 func (h *ResponseHeader) SetCanonical(key, value []byte) {
 	switch string(key) {
-	case "Content-Type":
+	case HeaderContentType:
 		h.SetContentTypeBytes(value)
-	case "Server":
+	case HeaderServer:
 		h.SetServerBytes(value)
-	case "Set-Cookie":
+	case HeaderSetCookie:
 		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":
+	case HeaderContentLength:
 		if contentLength, err := parseContentLength(value); err == nil {
 			h.contentLength = contentLength
 			h.contentLengthBytes = append(h.contentLengthBytes[:0], value...)
 		}
-	case "Connection":
+	case HeaderConnection:
 		if bytes.Equal(strClose, value) {
 			h.SetConnectionClose()
 		} else {
 			h.ResetConnectionClose()
 			h.h = setArgBytes(h.h, key, value, argsHasValue)
 		}
-	case "Transfer-Encoding":
+	case HeaderTransferEncoding:
 		// Transfer-Encoding is managed automatically.
-	case "Date":
+	case HeaderDate:
 		// Date is managed automatically.
 	default:
 		h.h = setArgBytes(h.h, key, value, argsHasValue)
@@ -1149,28 +1149,28 @@ func (h *RequestHeader) SetBytesKV(key, value []byte) {
 func (h *RequestHeader) SetCanonical(key, value []byte) {
 	h.parseRawHeaders()
 	switch string(key) {
-	case "Host":
+	case HeaderHost:
 		h.SetHostBytes(value)
-	case "Content-Type":
+	case HeaderContentType:
 		h.SetContentTypeBytes(value)
-	case "User-Agent":
+	case HeaderUserAgent:
 		h.SetUserAgentBytes(value)
-	case "Cookie":
+	case HeaderCookie:
 		h.collectCookies()
 		h.cookies = parseRequestCookies(h.cookies, value)
-	case "Content-Length":
+	case HeaderContentLength:
 		if contentLength, err := parseContentLength(value); err == nil {
 			h.contentLength = contentLength
 			h.contentLengthBytes = append(h.contentLengthBytes[:0], value...)
 		}
-	case "Connection":
+	case HeaderConnection:
 		if bytes.Equal(strClose, value) {
 			h.SetConnectionClose()
 		} else {
 			h.ResetConnectionClose()
 			h.h = setArgBytes(h.h, key, value, argsHasValue)
 		}
-	case "Transfer-Encoding":
+	case HeaderTransferEncoding:
 		// Transfer-Encoding is managed automatically.
 	default:
 		h.h = setArgBytes(h.h, key, value, argsHasValue)
@@ -1217,18 +1217,18 @@ func (h *RequestHeader) PeekBytes(key []byte) []byte {
 
 func (h *ResponseHeader) peek(key []byte) []byte {
 	switch string(key) {
-	case "Content-Type":
+	case HeaderContentType:
 		return h.ContentType()
-	case "Server":
+	case HeaderServer:
 		return h.Server()
-	case "Connection":
+	case HeaderConnection:
 		if h.ConnectionClose() {
 			return strClose
 		}
 		return peekArgBytes(h.h, key)
-	case "Content-Length":
+	case HeaderContentLength:
 		return h.contentLengthBytes
-	case "Set-Cookie":
+	case HeaderSetCookie:
 		return appendResponseCookieBytes(nil, h.cookies)
 	default:
 		return peekArgBytes(h.h, key)
@@ -1238,20 +1238,20 @@ func (h *ResponseHeader) peek(key []byte) []byte {
 func (h *RequestHeader) peek(key []byte) []byte {
 	h.parseRawHeaders()
 	switch string(key) {
-	case "Host":
+	case HeaderHost:
 		return h.Host()
-	case "Content-Type":
+	case HeaderContentType:
 		return h.ContentType()
-	case "User-Agent":
+	case HeaderUserAgent:
 		return h.UserAgent()
-	case "Connection":
+	case HeaderConnection:
 		if h.ConnectionClose() {
 			return strClose
 		}
 		return peekArgBytes(h.h, key)
-	case "Content-Length":
+	case HeaderContentLength:
 		return h.contentLengthBytes
-	case "Cookie":
+	case HeaderCookie:
 		if h.cookiesCollected {
 			return appendRequestCookieBytes(nil, h.cookies)
 		} else {
diff --git a/headers.go b/headers.go
new file mode 100644
index 0000000..7c3b2cb
--- /dev/null
+++ b/headers.go
@@ -0,0 +1,164 @@
+package fasthttp
+
+// Headers
+const (
+	// Authentication
+	HeaderAuthorization      = "Authorization"
+	HeaderProxyAuthenticate  = "Proxy-Authenticate"
+	HeaderProxyAuthorization = "Proxy-Authorization"
+	HeaderWWWAuthenticate    = "WWW-Authenticate"
+
+	// Caching
+	HeaderAge           = "Age"
+	HeaderCacheControl  = "Cache-Control"
+	HeaderClearSiteData = "Clear-Site-Data"
+	HeaderExpires       = "Expires"
+	HeaderPragma        = "Pragma"
+	HeaderWarning       = "Warning"
+
+	// Client hints
+	HeaderAcceptCH         = "Accept-CH"
+	HeaderAcceptCHLifetime = "Accept-CH-Lifetime"
+	HeaderContentDPR       = "Content-DPR"
+	HeaderDPR              = "DPR"
+	HeaderEarlyData        = "Early-Data"
+	HeaderSaveData         = "Save-Data"
+	HeaderViewportWidth    = "Viewport-Width"
+	HeaderWidth            = "Width"
+
+	// Conditionals
+	HeaderETag              = "ETag"
+	HeaderIfMatch           = "If-Match"
+	HeaderIfModifiedSince   = "If-Modified-Since"
+	HeaderIfNoneMatch       = "If-None-Match"
+	HeaderIfUnmodifiedSince = "If-Unmodified-Since"
+	HeaderLastModified      = "Last-Modified"
+	HeaderVary              = "Vary"
+
+	// Connection management
+	HeaderConnection = "Connection"
+	HeaderKeepAlive  = "Keep-Alive"
+
+	// Content negotiation
+	HeaderAccept         = "Accept"
+	HeaderAcceptCharset  = "Accept-Charset"
+	HeaderAcceptEncoding = "Accept-Encoding"
+	HeaderAcceptLanguage = "Accept-Language"
+
+	// Controls
+	HeaderCookie      = "Cookie"
+	HeaderExpect      = "Expect"
+	HeaderMaxForwards = "Max-Forwards"
+	HeaderSetCookie   = "Set-Cookie"
+
+	// CORS
+	HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials"
+	HeaderAccessControlAllowHeaders     = "Access-Control-Allow-Headers"
+	HeaderAccessControlAllowMethods     = "Access-Control-Allow-Methods"
+	HeaderAccessControlAllowOrigin      = "Access-Control-Allow-Origin"
+	HeaderAccessControlExposeHeaders    = "Access-Control-Expose-Headers"
+	HeaderAccessControlMaxAge           = "Access-Control-Max-Age"
+	HeaderAccessControlRequestHeaders   = "Access-Control-Request-Headers"
+	HeaderAccessControlRequestMethod    = "Access-Control-Request-Method"
+	HeaderOrigin                        = "Origin"
+	HeaderTimingAllowOrigin             = "Timing-Allow-Origin"
+	HeaderXPermittedCrossDomainPolicies = "X-Permitted-Cross-Domain-Policies"
+
+	// Do Not Track
+	HeaderDNT = "DNT"
+	HeaderTk  = "Tk"
+
+	// Downloads
+	HeaderContentDisposition = "Content-Disposition"
+
+	// Message body information
+	HeaderContentEncoding = "Content-Encoding"
+	HeaderContentLanguage = "Content-Language"
+	HeaderContentLength   = "Content-Length"
+	HeaderContentLocation = "Content-Location"
+	HeaderContentType     = "Content-Type"
+
+	// Proxies
+	HeaderForwarded       = "Forwarded"
+	HeaderVia             = "Via"
+	HeaderXForwardedFor   = "X-Forwarded-For"
+	HeaderXForwardedHost  = "X-Forwarded-Host"
+	HeaderXForwardedProto = "X-Forwarded-Proto"
+
+	// Redirects
+	HeaderLocation = "Location"
+
+	// Request context
+	HeaderFrom           = "From"
+	HeaderHost           = "Host"
+	HeaderReferer        = "Referer"
+	HeaderReferrerPolicy = "Referrer-Policy"
+	HeaderUserAgent      = "User-Agent"
+
+	// Response context
+	HeaderAllow  = "Allow"
+	HeaderServer = "Server"
+
+	// Range requests
+	HeaderAcceptRanges = "Accept-Ranges"
+	HeaderContentRange = "Content-Range"
+	HeaderIfRange      = "If-Range"
+	HeaderRange        = "Range"
+
+	// Security
+	HeaderContentSecurityPolicy           = "Content-Security-Policy"
+	HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only"
+	HeaderCrossOriginResourcePolicy       = "Cross-Origin-Resource-Policy"
+	HeaderExpectCT                        = "Expect-CT"
+	HeaderFeaturePolicy                   = "Feature-Policy"
+	HeaderPublicKeyPins                   = "Public-Key-Pins"
+	HeaderPublicKeyPinsReportOnly         = "Public-Key-Pins-Report-Only"
+	HeaderStrictTransportSecurity         = "Strict-Transport-Security"
+	HeaderUpgradeInsecureRequests         = "Upgrade-Insecure-Requests"
+	HeaderXContentTypeOptions             = "X-Content-Type-Options"
+	HeaderXDownloadOptions                = "X-Download-Options"
+	HeaderXFrameOptions                   = "X-Frame-Options"
+	HeaderXPoweredBy                      = "X-Powered-By"
+	HeaderXXSSProtection                  = "X-XSS-Protection"
+
+	// Server-sent event
+	HeaderLastEventID = "Last-Event-ID"
+	HeaderNEL         = "NEL"
+	HeaderPingFrom    = "Ping-From"
+	HeaderPingTo      = "Ping-To"
+	HeaderReportTo    = "Report-To"
+
+	// Transfer coding
+	HeaderTE               = "TE"
+	HeaderTrailer          = "Trailer"
+	HeaderTransferEncoding = "Transfer-Encoding"
+
+	// WebSockets
+	HeaderSecWebSocketAccept     = "Sec-WebSocket-Accept"
+	HeaderSecWebSocketExtensions = "Sec-WebSocket-Extensions"
+	HeaderSecWebSocketKey        = "Sec-WebSocket-Key"
+	HeaderSecWebSocketProtocol   = "Sec-WebSocket-Protocol"
+	HeaderSecWebSocketVersion    = "Sec-WebSocket-Version"
+
+	// Other
+	HeaderAcceptPatch         = "Accept-Patch"
+	HeaderAcceptPushPolicy    = "Accept-Push-Policy"
+	HeaderAcceptSignature     = "Accept-Signature"
+	HeaderAltSvc              = "Alt-Svc"
+	HeaderDate                = "Date"
+	HeaderIndex               = "Index"
+	HeaderLargeAllocation     = "Large-Allocation"
+	HeaderLink                = "Link"
+	HeaderPushPolicy          = "Push-Policy"
+	HeaderRetryAfter          = "Retry-After"
+	HeaderServerTiming        = "Server-Timing"
+	HeaderSignature           = "Signature"
+	HeaderSignedHeaders       = "Signed-Headers"
+	HeaderSourceMap           = "SourceMap"
+	HeaderUpgrade             = "Upgrade"
+	HeaderXDNSPrefetchControl = "X-DNS-Prefetch-Control"
+	HeaderXPingback           = "X-Pingback"
+	HeaderXRequestedWith      = "X-RequestedWith"
+	HeaderXRobotsTag          = "X-Robots-Tag"
+	HeaderXUACompatible       = "X-UA-Compatible"
+)
diff --git a/server.go b/server.go
index 98a5be8..9d14599 100644
--- a/server.go
+++ b/server.go
@@ -371,6 +371,17 @@ type Server struct {
 // msg to the client if there are more than Server.Concurrency concurrent
 // handlers h are running at the moment.
 func TimeoutHandler(h RequestHandler, timeout time.Duration, msg string) RequestHandler {
+	return TimeoutWithCodeHandler(h,timeout,msg, StatusRequestTimeout)
+}
+
+// TimeoutWithCodeHandler creates RequestHandler, which returns an error with 
+// the given msg and status code to the client  if h didn't return during
+// the given duration.
+//
+// The returned handler may return StatusTooManyRequests error with the given
+// msg to the client if there are more than Server.Concurrency concurrent
+// handlers h are running at the moment.
+func TimeoutWithCodeHandler(h RequestHandler, timeout time.Duration, msg string, statusCode int) RequestHandler {
 	if timeout <= 0 {
 		return h
 	}
@@ -398,7 +409,7 @@ func TimeoutHandler(h RequestHandler, timeout time.Duration, msg string) Request
 		select {
 		case <-ch:
 		case <-ctx.timeoutTimer.C:
-			ctx.TimeoutError(msg)
+			ctx.TimeoutErrorWithCode(msg, statusCode)
 		}
 		stopTimer(ctx.timeoutTimer)
 	}
diff --git a/strings.go b/strings.go
index 17e5602..f654f95 100644
--- a/strings.go
+++ b/strings.go
@@ -32,26 +32,26 @@ var (
 	strTrace   = []byte(MethodTrace)
 	strPatch   = []byte(MethodPatch)
 
-	strExpect           = []byte("Expect")
-	strConnection       = []byte("Connection")
-	strContentLength    = []byte("Content-Length")
-	strContentType      = []byte("Content-Type")
-	strDate             = []byte("Date")
-	strHost             = []byte("Host")
-	strReferer          = []byte("Referer")
-	strServer           = []byte("Server")
-	strTransferEncoding = []byte("Transfer-Encoding")
-	strContentEncoding  = []byte("Content-Encoding")
-	strAcceptEncoding   = []byte("Accept-Encoding")
-	strUserAgent        = []byte("User-Agent")
-	strCookie           = []byte("Cookie")
-	strSetCookie        = []byte("Set-Cookie")
-	strLocation         = []byte("Location")
-	strIfModifiedSince  = []byte("If-Modified-Since")
-	strLastModified     = []byte("Last-Modified")
-	strAcceptRanges     = []byte("Accept-Ranges")
-	strRange            = []byte("Range")
-	strContentRange     = []byte("Content-Range")
+	strExpect           = []byte(HeaderExpect)
+	strConnection       = []byte(HeaderConnection)
+	strContentLength    = []byte(HeaderContentLength)
+	strContentType      = []byte(HeaderContentType)
+	strDate             = []byte(HeaderDate)
+	strHost             = []byte(HeaderHost)
+	strReferer          = []byte(HeaderReferer)
+	strServer           = []byte(HeaderServer)
+	strTransferEncoding = []byte(HeaderTransferEncoding)
+	strContentEncoding  = []byte(HeaderContentEncoding)
+	strAcceptEncoding   = []byte(HeaderAcceptEncoding)
+	strUserAgent        = []byte(HeaderUserAgent)
+	strCookie           = []byte(HeaderCookie)
+	strSetCookie        = []byte(HeaderSetCookie)
+	strLocation         = []byte(HeaderLocation)
+	strIfModifiedSince  = []byte(HeaderIfModifiedSince)
+	strLastModified     = []byte(HeaderLastModified)
+	strAcceptRanges     = []byte(HeaderAcceptRanges)
+	strRange            = []byte(HeaderRange)
+	strContentRange     = []byte(HeaderContentRange)
 
 	strCookieExpires        = []byte("expires")
 	strCookieDomain         = []byte("domain")
@@ -62,6 +62,7 @@ var (
 	strCookieSameSite       = []byte("SameSite")
 	strCookieSameSiteLax    = []byte("Lax")
 	strCookieSameSiteStrict = []byte("Strict")
+	strCookieSameSiteNone   = []byte("None")
 
 	strClose               = []byte("close")
 	strGzip                = []byte("gzip")


Test patch:
diff --git a/client_timing_test.go b/client_timing_test.go
index 8cc72a2..1a97cd8 100644
--- a/client_timing_test.go
+++ b/client_timing_test.go
@@ -186,7 +186,7 @@ func fasthttpEchoHandler(ctx *RequestCtx) {
 }
 
 func nethttpEchoHandler(w http.ResponseWriter, r *http.Request) {
-	w.Header().Set("Content-Type", "text/plain")
+	w.Header().Set(HeaderContentType, "text/plain")
 	w.Write([]byte(r.RequestURI))
 }
 
@@ -516,7 +516,7 @@ func BenchmarkNetHTTPClientEndToEndBigResponse10Inmemory(b *testing.B) {
 func benchmarkNetHTTPClientEndToEndBigResponseInmemory(b *testing.B, parallelism int) {
 	bigResponse := createFixedBody(1024 * 1024)
 	h := func(w http.ResponseWriter, r *http.Request) {
-		w.Header().Set("Content-Type", "text/plain")
+		w.Header().Set(HeaderContentType, "text/plain")
 		w.Write(bigResponse)
 	}
 	ln := fasthttputil.NewInmemoryListener()
diff --git a/cookie_test.go b/cookie_test.go
index 50c2ad3..9add593 100644
--- a/cookie_test.go
+++ b/cookie_test.go
@@ -121,6 +121,29 @@ func TestCookieSameSite(t *testing.T) {
 		t.Fatalf("missing SameSite flag in cookie %q", s)
 	}
 
+	if err := c.Parse("foo=bar; samesite=none"); err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	if c.SameSite() != CookieSameSiteNoneMode {
+		t.Fatalf("SameSite None Mode must be set")
+	}
+	s = c.String()
+	if !strings.Contains(s, "; SameSite=None") {
+		t.Fatalf("missing SameSite flag in cookie %q", s)
+	}
+
+	if err := c.Parse("foo=bar"); err != nil {
+		t.Fatalf("unexpected error: %s", err)
+	}
+	c.SetSameSite(CookieSameSiteNoneMode)
+	s = c.String()
+	if !strings.Contains(s, "; SameSite=None") {
+		t.Fatalf("missing SameSite flag in cookie %q", s)
+	}
+	if !strings.Contains(s, "; secure") {
+		t.Fatalf("missing Secure flag in cookie %q", s)
+	}
+
 	if err := c.Parse("foo=bar"); err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
diff --git a/fasthttpadaptor/adaptor_test.go b/fasthttpadaptor/adaptor_test.go
index 96a1093..452711b 100644
--- a/fasthttpadaptor/adaptor_test.go
+++ b/fasthttpadaptor/adaptor_test.go
@@ -95,7 +95,7 @@ func TestNewFastHTTPHandler(t *testing.T) {
 	req.Header.SetMethod(expectedMethod)
 	req.SetRequestURI(expectedRequestURI)
 	req.Header.SetHost(expectedHost)
-	req.Header.Add("Transfer-Encoding", expectedTransferEncoding)
+	req.Header.Add(fasthttp.HeaderTransferEncoding, expectedTransferEncoding)
 	req.BodyWriter().Write([]byte(expectedBody))
 	for k, v := range expectedHeader {
 		req.Header.Set(k, v)
diff --git a/fs_test.go b/fs_test.go
index 9d56d48..083bdb9 100644
--- a/fs_test.go
+++ b/fs_test.go
@@ -115,7 +115,7 @@ func TestServeFileHead(t *testing.T) {
 		t.Fatalf("unexpected error: %s", err)
 	}
 
-	ce := resp.Header.Peek("Content-Encoding")
+	ce := resp.Header.Peek(HeaderContentEncoding)
 	if len(ce) > 0 {
 		t.Fatalf("Unexpected 'Content-Encoding' %q", ce)
 	}
@@ -190,7 +190,7 @@ func TestServeFileCompressed(t *testing.T) {
 	var ctx RequestCtx
 	var req Request
 	req.SetRequestURI("http://foobar.com/baz")
-	req.Header.Set("Accept-Encoding", "gzip")
+	req.Header.Set(HeaderAcceptEncoding, "gzip")
 	ctx.Init(&req, nil, nil)
 
 	ServeFile(&ctx, "fs.go")
@@ -202,7 +202,7 @@ func TestServeFileCompressed(t *testing.T) {
 		t.Fatalf("unexpected error: %s", err)
 	}
 
-	ce := resp.Header.Peek("Content-Encoding")
+	ce := resp.Header.Peek(HeaderContentEncoding)
 	if string(ce) != "gzip" {
 		t.Fatalf("Unexpected 'Content-Encoding' %q. Expecting %q", ce, "gzip")
 	}
@@ -224,7 +224,7 @@ func TestServeFileUncompressed(t *testing.T) {
 	var ctx RequestCtx
 	var req Request
 	req.SetRequestURI("http://foobar.com/baz")
-	req.Header.Set("Accept-Encoding", "gzip")
+	req.Header.Set(HeaderAcceptEncoding, "gzip")
 	ctx.Init(&req, nil, nil)
 
 	ServeFileUncompressed(&ctx, "fs.go")
@@ -236,7 +236,7 @@ func TestServeFileUncompressed(t *testing.T) {
 		t.Fatalf("unexpected error: %s", err)
 	}
 
-	ce := resp.Header.Peek("Content-Encoding")
+	ce := resp.Header.Peek(HeaderContentEncoding)
 	if len(ce) > 0 {
 		t.Fatalf("Unexpected 'Content-Encoding' %q", ce)
 	}
@@ -319,7 +319,7 @@ func testFSByteRange(t *testing.T, h RequestHandler, filePath string) {
 	if resp.StatusCode() != StatusPartialContent {
 		t.Fatalf("unexpected status code: %d. Expecting %d. filePath=%q", resp.StatusCode(), StatusPartialContent, filePath)
 	}
-	cr := resp.Header.Peek("Content-Range")
+	cr := resp.Header.Peek(HeaderContentRange)
 
 	expectedCR := fmt.Sprintf("bytes %d-%d/%d", startPos, endPos, fileSize)
 	if string(cr) != expectedCR {
@@ -473,7 +473,7 @@ func testFSCompress(t *testing.T, h RequestHandler, filePath string) {
 	if resp.StatusCode() != StatusOK {
 		t.Fatalf("unexpected status code: %d. Expecting %d. filePath=%q", resp.StatusCode(), StatusOK, filePath)
 	}
-	ce := resp.Header.Peek("Content-Encoding")
+	ce := resp.Header.Peek(HeaderContentEncoding)
 	if string(ce) != "" {
 		t.Fatalf("unexpected content-encoding %q. Expecting empty string. filePath=%q", ce, filePath)
 	}
@@ -482,7 +482,7 @@ func testFSCompress(t *testing.T, h RequestHandler, filePath string) {
 	// request compressed file
 	ctx.Request.Reset()
 	ctx.Request.SetRequestURI(filePath)
-	ctx.Request.Header.Set("Accept-Encoding", "gzip")
+	ctx.Request.Header.Set(HeaderAcceptEncoding, "gzip")
 	h(&ctx)
 	s = ctx.Response.String()
 	br = bufio.NewReader(bytes.NewBufferString(s))
@@ -492,7 +492,7 @@ func testFSCompress(t *testing.T, h RequestHandler, filePath string) {
 	if resp.StatusCode() != StatusOK {
 		t.Fatalf("unexpected status code: %d. Expecting %d. filePath=%q", resp.StatusCode(), StatusOK, filePath)
 	}
-	ce = resp.Header.Peek("Content-Encoding")
+	ce = resp.Header.Peek(HeaderContentEncoding)
 	if string(ce) != "gzip" {
 		t.Fatalf("unexpected content-encoding %q. Expecting %q. filePath=%q", ce, "gzip", filePath)
 	}
diff --git a/header_test.go b/header_test.go
index 1ff9ccf..7ec21af 100644
--- a/header_test.go
+++ b/header_test.go
@@ -216,7 +216,7 @@ func TestRequestHeaderSetCookieWithSpecialChars(t *testing.T) {
 	if err := h1.Read(br); err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
-	cookie := h1.Peek("Cookie")
+	cookie := h1.Peek(HeaderCookie)
 	if string(cookie) != "ID&14" {
 		t.Fatalf("unexpected cooke: %q. Expecting %q", cookie, "ID&14")
 	}
@@ -389,9 +389,9 @@ func TestRequestHeaderDel(t *testing.T) {
 	var h RequestHeader
 	h.Set("Foo-Bar", "baz")
 	h.Set("aaa", "bbb")
-	h.Set("Connection", "keep-alive")
+	h.Set(HeaderConnection, "keep-alive")
 	h.Set("Content-Type", "aaa")
-	h.Set("Host", "aaabbb")
+	h.Set(HeaderHost, "aaabbb")
 	h.Set("User-Agent", "asdfas")
 	h.Set("Content-Length", "1123")
 	h.Set("Cookie", "foobar=baz")
@@ -412,27 +412,27 @@ func TestRequestHeaderDel(t *testing.T) {
 	if len(hv) > 0 {
 		t.Fatalf("non-zero value: %q", hv)
 	}
-	hv = h.Peek("Connection")
+	hv = h.Peek(HeaderConnection)
 	if len(hv) > 0 {
 		t.Fatalf("non-zero value: %q", hv)
 	}
-	hv = h.Peek("Content-Type")
+	hv = h.Peek(HeaderContentType)
 	if len(hv) > 0 {
 		t.Fatalf("non-zero value: %q", hv)
 	}
-	hv = h.Peek("Host")
+	hv = h.Peek(HeaderHost)
 	if len(hv) > 0 {
 		t.Fatalf("non-zero value: %q", hv)
 	}
-	hv = h.Peek("User-Agent")
+	hv = h.Peek(HeaderUserAgent)
 	if len(hv) > 0 {
 		t.Fatalf("non-zero value: %q", hv)
 	}
-	hv = h.Peek("Content-Length")
+	hv = h.Peek(HeaderContentLength)
 	if len(hv) > 0 {
 		t.Fatalf("non-zero value: %q", hv)
 	}
-	hv = h.Peek("Cookie")
+	hv = h.Peek(HeaderCookie)
 	if len(hv) > 0 {
 		t.Fatalf("non-zero value: %q", hv)
 	}
@@ -450,10 +450,10 @@ func TestResponseHeaderDel(t *testing.T) {
 	var h ResponseHeader
 	h.Set("Foo-Bar", "baz")
 	h.Set("aaa", "bbb")
-	h.Set("Connection", "keep-alive")
-	h.Set("Content-Type", "aaa")
-	h.Set("Server", "aaabbb")
-	h.Set("Content-Length", "1123")
+	h.Set(HeaderConnection, "keep-alive")
+	h.Set(HeaderContentType, "aaa")
+	h.Set(HeaderServer, "aaabbb")
+	h.Set(HeaderContentLength, "1123")
 
 	var c Cookie
 	c.SetKey("foo")
@@ -463,7 +463,7 @@ func TestResponseHeaderDel(t *testing.T) {
 	h.Del("foo-bar")
 	h.Del("connection")
 	h.DelBytes([]byte("content-type"))
-	h.Del("Server")
+	h.Del(HeaderServer)
 	h.Del("content-length")
 	h.Del("set-cookie")
 
@@ -475,19 +475,19 @@ func TestResponseHeaderDel(t *testing.T) {
 	if len(hv) > 0 {
 		t.Fatalf("non-zero header value: %q", hv)
 	}
-	hv = h.Peek("Connection")
+	hv = h.Peek(HeaderConnection)
 	if len(hv) > 0 {
 		t.Fatalf("non-zero value: %q", hv)
 	}
-	hv = h.Peek("Content-Type")
+	hv = h.Peek(HeaderContentType)
 	if string(hv) != string(defaultContentType) {
 		t.Fatalf("unexpected content-type: %q. Expecting %q", hv, defaultContentType)
 	}
-	hv = h.Peek("Server")
+	hv = h.Peek(HeaderServer)
 	if len(hv) > 0 {
 		t.Fatalf("non-zero value: %q", hv)
 	}
-	hv = h.Peek("Content-Length")
+	hv = h.Peek(HeaderContentLength)
 	if len(hv) > 0 {
 		t.Fatalf("non-zero value: %q", hv)
 	}
@@ -727,7 +727,7 @@ func TestRequestHeaderSetByteRange(t *testing.T) {
 func testRequestHeaderSetByteRange(t *testing.T, startPos, endPos int, expectedV string) {
 	var h RequestHeader
 	h.SetByteRange(startPos, endPos)
-	v := h.Peek("Range")
+	v := h.Peek(HeaderRange)
 	if string(v) != expectedV {
 		t.Fatalf("unexpected range: %q. Expecting %q. startPos=%d, endPos=%d", v, expectedV, startPos, endPos)
 	}
@@ -741,7 +741,7 @@ func TestResponseHeaderSetContentRange(t *testing.T) {
 func testResponseHeaderSetContentRange(t *testing.T, startPos, endPos, contentLength int, expectedV string) {
 	var h ResponseHeader
 	h.SetContentRange(startPos, endPos, contentLength)
-	v := h.Peek("Content-Range")
+	v := h.Peek(HeaderContentRange)
 	if string(v) != expectedV {
 		t.Fatalf("unexpected content-range: %q. Expecting %q. startPos=%d, endPos=%d, contentLength=%d",
 			v, expectedV, startPos, endPos, contentLength)
@@ -766,7 +766,7 @@ func TestRequestHeaderHasAcceptEncoding(t *testing.T) {
 
 func testRequestHeaderHasAcceptEncoding(t *testing.T, ae, v string, resultExpected bool) {
 	var h RequestHeader
-	h.Set("Accept-Encoding", ae)
+	h.Set(HeaderAcceptEncoding, ae)
 	result := h.HasAcceptEncoding(v)
 	if result != resultExpected {
 		t.Fatalf("unexpected result in HasAcceptEncoding(%q, %q): %v. Expecting %v", ae, v, result, resultExpected)
@@ -1054,8 +1054,8 @@ func testRequestHeaderHTTPVer(t *testing.T, s string, connectionClose bool) {
 func TestResponseHeaderCopyTo(t *testing.T) {
 	var h ResponseHeader
 
-	h.Set("Set-Cookie", "foo=bar")
-	h.Set("Content-Type", "foobar")
+	h.Set(HeaderSetCookie, "foo=bar")
+	h.Set(HeaderContentType, "foobar")
 	h.Set("AAA-BBB", "aaaa")
 
 	var h1 ResponseHeader
@@ -1063,7 +1063,7 @@ func TestResponseHeaderCopyTo(t *testing.T) {
 	if !bytes.Equal(h1.Peek("Set-cookie"), h.Peek("Set-Cookie")) {
 		t.Fatalf("unexpected cookie %q. Expected %q", h1.Peek("set-cookie"), h.Peek("set-cookie"))
 	}
-	if !bytes.Equal(h1.Peek("Content-Type"), h.Peek("Content-Type")) {
+	if !bytes.Equal(h1.Peek(HeaderContentType), h.Peek(HeaderContentType)) {
 		t.Fatalf("unexpected content-type %q. Expected %q", h1.Peek("content-type"), h.Peek("content-type"))
 	}
 	if !bytes.Equal(h1.Peek("aaa-bbb"), h.Peek("AAA-BBB")) {
@@ -1082,17 +1082,17 @@ func TestResponseHeaderCopyTo(t *testing.T) {
 func TestRequestHeaderCopyTo(t *testing.T) {
 	var h RequestHeader
 
-	h.Set("Cookie", "aa=bb; cc=dd")
-	h.Set("Content-Type", "foobar")
-	h.Set("Host", "aaaa")
+	h.Set(HeaderCookie, "aa=bb; cc=dd")
+	h.Set(HeaderContentType, "foobar")
+	h.Set(HeaderHost, "aaaa")
 	h.Set("aaaxxx", "123")
 
 	var h1 RequestHeader
 	h.CopyTo(&h1)
-	if !bytes.Equal(h1.Peek("cookie"), h.Peek("Cookie")) {
+	if !bytes.Equal(h1.Peek("cookie"), h.Peek(HeaderCookie)) {
 		t.Fatalf("unexpected cookie after copying: %q. Expected %q", h1.Peek("cookie"), h.Peek("cookie"))
 	}
-	if !bytes.Equal(h1.Peek("content-type"), h.Peek("Content-Type")) {
+	if !bytes.Equal(h1.Peek("content-type"), h.Peek(HeaderContentType)) {
 		t.Fatalf("unexpected content-type %q. Expected %q", h1.Peek("content-type"), h.Peek("content-type"))
 	}
 	if !bytes.Equal(h1.Peek("host"), h.Peek("host")) {
@@ -1114,8 +1114,8 @@ func TestRequestHeaderCopyTo(t *testing.T) {
 func TestRequestHeaderConnectionClose(t *testing.T) {
 	var h RequestHeader
 
-	h.Set("Connection", "close")
-	h.Set("Host", "foobar")
+	h.Set(HeaderConnection, "close")
+	h.Set(HeaderHost, "foobar")
 	if !h.ConnectionClose() {
 		t.Fatalf("connection: close not set")
 	}
@@ -1138,7 +1138,7 @@ func TestRequestHeaderConnectionClose(t *testing.T) {
 	if !h1.ConnectionClose() {
 		t.Fatalf("unexpected connection: close value: %v", h1.ConnectionClose())
 	}
-	if string(h1.Peek("Connection")) != "close" {
+	if string(h1.Peek(HeaderConnection)) != "close" {
 		t.Fatalf("unexpected connection value: %q. Expecting %q", h.Peek("Connection"), "close")
 	}
 
@@ -1165,7 +1165,7 @@ func TestResponseHeaderSetCookie(t *testing.T) {
 	var h ResponseHeader
 
 	h.Set("set-cookie", "foo=bar; path=/aa/bb; domain=aaa.com")
-	h.Set("Set-Cookie", "aaaaa=bxx")
+	h.Set(HeaderSetCookie, "aaaaa=bxx")
 
 	var c Cookie
 	c.SetKey("foo")
@@ -1210,17 +1210,17 @@ func TestResponseHeaderVisitAll(t *testing.T) {
 		k := string(key)
 		v := string(value)
 		switch k {
-		case "Content-Length":
+		case HeaderContentLength:
 			if v != string(h.Peek(k)) {
 				t.Fatalf("unexpected content-length: %q. Expecting %q", v, h.Peek(k))
 			}
 			contentLengthCount++
-		case "Content-Type":
+		case HeaderContentType:
 			if v != string(h.Peek(k)) {
 				t.Fatalf("Unexpected content-type: %q. Expected %q", v, h.Peek(k))
 			}
 			contentTypeCount++
-		case "Set-Cookie":
+		case HeaderSetCookie:
 			if cookieCount == 0 && v != "aa=bb; path=/foo/bar" {
 				t.Fatalf("unexpected cookie header: %q. Expected %q", v, "aa=bb; path=/foo/bar")
 			}
@@ -1262,7 +1262,7 @@ func TestRequestHeaderVisitAll(t *testing.T) {
 		k := string(key)
 		v := string(value)
 		switch k {
-		case "Host":
+		case HeaderHost:
 			if v != string(h.Peek(k)) {
 				t.Fatalf("Unexpected host value %q. Expected %q", v, h.Peek(k))
 			}
@@ -1275,7 +1275,7 @@ func TestRequestHeaderVisitAll(t *testing.T) {
 				t.Fatalf("Unexpected value %q. Expected %q", v, "ZZ")
 			}
 			xxCount++
-		case "Cookie":
+		case HeaderCookie:
 			if v != "a=b; c=d" {
 				t.Fatalf("Unexpected cookie %q. Expected %q", v, "a=b; c=d")
 			}
@@ -1309,10 +1309,10 @@ func TestResponseHeaderVisitAllInOrder(t *testing.T) {
 	}
 
 	order := []string{
-		"Content-Type",
-		"Cookie",
-		"Host",
-		"User-Agent",
+		HeaderContentType,
+		HeaderCookie,
+		HeaderHost,
+		HeaderUserAgent,
 	}
 	values := []string{
 		"aa",
@@ -1466,7 +1466,7 @@ func equalCookie(c1, c2 *Cookie) bool {
 func TestRequestHeaderCookie(t *testing.T) {
 	var h RequestHeader
 	h.SetRequestURI("/foobar")
-	h.Set("Host", "foobar.com")
+	h.Set(HeaderHost, "foobar.com")
 
 	h.SetCookie("foo", "bar")
 	h.SetCookie("привет", "мир")
@@ -1525,13 +1525,13 @@ func TestResponseHeaderCookieIssue4(t *testing.T) {
 	c.SetValue("bar")
 	h.SetCookie(c)
 
-	if string(h.Peek("Set-Cookie")) != "foo=bar" {
-		t.Fatalf("Unexpected Set-Cookie header %q. Expected %q", h.Peek("Set-Cookie"), "foo=bar")
+	if string(h.Peek(HeaderSetCookie)) != "foo=bar" {
+		t.Fatalf("Unexpected Set-Cookie header %q. Expected %q", h.Peek(HeaderSetCookie), "foo=bar")
 	}
 	cookieSeen := false
 	h.VisitAll(func(key, value []byte) {
 		switch string(key) {
-		case "Set-Cookie":
+		case HeaderSetCookie:
 			cookieSeen = true
 		}
 	})
@@ -1546,13 +1546,13 @@ func TestResponseHeaderCookieIssue4(t *testing.T) {
 		t.Fatalf("Unexpected cookie value %q. Exepcted %q", c.Value(), "bar")
 	}
 
-	if string(h.Peek("Set-Cookie")) != "foo=bar" {
-		t.Fatalf("Unexpected Set-Cookie header %q. Expected %q", h.Peek("Set-Cookie"), "foo=bar")
+	if string(h.Peek(HeaderSetCookie)) != "foo=bar" {
+		t.Fatalf("Unexpected Set-Cookie header %q. Expected %q", h.Peek(HeaderSetCookie), "foo=bar")
 	}
 	cookieSeen = false
 	h.VisitAll(func(key, value []byte) {
 		switch string(key) {
-		case "Set-Cookie":
+		case HeaderSetCookie:
 			cookieSeen = true
 		}
 	})
@@ -1564,17 +1564,17 @@ func TestResponseHeaderCookieIssue4(t *testing.T) {
 func TestRequestHeaderCookieIssue313(t *testing.T) {
 	var h RequestHeader
 	h.SetRequestURI("/")
-	h.Set("Host", "foobar.com")
+	h.Set(HeaderHost, "foobar.com")
 
 	h.SetCookie("foo", "bar")
 
-	if string(h.Peek("Cookie")) != "foo=bar" {
-		t.Fatalf("Unexpected Cookie header %q. Expected %q", h.Peek("Cookie"), "foo=bar")
+	if string(h.Peek(HeaderCookie)) != "foo=bar" {
+		t.Fatalf("Unexpected Cookie header %q. Expected %q", h.Peek(HeaderCookie), "foo=bar")
 	}
 	cookieSeen := false
 	h.VisitAll(func(key, value []byte) {
 		switch string(key) {
-		case "Cookie":
+		case HeaderCookie:
 			cookieSeen = true
 		}
 	})
@@ -1586,13 +1586,13 @@ func TestRequestHeaderCookieIssue313(t *testing.T) {
 		t.Fatalf("Unexpected cookie value %q. Exepcted %q", h.Cookie("foo"), "bar")
 	}
 
-	if string(h.Peek("Cookie")) != "foo=bar" {
-		t.Fatalf("Unexpected Cookie header %q. Expected %q", h.Peek("Cookie"), "foo=bar")
+	if string(h.Peek(HeaderCookie)) != "foo=bar" {
+		t.Fatalf("Unexpected Cookie header %q. Expected %q", h.Peek(HeaderCookie), "foo=bar")
 	}
 	cookieSeen = false
 	h.VisitAll(func(key, value []byte) {
 		switch string(key) {
-		case "Cookie":
+		case HeaderCookie:
 			cookieSeen = true
 		}
 	})
@@ -1648,13 +1648,13 @@ func TestRequestHeaderSetGet(t *testing.T) {
 	h.Set("connection", "close")
 
 	expectRequestHeaderGet(t, h, "Foo", "bar")
-	expectRequestHeaderGet(t, h, "Host", "12345")
-	expectRequestHeaderGet(t, h, "Content-Type", "aaa/bbb")
-	expectRequestHeaderGet(t, h, "Content-Length", "1234")
+	expectRequestHeaderGet(t, h, HeaderHost, "12345")
+	expectRequestHeaderGet(t, h, HeaderContentType, "aaa/bbb")
+	expectRequestHeaderGet(t, h, HeaderContentLength, "1234")
 	expectRequestHeaderGet(t, h, "USER-AGent", "aaabbb")
-	expectRequestHeaderGet(t, h, "Referer", "axcv")
+	expectRequestHeaderGet(t, h, HeaderReferer, "axcv")
 	expectRequestHeaderGet(t, h, "baz", "xxxxx")
-	expectRequestHeaderGet(t, h, "Transfer-Encoding", "")
+	expectRequestHeaderGet(t, h, HeaderTransferEncoding, "")
 	expectRequestHeaderGet(t, h, "connecTION", "close")
 	if !h.ConnectionClose() {
 		t.Fatalf("unset connection: close")
@@ -1686,13 +1686,13 @@ func TestRequestHeaderSetGet(t *testing.T) {
 
 	expectRequestHeaderGet(t, &h1, "Foo", "bar")
 	expectRequestHeaderGet(t, &h1, "HOST", "12345")
-	expectRequestHeaderGet(t, &h1, "Content-Type", "aaa/bbb")
-	expectRequestHeaderGet(t, &h1, "Content-Length", "1234")
+	expectRequestHeaderGet(t, &h1, HeaderContentType, "aaa/bbb")
+	expectRequestHeaderGet(t, &h1, HeaderContentLength, "1234")
 	expectRequestHeaderGet(t, &h1, "USER-AGent", "aaabbb")
-	expectRequestHeaderGet(t, &h1, "Referer", "axcv")
+	expectRequestHeaderGet(t, &h1, HeaderReferer, "axcv")
 	expectRequestHeaderGet(t, &h1, "baz", "xxxxx")
-	expectRequestHeaderGet(t, &h1, "Transfer-Encoding", "")
-	expectRequestHeaderGet(t, &h1, "Connection", "close")
+	expectRequestHeaderGet(t, &h1, HeaderTransferEncoding, "")
+	expectRequestHeaderGet(t, &h1, HeaderConnection, "close")
 	if !h1.ConnectionClose() {
 		t.Fatalf("unset connection: close")
 	}
@@ -1704,17 +1704,17 @@ func TestResponseHeaderSetGet(t *testing.T) {
 	h.Set("content-type", "aaa/bbb")
 	h.Set("connection", "close")
 	h.Set("content-length", "1234")
-	h.Set("Server", "aaaa")
+	h.Set(HeaderServer, "aaaa")
 	h.Set("baz", "xxxxx")
-	h.Set("Transfer-Encoding", "chunked")
+	h.Set(HeaderTransferEncoding, "chunked")
 
 	expectResponseHeaderGet(t, h, "Foo", "bar")
-	expectResponseHeaderGet(t, h, "Content-Type", "aaa/bbb")
-	expectResponseHeaderGet(t, h, "Connection", "close")
-	expectResponseHeaderGet(t, h, "Content-Length", "1234")
+	expectResponseHeaderGet(t, h, HeaderContentType, "aaa/bbb")
+	expectResponseHeaderGet(t, h, HeaderConnection, "close")
+	expectResponseHeaderGet(t, h, HeaderContentLength, "1234")
 	expectResponseHeaderGet(t, h, "seRVer", "aaaa")
 	expectResponseHeaderGet(t, h, "baz", "xxxxx")
-	expectResponseHeaderGet(t, h, "Transfer-Encoding", "")
+	expectResponseHeaderGet(t, h, HeaderTransferEncoding, "")
 
 	if h.ContentLength() != 1234 {
 		t.Fatalf("Unexpected content-length %d. Expected %d", h.ContentLength(), 1234)
@@ -1747,8 +1747,8 @@ func TestResponseHeaderSetGet(t *testing.T) {
 	}
 
 	expectResponseHeaderGet(t, &h1, "Foo", "bar")
-	expectResponseHeaderGet(t, &h1, "Content-Type", "aaa/bbb")
-	expectResponseHeaderGet(t, &h1, "Connection", "close")
+	expectResponseHeaderGet(t, &h1, HeaderContentType, "aaa/bbb")
+	expectResponseHeaderGet(t, &h1, HeaderConnection, "close")
 	expectResponseHeaderGet(t, &h1, "seRVer", "aaaa")
 	expectResponseHeaderGet(t, &h1, "baz", "xxxxx")
 }
@@ -2280,8 +2280,8 @@ func verifyResponseHeader(t *testing.T, h *ResponseHeader, expectedStatusCode, e
 	if h.ContentLength() != expectedContentLength {
 		t.Fatalf("Unexpected content length %d. Expected %d", h.ContentLength(), expectedContentLength)
 	}
-	if string(h.Peek("Content-Type")) != expectedContentType {
-		t.Fatalf("Unexpected content type %q. Expected %q", h.Peek("Content-Type"), expectedContentType)
+	if string(h.Peek(HeaderContentType)) != expectedContentType {
+		t.Fatalf("Unexpected content type %q. Expected %q", h.Peek(HeaderContentType), expectedContentType)
 	}
 }
 
@@ -2293,14 +2293,14 @@ func verifyRequestHeader(t *testing.T, h *RequestHeader, expectedContentLength i
 	if string(h.RequestURI()) != expectedRequestURI {
 		t.Fatalf("Unexpected RequestURI %q. Expected %q", h.RequestURI(), expectedRequestURI)
 	}
-	if string(h.Peek("Host")) != expectedHost {
-		t.Fatalf("Unexpected host %q. Expected %q", h.Peek("Host"), expectedHost)
+	if string(h.Peek(HeaderHost)) != expectedHost {
+		t.Fatalf("Unexpected host %q. Expected %q", h.Peek(HeaderHost), expectedHost)
 	}
-	if string(h.Peek("Referer")) != expectedReferer {
-		t.Fatalf("Unexpected referer %q. Expected %q", h.Peek("Referer"), expectedReferer)
+	if string(h.Peek(HeaderReferer)) != expectedReferer {
+		t.Fatalf("Unexpected referer %q. Expected %q", h.Peek(HeaderReferer), expectedReferer)
 	}
-	if string(h.Peek("Content-Type")) != expectedContentType {
-		t.Fatalf("Unexpected content-type %q. Expected %q", h.Peek("Content-Type"), expectedContentType)
+	if string(h.Peek(HeaderContentType)) != expectedContentType {
+		t.Fatalf("Unexpected content-type %q. Expected %q", h.Peek(HeaderContentType), expectedContentType)
 	}
 }
 
diff --git a/http_test.go b/http_test.go
index 03aa52d..e739a9c 100644
--- a/http_test.go
+++ b/http_test.go
@@ -730,8 +730,8 @@ func TestRequestReadGzippedBody(t *testing.T) {
 		t.Fatalf("unexpected error: %s", err)
 	}
 
-	if string(r.Header.Peek("Content-Encoding")) != "gzip" {
-		t.Fatalf("unexpected content-encoding: %q. Expecting %q", r.Header.Peek("Content-Encoding"), "gzip")
+	if string(r.Header.Peek(HeaderContentEncoding)) != "gzip" {
+		t.Fatalf("unexpected content-encoding: %q. Expecting %q", r.Header.Peek(HeaderContentEncoding), "gzip")
 	}
 	if r.Header.ContentLength() != len(body) {
 		t.Fatalf("unexpected content-length: %d. Expecting %d", r.Header.ContentLength(), len(body))
@@ -913,7 +913,7 @@ func testResponseDeflateExt(t *testing.T, r *Response, s string) {
 		t.Fatalf("unexpected error: %s", err)
 	}
 
-	ce := r1.Header.Peek("Content-Encoding")
+	ce := r1.Header.Peek(HeaderContentEncoding)
 	var body []byte
 	if isCompressible {
 		if string(ce) != "deflate" {
@@ -966,7 +966,7 @@ func testResponseGzipExt(t *testing.T, r *Response, s string) {
 		t.Fatalf("unexpected error: %s", err)
 	}
 
-	ce := r1.Header.Peek("Content-Encoding")
+	ce := r1.Header.Peek(HeaderContentEncoding)
 	var body []byte
 	if isCompressible {
 		if string(ce) != "gzip" {
@@ -1485,11 +1485,11 @@ func testResponseSuccess(t *testing.T, statusCode int, contentType, serverName,
 	if resp1.Header.ContentLength() != len(body) {
 		t.Fatalf("Unexpected content-length: %d. Expected %d", resp1.Header.ContentLength(), len(body))
 	}
-	if string(resp1.Header.Peek("Content-Type")) != expectedContentType {
-		t.Fatalf("Unexpected content-type: %q. Expected %q", resp1.Header.Peek("Content-Type"), expectedContentType)
+	if string(resp1.Header.Peek(HeaderContentType)) != expectedContentType {
+		t.Fatalf("Unexpected content-type: %q. Expected %q", resp1.Header.Peek(HeaderContentType), expectedContentType)
 	}
-	if string(resp1.Header.Peek("Server")) != expectedServerName {
-		t.Fatalf("Unexpected server: %q. Expected %q", resp1.Header.Peek("Server"), expectedServerName)
+	if string(resp1.Header.Peek(HeaderServer)) != expectedServerName {
+		t.Fatalf("Unexpected server: %q. Expected %q", resp1.Header.Peek(HeaderServer), expectedServerName)
 	}
 	if !bytes.Equal(resp1.Body(), []byte(body)) {
 		t.Fatalf("Unexpected body: %q. Expected %q", resp1.Body(), body)
@@ -1509,8 +1509,8 @@ func testRequestWriteError(t *testing.T, method, requestURI, host, userAgent, bo
 
 	req.Header.SetMethod(method)
 	req.Header.SetRequestURI(requestURI)
-	req.Header.Set("Host", host)
-	req.Header.Set("User-Agent", userAgent)
+	req.Header.Set(HeaderHost, host)
+	req.Header.Set(HeaderUserAgent, userAgent)
 	req.SetBody([]byte(body))
 
 	w := &bytebufferpool.ByteBuffer{}
@@ -1526,13 +1526,13 @@ func testRequestSuccess(t *testing.T, method, requestURI, host, userAgent, body,
 
 	req.Header.SetMethod(method)
 	req.Header.SetRequestURI(requestURI)
-	req.Header.Set("Host", host)
-	req.Header.Set("User-Agent", userAgent)
+	req.Header.Set(HeaderHost, host)
+	req.Header.Set(HeaderUserAgent, userAgent)
 	req.SetBody([]byte(body))
 
 	contentType := "foobar"
 	if method == MethodPost {
-		req.Header.Set("Content-Type", contentType)
+		req.Header.Set(HeaderContentType, contentType)
 	}
 
 	w := &bytes.Buffer{}
@@ -1559,18 +1559,18 @@ func testRequestSuccess(t *testing.T, method, requestURI, host, userAgent, body,
 	if string(req1.Header.RequestURI()) != requestURI {
 		t.Fatalf("Unexpected RequestURI: %q. Expected %q", req1.Header.RequestURI(), requestURI)
 	}
-	if string(req1.Header.Peek("Host")) != host {
-		t.Fatalf("Unexpected host: %q. Expected %q", req1.Header.Peek("Host"), host)
+	if string(req1.Header.Peek(HeaderHost)) != host {
+		t.Fatalf("Unexpected host: %q. Expected %q", req1.Header.Peek(HeaderHost), host)
 	}
-	if string(req1.Header.Peek("User-Agent")) != userAgent {
-		t.Fatalf("Unexpected user-agent: %q. Expected %q", req1.Header.Peek("User-Agent"), userAgent)
+	if string(req1.Header.Peek(HeaderUserAgent)) != userAgent {
+		t.Fatalf("Unexpected user-agent: %q. Expected %q", req1.Header.Peek(HeaderUserAgent), userAgent)
 	}
 	if !bytes.Equal(req1.Body(), []byte(body)) {
 		t.Fatalf("Unexpected body: %q. Expected %q", req1.Body(), body)
 	}
 
-	if method == MethodPost && string(req1.Header.Peek("Content-Type")) != contentType {
-		t.Fatalf("Unexpected content-type: %q. Expected %q", req1.Header.Peek("Content-Type"), contentType)
+	if method == MethodPost && string(req1.Header.Peek(HeaderContentType)) != contentType {
+		t.Fatalf("Unexpected content-type: %q. Expected %q", req1.Header.Peek(HeaderContentType), contentType)
 	}
 }
 
@@ -1729,7 +1729,7 @@ func TestRequestURI(t *testing.T) {
 	expectedHash := "1334dfds&=d"
 
 	var req Request
-	req.Header.Set("Host", host)
+	req.Header.Set(HeaderHost, host)
 	req.Header.SetRequestURI(requestURI)
 
 	uri := req.URI()
diff --git a/server_test.go b/server_test.go
index 8d7d97f..a68d432 100644
--- a/server_test.go
+++ b/server_test.go
@@ -314,7 +314,7 @@ func TestRequestCtxRedirectHTTPSSchemeless(t *testing.T) {
 	ctx.Request.isTLS = true
 
 	ctx.Redirect("//foobar.com/aa/bbb", StatusFound)
-	location := ctx.Response.Header.Peek("Location")
+	location := ctx.Response.Header.Peek(HeaderLocation)
 	expectedLocation := "https://foobar.com/aa/bbb"
 	if string(location) != expectedLocation {
 		t.Fatalf("Unexpected location: %q. Expecting %q", location, expectedLocation)
@@ -348,7 +348,7 @@ func testRequestCtxRedirect(t *testing.T, origURL, redirectURL, expectedURL stri
 	ctx.Init(&req, nil, nil)
 
 	ctx.Redirect(redirectURL, StatusFound)
-	loc := ctx.Response.Header.Peek("Location")
+	loc := ctx.Response.Header.Peek(HeaderLocation)
 	if string(loc) != expectedURL {
 		t.Fatalf("unexpected redirect url %q. Expecting %q. origURL=%q, redirectURL=%q", loc, expectedURL, origURL, redirectURL)
 	}
@@ -1005,7 +1005,7 @@ Connection: close
 		if resp.StatusCode() != StatusSeeOther {
 			t.Fatalf("unexpected status code %d. Expecting %d", resp.StatusCode(), StatusSeeOther)
 		}
-		loc := resp.Header.Peek("Location")
+		loc := resp.Header.Peek(HeaderLocation)
 		if string(loc) != "http://qwerty.com/" {
 			t.Fatalf("unexpected location %q. Expecting %q", loc, "http://qwerty.com/")
 		}
@@ -1317,9 +1317,9 @@ func TestServerHTTP10ConnectionClose(t *testing.T) {
 			// handler, since the HTTP/1.0 request
 			// had no 'Connection: keep-alive' header.
 			ctx.Request.Header.ResetConnectionClose()
-			ctx.Request.Header.Set("Connection", "keep-alive")
+			ctx.Request.Header.Set(HeaderConnection, "keep-alive")
 			ctx.Response.Header.ResetConnectionClose()
-			ctx.Response.Header.Set("Connection", "keep-alive")
+			ctx.Response.Header.Set(HeaderConnection, "keep-alive")
 		})
 		if err != nil {
 			t.Fatalf("unexpected error: %s", err)
@@ -1553,7 +1553,7 @@ func TestCompressHandler(t *testing.T) {
 	if err := resp.Read(br); err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
-	ce := resp.Header.Peek("Content-Encoding")
+	ce := resp.Header.Peek(HeaderContentEncoding)
 	if string(ce) != "" {
 		t.Fatalf("unexpected Content-Encoding: %q. Expecting %q", ce, "")
 	}
@@ -1573,7 +1573,7 @@ func TestCompressHandler(t *testing.T) {
 	if err := resp.Read(br); err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
-	ce = resp.Header.Peek("Content-Encoding")
+	ce = resp.Header.Peek(HeaderContentEncoding)
 	if string(ce) != "gzip" {
 		t.Fatalf("unexpected Content-Encoding: %q. Expecting %q", ce, "gzip")
 	}
@@ -1596,7 +1596,7 @@ func TestCompressHandler(t *testing.T) {
 	if err := resp.Read(br); err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
-	ce = resp.Header.Peek("Content-Encoding")
+	ce = resp.Header.Peek(HeaderContentEncoding)
 	if string(ce) != "gzip" {
 		t.Fatalf("unexpected Content-Encoding: %q. Expecting %q", ce, "gzip")
 	}
@@ -1611,7 +1611,7 @@ func TestCompressHandler(t *testing.T) {
 	// verify deflate-compressed response
 	ctx.Request.Reset()
 	ctx.Response.Reset()
-	ctx.Request.Header.Set("Accept-Encoding", "foobar, deflate, sdhc")
+	ctx.Request.Header.Set(HeaderAcceptEncoding, "foobar, deflate, sdhc")
 
 	h(&ctx)
 	s = ctx.Response.String()
@@ -1619,7 +1619,7 @@ func TestCompressHandler(t *testing.T) {
 	if err := resp.Read(br); err != nil {
 		t.Fatalf("unexpected error: %s", err)
 	}
-	ce = resp.Header.Peek("Content-Encoding")
+	ce = resp.Header.Peek(HeaderContentEncoding)
 	if string(ce) != "deflate" {
 		t.Fatalf("unexpected Content-Encoding: %q. Expecting %q", ce, "deflate")
 	}
@@ -1689,8 +1689,8 @@ func TestServeConnNonHTTP11KeepAlive(t *testing.T) {
 	if err := resp.Read(br); err != nil {
 		t.Fatalf("Unexpected error when parsing response: %s", err)
 	}
-	if string(resp.Header.Peek("Connection")) != "keep-alive" {
-		t.Fatalf("unexpected Connection header %q. Expecting %q", resp.Header.Peek("Connection"), "keep-alive")
+	if string(resp.Header.Peek(HeaderConnection)) != "keep-alive" {
+		t.Fatalf("unexpected Connection header %q. Expecting %q", resp.Header.Peek(HeaderConnection), "keep-alive")
 	}
 	if resp.Header.ConnectionClose() {
 		t.Fatalf("unexpected Connection: close")
@@ -1700,8 +1700,8 @@ func TestServeConnNonHTTP11KeepAlive(t *testing.T) {
 	if err := resp.Read(br); err != nil {
 		t.Fatalf("Unexpected error when parsing response: %s", err)
 	}
-	if string(resp.Header.Peek("Connection")) != "close" {
-		t.Fatalf("unexpected Connection header %q. Expecting %q", resp.Header.Peek("Connection"), "close")
+	if string(resp.Header.Peek(HeaderConnection)) != "close" {
+		t.Fatalf("unexpected Connection header %q. Expecting %q", resp.Header.Peek(HeaderConnection), "close")
 	}
 	if !resp.Header.ConnectionClose() {
 		t.Fatalf("expecting Connection: close")
@@ -2608,8 +2608,8 @@ func TestServerConnError(t *testing.T) {
 	if resp.Header.ContentLength() != 6 {
 		t.Fatalf("Unexpected Content-Length %d. Expected %d", resp.Header.ContentLength(), 6)
 	}
-	if !bytes.Equal(resp.Header.Peek("Content-Type"), defaultContentType) {
-		t.Fatalf("Unexpected Content-Type %q. Expected %q", resp.Header.Peek("Content-Type"), defaultContentType)
+	if !bytes.Equal(resp.Header.Peek(HeaderContentType), defaultContentType) {
+		t.Fatalf("Unexpected Content-Type %q. Expected %q", resp.Header.Peek(HeaderContentType), defaultContentType)
 	}
 	if !bytes.Equal(resp.Body(), []byte("foobar")) {
 		t.Fatalf("Unexpected body %q. Expected %q", resp.Body(), "foobar")
@@ -2620,7 +2620,7 @@ func TestServeConnSingleRequest(t *testing.T) {
 	s := &Server{
 		Handler: func(ctx *RequestCtx) {
 			h := &ctx.Request.Header
-			ctx.Success("aaa", []byte(fmt.Sprintf("requestURI=%s, host=%s", h.RequestURI(), h.Peek("Host"))))
+			ctx.Success("aaa", []byte(fmt.Sprintf("requestURI=%s, host=%s", h.RequestURI(), h.Peek(HeaderHost))))
 		},
 	}
 
@@ -2649,7 +2649,7 @@ func TestServeConnMultiRequests(t *testing.T) {
 	s := &Server{
 		Handler: func(ctx *RequestCtx) {
 			h := &ctx.Request.Header
-			ctx.Success("aaa", []byte(fmt.Sprintf("requestURI=%s, host=%s", h.RequestURI(), h.Peek("Host"))))
+			ctx.Success("aaa", []byte(fmt.Sprintf("requestURI=%s, host=%s", h.RequestURI(), h.Peek(HeaderHost))))
 		},
 	}
 
diff --git a/server_timing_test.go b/server_timing_test.go
index e4318a7..d8893f6 100644
--- a/server_timing_test.go
+++ b/server_timing_test.go
@@ -353,7 +353,7 @@ func benchmarkNetHTTPServerGet(b *testing.B, clientsCount, requestsPerConn int)
 			h := w.Header()
 			h.Set("Content-Type", "text/plain")
 			if requestsPerConn == 1 {
-				h.Set("Connection", "close")
+				h.Set(HeaderConnection, "close")
 			}
 			w.Write(fakeResponse)
 			registerServedRequest(b, ch)
@@ -404,7 +404,7 @@ func benchmarkNetHTTPServerPost(b *testing.B, clientsCount, requestsPerConn int)
 			h := w.Header()
 			h.Set("Content-Type", "text/plain")
 			if requestsPerConn == 1 {
-				h.Set("Connection", "close")
+				h.Set(HeaderConnection, "close")
 			}
 			w.Write(body)
 			registerServedRequest(b, ch)