HTTP Headers | Article | Headers API | Fields (list) | HTTP Status Codes
The standard imposes no limit on size, but servers impose limits. E.g., @ Apache 2.3 server, the defaults are 8,190 bytes/field, and max 100 header fields/request. That's over
800KB
of data!
Context request
From
— Contains an Internet email address for a human user who controls the requesting user agent.Host
— Specifies the host (and perhaps port number) of the server to which the request is being sent. Sans port, default per service requested (e.g.,443
if per HTTPS80
if per HTTP). A Host header field must be sent with all HTTP/1.1 requests. A 400 (Bad Request) status code may be sent to any HTTP/1.1 request message that lacks a Host header field or that contains more than one.Host: <host>[:<port>]
Host: developer.cdn.mozilla.net
Referer
— the address of the page making the request, and so not always present; may be that of the previous web page from which a link to the currently requested page was followed. Sent with requests for page links,<link ...>
. When making AJAX requests to another domain, this is the url of the active page running the script; allows servers to identify clients for analytics, logging, optimized caching, etc. Notorious for being utilized (manipulated) by malicous attackers, e.g., Cross-Site Request Forgery. SeeCSRF.XSRF
(Referer: <url>Referer: https://developer.mozilla.org/en-US/docs/Web/JavaScript
- The full URL sans fragments (
#foo
) and userinfo (username:password
).
- The full URL sans fragments (
Referrer-Policy
— Governs which referrer information sent in the Referer header should be included with requests made.User-Agent
— Characteristic string to identify the application type, operating system, vendor/version of the client (user agent) performing the request.User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0
CORS | Docs/CORS | Network.HTTP.CORS+Fetch
(Access-Control-Allow-Origin
— Sent by the server of the requested resource. See PRJ.HTTP.CORS
(Origin
— Indicates the server requesting the resource; sent with CORS requests and POST
requests. It is similar to the Referer
header, but, unlike this header, it doesn't disclose the whole path.
Origin: <scheme> "://" <hostname> [ ":" <port> ]
Proxies
Forwarded
— Contains information from the client-facing side of proxy servers that is altered or lost when a proxy is involved in the path of the request. Less common than X-Forwarded-For
X-Forwarded-For
(XFF) — Client IP Address. The de-facto standard request header for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or a load balancer.
X-Forwarded-For: <clientIP>, <proxy1_IP>, <proxy2_IP>
- Right-most is most recent proxy IP address; left-most is client IP address.
- May be IPv6 address(es).
X-Forwarded-Host
(XFH) — Server domain name. The de-facto standard request header for identifying the original host requested by the client (in the Host
HTTP request header) behind a proxy or load balancer.
X-Forwarded-Host: <domain-name-of-forwarded-server>
X-Forwarded-Host: id42.example-cdn.com
X-Forwarded-Proto
— Identifies the protocol (HTTP or HTTPS) that a client used to connect to your proxy or load balancer.
Via
— Added by proxies, both forward and reverse proxies, and can appear in the request headers and the response headers.
Sec-Fetch-{Dest|Mode|Site|User}
request
Origin: <scheme> "://" <hostname> [ ":" <port> ]
Forwarded
— Contains information from the client-facing side of proxy servers that is altered or lost when a proxy is involved in the path of the request. Less common than X-Forwarded-For
X-Forwarded-For
(XFF) — Client IP Address. The de-facto standard request header for identifying the originating IP address of a client connecting to a web server through an HTTP proxy or a load balancer.
X-Forwarded-For: <clientIP>, <proxy1_IP>, <proxy2_IP>
- Right-most is most recent proxy IP address; left-most is client IP address.
- May be IPv6 address(es).
X-Forwarded-Host
(XFH) — Server domain name. The de-facto standard request header for identifying the original host requested by the client (in the Host
HTTP request header) behind a proxy or load balancer.
X-Forwarded-Host: <domain-name-of-forwarded-server>
X-Forwarded-Host: id42.example-cdn.com
X-Forwarded-Proto
— Identifies the protocol (HTTP or HTTPS) that a client used to connect to your proxy or load balancer.
Via
— Added by proxies, both forward and reverse proxies, and can appear in the request headers and the response headers.
Sec-Fetch-{Dest|Mode|Site|User}
requestA new (2019) security mechanism for user agents (Fetch API) to add specific context to outgoing requests, thereby aiding server-side decision making. By delivering metadata to a server in a set of fetch metadata headers, applications may quickly reject requests based on testing a set of preconditions. That work can even be lifted up above the application layer (to reverse proxies, CDNs, etc) if desired.
Fetch API Metadata Headers
Sec-Fetch-Mode = sh-token
Sec-Fetch-Site = sh-token
Sec-Fetch-User = sh-boolean
(sh-token
— Structured Headers Token.)
Sec-Fetch-Dest: (N/A)
Sec-Fetch-Mode: cors|navigate|nested-navigate|no-cors|same-origin|websocket
Sec-Fetch-Site: same-origin|cross-site
Sec-Fetch-User: ?F|?T
- @ Brave browser,
Sec-Fetch-User: ?1|!0
; odd notation to avoid collision with other types.
Location
response
Indicates redirect destination URL. For use with 3xx
(redirection) or 201
(created) only.
Location
and Content-Location
are different.
HTTP Redirects (3xx
)
Content-Location
response
Indicates an alternate location; principal use is @ content negotiation.
Cookie
request
Browsers automatically send Cookie
header with each request, if any exist of its domain. The value thereof is a semicolon-delimited set of name=value
pairs, each a stored HTTP cookie previously sent by the server per Set-Cookie
header.
Cookie: <cookie-list>
Cookie: name=value
Cookie: name=value; name2=value2; name3=value3
- Pairs in the list are separated by a semicolon and a space, "
;
".
Set-Cookie
response
To send cookies from the server to the User Agent, e.g., a session cookie, which may be the result of a successful login.
Set-Cookie: <cookie-name>=<cookie-value>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly
For example, at twitter.com
(the server sent both) …
set-cookie: fm=0; Max-Age=0; Expires=Wed, 11 Sep 2019 14:57:57 GMT; Path=/; Domain=.twitter.com; Secure; HTTPOnly
set-cookie: _twitter_sess=BAh...NyZl9p%250...jQ1%250...xNg%253D%253D--690...c351; Path=/; Domain=.twitter.com; Secure; HTTPOnly
Delete cookie by expiring it:
☩ curl -Is localhost:3030/app/logout
HTTP/1.1 200 OK
Set-Cookie: __Host-ia=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; HttpOnly; Secure; SameSite=Strict
Set-Cookie: __Host-rr=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; HttpOnly; Secure; SameSite=Strict
Date: Sun, 04 Apr 2021 13:18:11 GMT
Content-Length: 11
Content-Type: text/plain; charset=utf-8
- See
PRJ.Headers.Req+Resp
(ETag
responseAn ETag is an identifier (validator) for a version of a resource.
ETag: "<etag_value>" ETag: W/"<etag_value>"
- The
<etag_value>
should be unique. The server's ETag response header triggers the client-side mechanism; the Etag value is cached and returned with all subsequent requests, per request header:
If-None-Match: <etag_value>, <etag_value>, …
- Such is a Conditional Request.
- Such is a Conditional Request.
Use cases:
- For HTTP caching. If the resource changes, a new
<etag_value>
must be generated. - Range requests.
- As an immutable ID for tracking per User Agent, similar to fingerprint schemes.
By default, ETag validation is a (costlier) hashsum check, assuring a bit-for-bit identical resource, so is used for
Range
requests. If used for caching, use theW/
prefix (weak validation), which does not perform the hashsum check, rather testing only for semantic equivalence. TheW/
method is faster, and so is commonly used for serving static resources (cache). E.g.,Etag: W/"581c5-xArf/LgZfhahmbgqOii1auQ2lkQ"
Conditional (Request) Headers / Requests
For a server response that varies per precondition(s) that match or not; the header-stipulated condition validates or doesn't.
Use Cases
- Cache update
- Integrity of a partial download, e.g., can be used in combination with a
Range
header to guarantee all parts of multipart doc come from the same resource. - Optimistic locking @ multiple clients modifying same document; the first returned wins.
- First upload (Creation) of a resource
Validators :: Headers
Last-Modified
— not as accurate asEtag
.Etag
Conditional Header(s)
Conditional request; for caching resources at the client; the server sends back the requested resource ___only on validation, e.g.,
<etag_value>
match @If-Match: <etag_value>
header, or none so @If-None-Match: <etag_value>
.If-None-Match
request
Conditional request; for caching resources; the server sends back the requested resource only if no<etag_value>
matches its; takes precedence overIf-Modified-Since
(date/time) request header (if both headers are sent).If-None-Match: <etag_value>, <etag_value>, …
If-Match
requestIf-Match: <etag_value> If-Match: <etag_value>, <etag_value>, … If-Match: *
If-Modified-Since
requestIf-Modified-Since: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
If-Unmodified-Since
requestIf-Range
request
Range
requestIndicates the part(s) of a document, in a multipart document, the server should return; uses the
206
(Partial Content
) for the response. If ranges are invalid, the server returns the416
(Range Not Satisfiable
) error. The server can also ignore the Range header and return the whole document with a200
status code.Range: <unit>=<range-start>-<range-end>, <range-start>-<range-end>
Cache-Control
request or responseAvoid requests for unchanged resources. Caching directives are unidirectional; a given directive in a request does not imply the same directive in the response.
Cache-Control: <directive-1>, <directive-2>, ...
Request Directives
Cache-Control: max-age=<seconds> Cache-Control: max-stale[=<seconds>] Cache-Control: min-fresh=<seconds> Cache-Control: no-cache Cache-Control: no-store Cache-Control: no-transform Cache-Control: only-if-cached
Response Directives
Cache-Control: must-revalidate Cache-Control: no-cache Cache-Control: no-store Cache-Control: no-transform Cache-Control: public Cache-Control: private Cache-Control: proxy-revalidate Cache-Control: max-age=<seconds> Cache-Control: s-maxage=<seconds>
To cache static assets, have server send:
Cache-Control: public, max-age=31536000
To prevent caching, have server send:
Cache-Control: no-store
- Else can use an
Expires
header; an HTTP-date timestamp:
Expires: Wed, 21 Oct 2015 07:28:00 GMT
(Ignored if withCache-Control
header havingmax-age
ors-maxage
directive.)
- Else can use an
Extension Directives (not as supported)
Cache-Control: immutable Cache-Control: stale-while-revalidate=<seconds> Cache-Control: stale-if-error=<seconds>
"Increasing Application Performance with HTTP Cache Headers"
Alt-Svc
responseAlternate Services; used to list alternate ways (host, protocol and port) to reach the server (website), e.g., per QUIC (vs HTTP). About half of all Google responses to Chrome browsers are per QUIC.
Alt-Svc: <service-list>; ma=<max-age>; persist=1
<service-list>
is a comma-separated list of service definitions:<service-name>="<host-name>:<port-number>"
<service-name>
is a valid ALPN identifier, e.g., "quic
".
@ Google Search …
Alt-Svc: quic=":443"; ma=2592000; v="46,43,39"
Strict-Transport-Security
(HSTS) responseHTTP Strict Transport Security (HSTS) policy ensures user agents (browsers) forbid access to the web app if it is not served per HTTPS. Receiving such from the server, browser will
preload
(internally redirect), to HTTPS, all subsequent HTTP requests to same origin. Spec per RFC 6797.More info @ OWASP.org
Strict-Transport-Security: max-age=1000; includeSubDomains; preload
max-age
directive is in seconds.- Same action for subdomain requests per optional
includeSubDomains
directive.
Can also submit site to list at hstspreload.org, which is adopted by most browsers.
Content-Security-Policy
(CSP) responseControl resources the user agent is allowed to load for a given page. Most policies specify server origins and script endpoints. This helps guard against cross-site scripting attacks (XSS).
Content-Security-Policy: <policy-directive>; <policy-directive> Content-Security-Policy: upgrade-insecure-requests
-
default-src https://theoneandonly.trusted.com
Allow only SSL and only from a single specified origin; all content.default-src 'self' *.trusted.com
Allow content from a trusted domain and all its subdomains.default-src 'self'; img-src *; media-src media1.com media2.com; script-src js.trusted.com
Allow images from any origin, but audio/video from only the 2 specified providers, and all scripts only from one specific server.frame-src
Allow for nested browsing contexts that load using elements such as<frame>
and<iframe>
.worker-src
Specifies valid (allowable) sources forWorker
,SharedWorker
, orServiceWorker
scripts.
Navigation Directives
Reporting Directives
Other Directives
upgrade-insecure-requests
Instructs user agents to treat all of a site's insecure URLs (those served over HTTP) as though they have been replaced with secure URLs (those served over HTTPS); intended for web sites with large numbers of insecure legacy URLs.
-
Content-Security-Policy-Report-Only: policy
Examples
Lockdown with "
default-src 'none';
"w.Header().Set("Content-Security-Policy", "default-src 'none';"+ // Forbid everything not explicitly declared. "script-src https://cdn.hard.net;"+ "style-src https://cdn.hard.net;"+ "img-src https://cdn.hard.net;"+ "connect-src https://api.hard.com;"+ // Restrict API-loaded URLs "child-src 'self'", // 'self' is origin server )
- The
connect-src
directive restricts URLs loaded per Web APIs:Fetch
,XMLHttpRequest
,WebSocket
, …
Note that CSP header(s) are not listed @ development tools of browsers (Chrome, Firefox).
SSL only
w.Header().Set("Content-Security-Policy", "default-src https:;"+ // SSL @ those not explicitly declared "object-src https://foo.com;"+ // specific host "script-src 'self' 'unsafe-inline';"+ // Forbid inline scripts "worker-src 'self'", )
Subresource Integrity (SRI)
Require match
integrity=...
value against the asset's cryptographic hash.<script src="https://foo.com/bundle.js" integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC" crossorigin="anonymous"></script>
The SRI (above) triggers CORS test at browser, so must include the access-control header …
Access-Control-Allow-Origin: *
Generate SRI of the asset (
$@
)#!/usr/bin/env bash [[ $(type -t openssl) ]] && { printf "sha384-$(cat "$@" | openssl dgst -sha384 -binary | openssl base64 -A)" } || { [[ $(type -t shasum) ]] && { printf "sha384-$(shasum -b -a 384 "$@" | awk '{ print $1 }' | xxd -r -p | base64)" } }
Accept-Encoding
requestAdvertises acceptable content compression schemes. Server selects one of the proposals, uses it and informs the client of its choice with the
Content-Encoding
response header. (The server may choose not to compress the body of a response.)Accept-Encoding: deflate, gzip;q=1.0, br, *;q=0.5
- Directives
- Quality values (
q=<#>
), orq-values
andq-factors
;
describing the order of priority.
- Quality values (
Accept
requestContent Negotiation: The client advertises (requests) acceptable media types (content types), expressed as MIME type(s). The server selects one (if more than one) and informs client per
Content-Type
response header attached to the resource.Accept: <MIME_type>/<MIME_subtype>
Accept: <MIME_type>/<MIME_subtype> Accept: <MIME_type>/* Accept: */*
Accept: text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8
MIME Types List
.html
HTML text/html
.css
CSS text/css
.js
JavaScript text/javascript
.json
JSON application/json
.jsonld
JSON-LD application/ld+json
.jsonp
JSONP application/javascript
.jpg
JPEG image/jpeg
.png
PNG image/png
.svg
SVG image/svg+xml
.ico
Win icons image/x-icon
Form POST multipart/form-data
Binary POST (upload) application/octet-stream
Range 206
(Partial Content)multipart/byteranges
Example
POST
:Request
<form action="/" method="post" enctype="multipart/form-data"> ... </form>
Response (See
Content-Type
.)
Content-Type
responseA header declaring the MIME type; media type. See
Content
Negotiation
.The most common one:
Content-Type: text/html; charset=UTF-8
@
HTTP POST
POST /foo HTTP/1.1 Content-Length: 68137 Content-Type: multipart/form-data; boundary=---...---974... ... X-Content-Type-Options: nosniff
# If sending binary (non-alphanumeric) data, or significantly sized payload: 'Content-Type: multipart/form-data' # Else send per URL-encoded string" 'Content-Type: application/x-www-form-urlencoded' # Body is one giant query-string equivalent; k1=v1&k2=v2
- Can send binary by URL-encoding, but is INEFFICIENT;
one byte encodes to (
base64url
) three 7-bit bytes
Content-Disposition
responseWhat to do with the resource; treat as part of a web page (
inline
), or as an attachment to save locally as a file. Also used @ multipart body …200 OK Content-Type: text/html; charset=utf-8 Content-Disposition: attachment; filename="cool.html" Content-Length: 21 <HTML>Save me!</HTML>
- "This simple HTML file will be saved as a regular download rather than displayed in the browser. Most browsers will propose to save it under the
cool.html
filename (by default)."
Accept-CH
(request header or meta tag)Client Hint for automating resource selection. The user agent advertises device specifications;
DPR
(Device Pixel Ratio) ,Viewport-Width
, andWidth
. This scheme is experimental; a work-in-progress (WIP).@
meta
tag (HTML)
<meta http-equiv="Accept-CH" content="DPR, Viewport-Width, Width">
<meta http-equiv="Accept-CH" content="Viewport-Width, Downlink"> <meta http-equiv="Accept-CH-Lifetime" content="86400">
@
Accept-CH
andAccept-CH-Lifetime
(HTTP headers)Accept-CH: Width, Viewport-Width Accept-CH-Lifetime: 100
Link Prefetching | Preload content (support)
@
rel="preload"
(HTML)<head> <link rel="preload" href="style.css" as="style"> <link rel="preload" href="main.js" as="script"> <link rel="preload" href="foo.mp4" as="video" type="video/mp4"> <link rel="stylesheet" href="style.css"> ... <body> <video controls> <source src="foo.mp4" type="video/mp4"> ... <script src="main.js" defer></script> ...
@
Link
request or response (HTTP header)Link: <http://www.example.com/white-paper.html>; rel=”canonical” Link: </feed>; rel=”alternate” Link: </images/big.jpg>; rel=prefetch
Feature-Policy
(support) responseDefine what features are allowed; limit pop-up permission dialogs.
Feature-Policy: <directive> <allowlist> Feature-Policy: vibrate 'none'; geolocation 'none'
Can be sent with request using HTML …
<iframe allow="camera 'none'; microphone 'none'">
Accept-Ranges
responseA marker used by the server to advertise its support of partial requests. The value of this field indicates the unit that can be used to define a range; browser may try to resume an interrupted download, rather than begin again.
Accept-Ranges: bytes
@ HTTP Range Requests
… for a server to send the requested resource in portions; useful for large media files; for those whose handler has pause/resume functions.
Test for server support:
If the
Accept-Ranges
is present in HTTP responses (and its value isn't "none"), then the server supports range requests:curl -I 'http://i.imgur.com/z4d4kWk.jpg' HTTP/1.1 200 OK ... Accept-Ranges: bytes Content-Length: 146515
- The