RFC 2068
Hypertext Transfer Protocol -- HTTP/1.1
Part 1 of 33 ๐
Title Block โจ
Hypertext Transfer Protocol -- HTTP/1.1 ๐
okay so this is RFC 2068 and it's giving standards-track royalty ๐. It was written by R. Fielding (UC Irvine), J. Gettys, J. Mogul (DEC), H. Frystyk, and T. Berners-Lee (MIT/LCS), all for the Network Working Group, and it's dated January 1997. Its category is Standards Track. The original doesn't list anything it obsoletes or updates, so there's nothing to report there ๐ซถ.
Status of this Memo ๐ธ
bestie, this one's basically a permission slip. It's an Internet standards track protocol for the Internet community, and the authors are literally asking everyone to discuss it and send suggestions for improvements ๐ . If you want the current standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐. And the memo can be distributed freely, no cap ๐ฆ.
Abstract ๐ง
okay so HTTP is an application-level protocol for distributed, collaborative, hypermedia information systems ๐. It's generic, stateless, and object-oriented, and you can stretch it to handle other jobs like name servers and distributed object management systems just by extending its request methods ๐ฅ. A big highlight is the typing and negotiation of data representation, which means you can build systems without tying them to whatever data is moving through them โจ.
HTTP has been powering the World-Wide Web global information initiative since 1990 ๐. This specification defines the version called "HTTP/1.1" ๐.
Table of Contents ๐
1 Introduction.............................................7
1.1 Purpose ..............................................7
1.2 Requirements .........................................7
1.3 Terminology ..........................................8
1.4 Overall Operation ...................................11
2 Notational Conventions and Generic Grammar..............13
2.1 Augmented BNF .......................................13
2.2 Basic Rules .........................................15
3 Protocol Parameters.....................................17
3.1 HTTP Version ........................................17
3.2 Uniform Resource Identifiers ........................18
3.2.1 General Syntax ...................................18
3.2.2 http URL .........................................19
3.2.3 URI Comparison ...................................20
3.3 Date/Time Formats ...................................21
3.3.1 Full Date ........................................21
3.3.2 Delta Seconds ....................................22
3.4 Character Sets ......................................22
3.5 Content Codings .....................................23
3.6 Transfer Codings ....................................24
3.7 Media Types .........................................25
3.7.1 Canonicalization and Text Defaults ...............26
3.7.2 Multipart Types ..................................27
3.8 Product Tokens ......................................28
3.9 Quality Values ......................................28
3.10 Language Tags ......................................28
3.11 Entity Tags ........................................29
3.12 Range Units ........................................30
4 HTTP Message............................................30
4.1 Message Types .......................................30
4.2 Message Headers .....................................31
4.3 Message Body ........................................32
4.4 Message Length ......................................32
4.5 General Header Fields ...............................34
5 Request.................................................34
5.1 Request-Line ........................................34
5.1.1 Method ...........................................35
5.1.2 Request-URI ......................................35
5.2 The Resource Identified by a Request ................37
5.3 Request Header Fields ...............................37
6 Response................................................38
6.1 Status-Line .........................................38
6.1.1 Status Code and Reason Phrase ....................39
6.2 Response Header Fields ..............................41
7 Entity..................................................41
7.1 Entity Header Fields ................................41
7.2 Entity Body .........................................42
7.2.1 Type .............................................42
7.2.2 Length ...........................................43
8 Connections.............................................43
8.1 Persistent Connections ..............................43
8.1.1 Purpose ..........................................43
8.1.2 Overall Operation ................................44
8.1.3 Proxy Servers ....................................45
8.1.4 Practical Considerations .........................45
8.2 Message Transmission Requirements ...................46
9 Method Definitions......................................48
9.1 Safe and Idempotent Methods .........................48
1. Introduction โจ
1.1 Purpose
Okay so, HTTP is an application-level protocol for distributed, collaborative, hypermedia information systems ๐ธ It's been powering the World-Wide Web since 1990! The first version, HTTP/0.9, was a super simple protocol for raw data transfer across the Internet ๐ฆ Then HTTP/1.0, defined in RFC 1945 [6], level-upped things by letting messages look like MIME-like messages, with metainformation about the data being transferred and modifiers on the request/response semantics โจ
But ngl, HTTP/1.0 didn't fully think through hierarchical proxies, caching, the need for persistent connections, and virtual hosts ๐ On top of that, so many half-finished apps were calling themselves "HTTP/1.0" that a protocol version change was needed so two communicating apps could figure out each other's true capabilities ๐
This spec defines the protocol called "HTTP/1.1" ๐ It has more stringent requirements than HTTP/1.0 so its features actually get implemented reliably. Main character energy, honestly ๐
Practical information systems need more than simple retrieval, like search, front-end update, and annotation. HTTP allows an open-ended set of methods that indicate the purpose of a request ๐ง It builds on the discipline of reference provided by the Uniform Resource Identifier (URI) [3][20], as a location (URL) [4] or name (URN) , for indicating the resource a method is applied to. Messages are passed in a format similar to Internet mail, as defined by the Multipurpose Internet Mail Extensions (MIME) ๐ฌ
HTTP is also used as a generic protocol for communication between user agents and proxies/gateways to other Internet systems, including those supported by the SMTP [16], NNTP [13], FTP [18], Gopher [2], and WAIS [10] protocols. So HTTP gives basic hypermedia access to resources from all kinds of diverse apps ๐
1.2 Requirements
Okay, this part is important, so listen up ๐ This specification uses the same words as RFC 1123 [8] to define how significant each requirement is. Here they are:
MUST This word or the adjective "required" means that the item is an absolute requirement of the specification. No exceptions, bestie ๐ซ
SHOULD This word or the adjective "recommended" means there may be valid reasons in particular circumstances to ignore this item, but the full implications should be understood and the case carefully weighed before choosing a different course ๐ค
MAY This word or the adjective "optional" means this item is truly optional. One vendor may include the item because a particular marketplace requires it or because it enhances the product, for example. Another vendor may omit the same item, and that's valid too ๐
An implementation is not compliant if it fails to satisfy one or more of the MUST requirements for the protocols it implements. An implementation that satisfies all the MUST and all the SHOULD requirements for its protocols is said to be "unconditionally compliant" โจ One that satisfies all the MUST requirements but not all the SHOULD requirements for its protocols is said to be "conditionally compliant." Both are valid, but one is clearly the flex ๐
1.3 Terminology
This specification uses a bunch of terms for the roles played by participants in, and objects of, the HTTP communication. Let's go through them ๐
connection A transport layer virtual circuit established between two programs for the purpose of communication ๐
message The basic unit of HTTP communication. It's a structured sequence of octets matching the syntax defined in section 4 and transmitted via the connection ๐ฆ
request An HTTP request message, as defined in section 5 ๐โโ๏ธ
response An HTTP response message, as defined in section 6 ๐
resource A network data object or service that can be identified by a URI, as defined in section 3.2. Resources may be available in multiple representations (e.g. multiple languages, data formats, size, resolutions) or vary in other ways ๐ธ
entity The information transferred as the payload of a request or response. An entity consists of metainformation in the form of entity-header fields and content in the form of an entity-body, as described in section 7 ๐
representation An entity included with a response that is subject to content negotiation, as described in section 12. There may exist multiple representations associated with a particular response status ๐ช
content negotiation The mechanism for selecting the appropriate representation when servicing a request, as described in section 12. The representation of entities in any response can be negotiated, including error responses. Yes, even the errors ๐ญ
variant A resource may have one, or more than one, representation(s) associated with it at any given instant. Each of these representations is termed a variant.' Use of the term variant' does not necessarily imply that the resource is subject to content negotiation ๐ฆ
client A program that establishes connections for the purpose of sending requests ๐ค
user agent The client which initiates a request. These are often browsers, editors, spiders (web-traversing robots), or other end user tools ๐ธ๏ธ
server An application program that accepts connections in order to service requests by sending back responses. Any given program may be capable of being both a client and a server. Our use of these terms refers only to the role the program is performing for a particular connection, rather than to the program's capabilities in general. Likewise, any server may act as an origin server, proxy, gateway, or tunnel, switching behavior based on the nature of each request ๐
origin server The server on which a given resource resides or is to be created ๐
proxy An intermediary program which acts as both a server and a client for the purpose of making requests on behalf of other clients. Requests are serviced internally or by passing them on, with possible translation, to other servers. A proxy must implement both the client and server requirements of this specification ๐ง
gateway A server which acts as an intermediary for some other server. Unlike a proxy, a gateway receives requests as if it were the origin server for the requested resource. The requesting client may not even be aware it's talking to a gateway ๐ต๏ธโโ๏ธ
tunnel An intermediary program which is acting as a blind relay between two connections. Once active, a tunnel is not considered a party to the HTTP communication, though the tunnel may have been initiated by an HTTP request. The tunnel ceases to exist when both ends of the relayed connections are closed ๐
cache A program's local store of response messages and the subsystem that controls its message storage, retrieval, and deletion. A cache stores cachable responses in order to reduce response time and network bandwidth consumption on future, equivalent requests. Any client or server may include a cache, though a cache cannot be used by a server that is acting as a tunnel ๐๏ธ
cachable A response is cachable if a cache is allowed to store a copy of the response message for use in answering subsequent requests. The rules for determining the cachability of HTTP responses are defined in section 13. Even if a resource is cachable, there may be additional constraints on whether a cache can use the cached copy for a particular request ๐ง
first-hand A response is first-hand if it comes directly and without unnecessary delay from the origin server, perhaps via one or more proxies. A response is also first-hand if its validity has just been checked directly with the origin server ๐ซถ
explicit expiration time The time at which the origin server intends that an entity should no longer be returned by a cache without further validation โฐ
heuristic expiration time An expiration time assigned by a cache when no explicit expiration time is available ๐ฎ
age The age of a response is the time since it was sent by, or successfully validated with, the origin server ๐ฐ๏ธ
freshness lifetime The length of time between the generation of a response and its expiration time โณ
fresh A response is fresh if its age has not yet exceeded its freshness lifetime. Fresh and fabulous โจ
stale A response is stale if its age has passed its freshness lifetime. Oof, it's giving expired ๐ฅ
semantically transparent A cache behaves in a "semantically transparent" manner, with respect to a particular response, when its use affects neither the requesting client nor the origin server, except to improve performance. When a cache is semantically transparent, the client receives exactly the same response (except for hop-by-hop headers) that it would have received had its request been handled directly by the origin server. Invisible helper energy ๐งโโ๏ธ
validator A protocol element (e.g., an entity tag or a Last-Modified time) that is used to find out whether a cache entry is an equivalent copy of an entity ๐
1.4 Overall Operation
HTTP is a request/response protocol, so the whole thing is basically a conversation ๐ฌ. A client sends a request to the server, and that request has a request method, a URI, and a protocol version, followed by a MIME-like message with request modifiers, client information, and possible body content. Everything travels over a connection with a server. The server replies with a status line that includes the message's protocol version and a success or error code, followed by a MIME-like message with server information, entity metainformation, and possible entity-body content. The relationship between HTTP and MIME is covered in appendix 19.4 ๐
Most HTTP communication starts with a user agent that wants a request applied to a resource on some origin server. In the simplest case, that happens over one single connection (v) between the user agent (UA) and the origin server (O). Very clean โจ
request chain ------------------------>
UA -------------------v------------------- O
<----------------------- response chain
Things get more interesting when one or more intermediaries show up in the request/response chain ๐ There are three common kinds. A proxy is a forwarding agent. It receives requests for a URI in its absolute form, rewrites all or part of the message, and forwards the reformatted request toward the server the URI points to. A gateway is a receiving agent that acts as a layer above some other server(s) and, if necessary, translates requests into the underlying server's protocol. A tunnel is a relay point between two connections that doesn't change the messages at all. Tunnels are used when communication needs to pass through an intermediary, like a firewall, even when that intermediary can't understand what the messages actually say ๐
request chain -------------------------------------->
UA -----v----- A -----v----- B -----v----- C -----v----- O
<------------------------------------- response chain
The figure above shows three intermediaries (A, B, and C) between the user agent and the origin server. A request or response that travels the whole chain goes through four separate connections, and this distinction matters a lot ๐ง Some HTTP communication options might only apply to the connection with the nearest, non-tunnel neighbor. Others apply only to the end-points of the chain, and some apply to every connection along the chain. Also, even though the diagram looks linear, each participant can be juggling multiple simultaneous communications. For example, B might be getting requests from lots of clients other than A, and/or forwarding requests to servers other than C, at the very same time it's handling A's request. Multitasking queen ๐
Any party to the communication that isn't acting as a tunnel may use an internal cache to handle requests. A cache makes the request/response chain shorter if one of the participants along the chain has a cached response that applies to the request. Here's what that looks like if B has a cached copy of an earlier response from O (which came via C) for a request that neither UA nor A has cached:
request chain ---------->
UA -----v----- A -----v----- B - - - - - - C - - - - - - O
<--------- response chain
Not every response is usefully cachable, and some requests come with modifiers that put special requirements on cache behavior. The HTTP requirements for cache behavior and cachable responses are defined in section 13 ๐ฆ
Honestly, there are a wild variety of cache and proxy architectures and configurations being experimented with or deployed across the World Wide Web right now ๐ Some are national hierarchies of proxy caches that save transoceanic bandwidth. Some broadcast or multicast cache entries. Some organizations distribute subsets of cached data on CD-ROM, and so on. HTTP systems run in corporate intranets over high-bandwidth links, and they're also used from PDAs with low-power radio links and intermittent connectivity. The goal of HTTP/1.1 is to support that huge diversity of already-deployed configurations while adding protocol constructs for people building web applications who need high reliability and, failing that, at least reliable indications of failure ๐
HTTP communication usually happens over TCP/IP connections. The default port is TCP 80, but other ports can be used too ๐ None of that stops HTTP from being implemented on top of any other protocol on the Internet, or on other networks. HTTP only presumes a reliable transport, so any protocol that provides those guarantees can be used. How the HTTP/1.1 request and response structures map onto the transport data units of that protocol is outside the scope of this specification, so that's a whole other story ๐ซถ
In HTTP/1.0, most implementations used a new connection for each request/response exchange. In HTTP/1.1, a connection may be used for one or more request/response exchanges, although connections may be closed for a variety of reasons (see section 8.1). Glow-up era ๐ฆ
2 Notational Conventions and Generic Grammar
2.1 Augmented BNF
Okay, so every mechanism in this document is described in both prose and an augmented Backus-Naur Form (BNF) that's similar to the one used by RFC 822 [9]. Implementers really do need to get comfy with this notation to understand the spec ๐ Here are the constructs it includes:
name = definition
The name of a rule is just the name itself (no enclosing < and >), and it's separated from its definition by the equal = character. Whitespace only matters in that indenting continuation lines shows a rule definition that spans more than one line. Certain basic rules are written in uppercase, like SP, LWS, HT, CRLF, DIGIT, ALPHA, and so on. Angle brackets get used inside definitions whenever their presence helps you tell which rule names are which ๐ธ
"literal"
Quotation marks wrap literal text. Unless stated otherwise, that text is case-insensitive ๐
rule1 | rule2
Elements separated by a bar (|) are alternatives. For example, "yes | no" will accept yes or no โจ
(rule1 rule2)
Elements inside parentheses are treated as a single element. So (elem (foo | bar) elem) allows the token sequences elem foo elem and elem bar elem ๐งฉ
*rule
The character * in front of an element means repetition. The full form is <n>*<m>element, which means at least <n> and at most <m> occurrences of the element. The default values are 0 and infinity, so *(element) allows any number, including zero. 1*element requires at least one, and 1*2element allows one or two ๐
[rule]
Square brackets enclose optional elements. [foo bar] is equivalent to *1(foo bar) ๐
N rule
This is specific repetition. <n>(element) is equivalent to <n>*<n>(element), meaning exactly <n> occurrences of the element. So 2DIGIT is a 2-digit number, and 3ALPHA is a string of three alphabetic characters ๐ข
#rule
The # construct is defined like *, but it's for defining lists of elements. The full form is <n>#<m>element, which means at least <n> and at most <m> elements, each separated by one or more commas (,) and optional linear whitespace (LWS). This makes normal lists super easy, since a rule like ( *LWS element *( *LWS "," *LWS element )) can be shown as 1#element. Wherever this construct is used, null elements are allowed, but they don't count toward the number of elements present. So (element), , (element) is permitted but only counts as two elements. That means that wherever at least one element is required, at least one non-null element must be present. The default values are 0 and infinity, so #element allows any number, including zero. 1#element requires at least one, and 1#2element allows one or two ๐
; comment
A semi-colon, set off some distance to the right of the rule text, starts a comment that continues to the end of the line. It's a simple way to include useful notes right alongside the specification ๐ฌ
implied *LWS
The grammar in this specification is word-based. Except where noted otherwise, linear whitespace (LWS) can be included between any two adjacent words (token or quoted-string), and between adjacent tokens and delimiters (tspecials), without changing how a field is interpreted. At least one delimiter (tspecials) must exist between any two tokens, because otherwise they'd be read as one single token. Don't skip the delimiter, bestie ๐ซ
2.2. Basic Rules
okay bestie, these are the building blocks everything else in the spec gets parsed out of, so pay attention ๐ the US-ASCII character set is defined by ANSI X3.4-1986 [21] ๐
OCTET = <any 8-bit sequence of data>
CHAR = <any US-ASCII character (octets 0 - 127)>
UPALPHA = <any US-ASCII uppercase letter "A".."Z">
LOALPHA = <any US-ASCII lowercase letter "a".."z">
ALPHA = UPALPHA | LOALPHA
DIGIT = <any US-ASCII digit "0".."9">
CTL = <any US-ASCII control character
(octets 0 - 31) and DEL (127)>
CR = <US-ASCII CR, carriage return (13)>
LF = <US-ASCII LF, linefeed (10)>
SP = <US-ASCII SP, space (32)>
HT = <US-ASCII HT, horizontal-tab (9)>
<"> = <US-ASCII double-quote mark (34)>
so HTTP/1.1 uses CR LF as the end-of-line marker for every protocol element โจ the only exception is the entity-body (see appendix 19.3 for tolerant applications) ๐ธ the end-of-line marker inside an entity-body is decided by its media type, as described in section 3.7 ๐ฆ
CRLF = CR LF
headers can get folded onto multiple lines ๐ง as long as the continuation line starts with a space or a horizontal tab. all linear white space, folding included, works the same as SP ๐
LWS = [CRLF] 1*( SP | HT )
the TEXT rule is only for descriptive field contents and values the message parser isn't supposed to interpret ๐ words of *TEXT can only use characters from character sets other than ISO 8859-1 [22] when they're encoded according to RFC 1522 [14] ๐
TEXT = <any OCTET except CTLs,
but including LWS>
hex characters show up in a bunch of protocol elements ๐ฅ
HEX = "A" | "B" | "C" | "D" | "E" | "F"
| "a" | "b" | "c" | "d" | "e" | "f" | DIGIT
lots of HTTP/1.1 header field values are words separated by LWS or special characters ๐ these special characters MUST be in a quoted string to be used within a parameter value. no exceptions, periodt ๐
token = 1*<any CHAR except CTLs or tspecials>
tspecials = "(" | ")" | "<" | ">" | "@"
| "," | ";" | ":" | "\" | <">
| "/" | "[" | "]" | "?" | "="
| "{" | "}" | SP | HT
comments can live inside some HTTP header fields ๐ you just wrap the comment text in parentheses. comments are only allowed in fields that have "comment" in their field value definition ๐ in all other fields, parentheses count as part of the field value ๐ญ
comment = "(" *( ctext | comment ) ")"
ctext = <any TEXT excluding "(" and ")">
a string of text gets parsed as one single word if you quote it with double-quote marks โจ
quoted-string = ( <"> *(qdtext) <"> )
qdtext = <any TEXT except <">>
the backslash ("") works as a single-character quoting mechanism, but only inside quoted-string and comment constructs ๐
quoted-pair = "\" CHAR
3. Protocol Parameters โจ
3.1. HTTP Version
HTTP uses a "<major>.<minor>" numbering scheme to show which version of the protocol is in play ๐ฆ the versioning is there so the sender can say what format a message is in and how much further HTTP communication it can handle, not what features that communication gets you ๐ adding message components that don't change communication behavior, or that only add to extensible field values, does not bump the version number ๐ธ the <minor> number goes up when the protocol gets features that don't change the general message parsing algorithm but might add to message semantics and imply extra capabilities for the sender ๐ง the <major> number goes up when the format of a message within the protocol changes ๐
the version of an HTTP message is shown by an HTTP-Version field in the first line of the message ๐
HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
ok this part is so important ๐ญ the major and minor numbers MUST be treated as separate integers, and each one can climb past a single digit. so HTTP/2.4 is a lower version than HTTP/2.13, which is lower than HTTP/12.3 ๐ฅ leading zeros MUST be ignored by recipients and MUST NOT be sent ๐
applications that send Request or Response messages, as this spec defines them, MUST include an HTTP-Version of "HTTP/1.1" ๐ using that version number tells everyone the sending application is at least conditionally compliant with this spec ๐
the HTTP version of an application is the highest HTTP version it's at least conditionally compliant with โจ
Note: proxies and gateways need to be extra careful when forwarding messages in protocol versions that are different from their own ๐ซถ since the protocol version tells everyone the sender's protocol capability, a proxy/gateway MUST never send a message with a version indicator greater than its actual version ๐ if it gets a higher-version request, the proxy/gateway MUST either downgrade the request version, respond with an error, or switch to tunnel behavior ๐ญ requests with a version lower than the proxy/gateway's own MAY be upgraded before being forwarded ๐ฆ and the proxy/gateway's response to that request MUST be in the same major version as the request ๐
Note: converting between HTTP versions may involve changing header fields that are required or forbidden by the versions involved ๐ธ
3.2. Uniform Resource Identifiers
URIs have been called a lot of things over the years ๐ WWW addresses, Universal Document Identifiers, Universal Resource Identifiers, and finally the mashup of Uniform Resource Locators (URL) and Names (URN) ๐ as far as HTTP is concerned, a URI is just a formatted string that identifies a resource, whether that's by name, location, or some other characteristic ๐ง
3.2.1. General Syntax
URIs in HTTP can be written in absolute form or relative to some known base URI, depending on the context ๐ฆ the two forms are told apart by one thing: absolute URIs always begin with a scheme name followed by a colon ๐
URI = ( absoluteURI | relativeURI ) [ "#" fragment ]
absoluteURI = scheme ":" *( uchar | reserved )
relativeURI = net_path | abs_path | rel_path
net_path = "//" net_loc [ abs_path ]
abs_path = "/" rel_path
rel_path = [ path ] [ ";" params ] [ "?" query ]
path = fsegment *( "/" segment )
fsegment = 1*pchar
segment = *pchar
params = param *( ";" param )
param = *( pchar | "/" )
scheme = 1*( ALPHA | DIGIT | "+" | "-" | "." )
net_loc = *( pchar | ";" | "?" )
query = *( uchar | reserved )
fragment = *( uchar | reserved )
pchar = uchar | ":" | "@" | "&" | "=" | "+"
uchar = unreserved | escape
unreserved = ALPHA | DIGIT | safe | extra | national
escape = "%" HEX HEX
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"
extra = "!" | "*" | "'" | "(" | ")" | ","
safe = "$" | "-" | "_" | "."
unsafe = CTL | SP | <"> | "#" | "%" | "<" | ">"
national = <any OCTET excluding ALPHA, DIGIT,
reserved, extra, safe, and unsafe>
for the real, definitive URL syntax and semantics, check out RFC 1738 [4] and RFC 1808 [11] ๐ the BNF above includes national characters that aren't allowed in valid URLs under RFC 1738 ๐ that's because HTTP servers aren't limited in which unreserved characters can show up in the rel_path part of addresses, and HTTP proxies might get requests for URIs that RFC 1738 never defined ๐
here's the length situation โจ HTTP doesn't put any a priori limit on how long a URI can be ๐ซถ servers MUST be able to handle the URI of any resource they serve, and SHOULD be able to handle URIs of unbounded length if they provide GET-based forms that could generate such URIs ๐ฅ a server SHOULD return 414 (Request-URI Too Long) status if a URI is longer than the server can handle (see section 10.4.15) ๐ญ
Note: servers should be careful about depending on URI lengths above 255 bytes, since some older client or proxy implementations may not properly support those lengths ๐
3.2.2. http URL
the "http" scheme is how you locate network resources over the HTTP protocol ๐ฆ this section defines the scheme-specific syntax and semantics for http URLs ๐
http_URL = "http:" "//" host [ ":" port ] [ abs_path ]
host = <A legal Internet host domain name
or IP address (in dotted-decimal form),
as defined by Section 2.1 of RFC 1123>
port = *DIGIT
if the port is empty or not given, port 80 is assumed ๐ the identified resource lives at the server listening for TCP connections on that port of that host, and the Request-URI for the resource is abs_path ๐ง the use of IP addresses in URL's SHOULD be avoided whenever possible (see RFC 1900 [24]) ๐ and if abs_path isn't in the URL, it MUST be given as "/" when used as a Request-URI for a resource (section 5.1.2) ๐
3.2.3. URI Comparison
when you're comparing two URIs to figure out if they match, a client SHOULD use a case-sensitive, octet-by-octet comparison of the entire URIs ๐ but there are a few exceptions ๐ธ
- a port that is empty or not given is equivalent to the default port for that URI;
- comparisons of host names MUST be case-insensitive;
- comparisons of scheme names MUST be case-insensitive;
- an empty abs_path is equivalent to an abs_path of "/".
characters outside the "reserved" and "unsafe" sets (see section 3.2) are equivalent to their ""%" HEX HEX" encodings ๐ฆ
for example, these three URIs are equivalent ๐ซถ
http://abc.com:80/~smith/home.html
http://ABC.com/%7Esmith/home.html
http://ABC.com:/%7esmith/home.html
3.3. Date/Time Formats
3.3.1 Full Date โจ
Okay bestie, so HTTP apps have historically allowed three different formats for writing date/time stamps ๐๏ธ, and it's giving chaos:
Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
The first format is the preferred Internet standard ๐. It's basically a fixed-length version of what RFC 1123 defines (and RFC 1123 is an update to RFC 822) ๐ . The second format is everywhere in the wild, but it's built on the obsolete RFC 850 [12] date format and it doesn't even have a four-digit year ๐. HTTP/1.1 clients and servers that parse the date value MUST accept all three formats (for compatibility with HTTP/1.0), though they MUST only generate the RFC 1123 format for representing HTTP-date values in header fields. So be accepting when you read and strict when you send ๐ซถ.
Note: Recipients of date values are encouraged to be robust in accepting date values that may have been sent by non-HTTP applications, as is sometimes the case when retrieving or posting messages via proxies/gateways to SMTP or NNTP.
All HTTP date/time stamps MUST be represented in Greenwich Mean Time (GMT), without exception ๐. The first two formats show this with "GMT" as the three-letter time zone abbreviation, and the asctime format MUST be assumed to be GMT when you read it ๐ฐ๏ธ.
HTTP-date = rfc1123-date | rfc850-date | asctime-date
rfc1123-date = wkday "," SP date1 SP time SP "GMT"
rfc850-date = weekday "," SP date2 SP time SP "GMT"
asctime-date = wkday SP date3 SP time SP 4DIGIT
date1 = 2DIGIT SP month SP 4DIGIT
; day month year (e.g., 02 Jun 1982)
date2 = 2DIGIT "-" month "-" 2DIGIT
; day-month-year (e.g., 02-Jun-82)
date3 = month SP ( 2DIGIT | ( SP 1DIGIT ))
; month day (e.g., Jun 2)
time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
; 00:00:00 - 23:59:59
wkday = "Mon" | "Tue" | "Wed"
| "Thu" | "Fri" | "Sat" | "Sun"
weekday = "Monday" | "Tuesday" | "Wednesday"
| "Thursday" | "Friday" | "Saturday" | "Sunday"
month = "Jan" | "Feb" | "Mar" | "Apr"
| "May" | "Jun" | "Jul" | "Aug"
| "Sep" | "Oct" | "Nov" | "Dec"
Note: HTTP requirements for the date/time stamp format apply only to their usage within the protocol stream. Clients and servers are not required to use these formats for user presentation, request logging, etc.
3.3.2 Delta Seconds โฑ๏ธ
Some HTTP header fields let you specify a time value as an integer number of seconds (written in decimal) counted from the moment the message was received. Very handy ๐ฆ.
delta-seconds = 1*DIGIT
3.4 Character Sets ๐ค
HTTP uses the exact same definition of "character set" that MIME uses ๐:
The term "character set" is used in this document to refer to a method used with one or more tables to convert a sequence of octets into a sequence of characters. Note that unconditional conversion in the other direction is not required, in that not all characters may be available in a given character set and a character set may provide more than one sequence of octets to represent a particular character. This definition is intended to allow various kinds of character encodings, from simple single-table mappings such as US-ASCII to complex table switching methods such as those that use ISO 2022's techniques. However, the definition associated with a MIME character set name MUST fully specify the mapping to be performed from octets to characters. In particular, use of external profiling information to determine the exact mapping is not permitted.
Note: This use of the term "character set" is more commonly referred to as a "character encoding." However, since HTTP and MIME share the same registry, it is important that the terminology also be shared.
HTTP character sets are identified by case-insensitive tokens ๐ง. The complete set of tokens is defined by the IANA Character Set registry [19].
charset = token
Even though HTTP lets you use any arbitrary token as a charset value, any token with a predefined value in the IANA Character Set registry MUST represent the character set defined by that registry ๐. Applications SHOULD limit their use of character sets to those defined by the IANA registry. Stick to the list, babe ๐.
3.5 Content Codings ๐๏ธ
Content coding values tell you about an encoding transformation that has been applied, or can be applied, to an entity ๐. Content codings mainly exist so a document can be compressed or otherwise usefully transformed without losing the identity of its underlying media type and without losing information. Usually the entity is stored in coded form, sent as-is, and only decoded by the recipient โจ.
content-coding = token
All content-coding values are case-insensitive. HTTP/1.1 uses content-coding values in the Accept-Encoding (section 14.3) and Content-Encoding (section 14.12) header fields. The value describes the content-coding, but what really matters is that it tells you what decoding mechanism will be needed to remove the encoding ๐.
The Internet Assigned Numbers Authority (IANA) acts as a registry for content-coding value tokens. To start, the registry contains the following tokens ๐ธ:
gzip An encoding format produced by the file compression program "gzip" (GNU zip) as described in RFC 1952 [25]. This format is a Lempel-Ziv coding (LZ77) with a 32 bit CRC.
compress The encoding format produced by the common UNIX file compression program "compress". This format is an adaptive Lempel-Ziv-Welch coding (LZW).
Note: Use of program names for the identification of encoding formats is not desirable and should be discouraged for future encodings. Their use here is representative of historical practice, not good design. For compatibility with previous implementations of HTTP, applications should consider "x-gzip" and "x-compress" to be equivalent to "gzip" and "compress" respectively.
deflate The "zlib" format defined in RFC 1950[31] in combination with the "deflate" compression mechanism described in RFC 1951[29].
New content-coding value tokens should be registered. For clients and servers to interoperate, the specs for the content coding algorithms needed to implement a new value should be publicly available and detailed enough for independent implementation, and they should match the purpose of content coding defined in this section ๐ง .
3.6 Transfer Codings ๐
Transfer coding values say that an encoding transformation has been, can be, or may need to be applied to an entity-body so it can get through the network "safely" ๐ก๏ธ. This is different from a content coding because a transfer coding is a property of the message, not of the original entity.
transfer-coding = "chunked" | transfer-extension
transfer-extension = token
All transfer-coding values are case-insensitive. HTTP/1.1 uses transfer coding values in the Transfer-Encoding header field (section 14.40).
Transfer codings are kind of like the Content-Transfer-Encoding values of MIME, which were designed to safely move binary data over a 7-bit transport service ๐ง. "Safe transport" means something different for an 8bit-clean transfer protocol, though. In HTTP, the only unsafe thing about message-bodies is that it can be hard to figure out the exact body length (section 7.2.2), or that you might want to encrypt data over a shared transport ๐.
The chunked encoding changes the body of a message so it can be sent as a series of chunks. Each chunk has its own size indicator, and there's an optional footer containing entity-header fields after them. This lets dynamically-produced content get sent along with the info the recipient needs to check that it got the whole message ๐.
Chunked-Body = *chunk
"0" CRLF
footer
CRLF
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF
hex-no-zero = <HEX excluding "0">
chunk-size = hex-no-zero *HEX
chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-value ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)
footer = *entity-header
The chunked encoding ends with a zero-sized chunk, then the footer, which finishes with an empty line ๐. The footer exists so you can efficiently send info about an entity that's generated dynamically. Applications MUST NOT send header fields in the footer that aren't explicitly defined as appropriate for the footer, like Content-MD5 or future HTTP extensions for digital signatures or other facilities. Don't be that person ๐ โโ๏ธ.
An example process for decoding a Chunked-Body is in appendix 19.4.6 ๐งฉ.
All HTTP/1.1 applications MUST be able to receive and decode the "chunked" transfer coding, and MUST ignore transfer coding extensions they don't understand ๐. A server that gets an entity-body with a transfer-coding it doesn't understand SHOULD return 501 (Unimplemented), and close the connection. A server MUST NOT send transfer-codings to an HTTP/1.0 client ๐.
3.7 Media Types ๐จ
HTTP uses Internet Media Types in the Content-Type (section 14.18) and Accept (section 14.1) header fields. That's how it gets open, extensible data typing and type negotiation ๐.
media-type = type "/" subtype *( ";" parameter )
type = token
subtype = token
Parameters can follow the type/subtype as attribute/value pairs ๐.
parameter = attribute "=" value
attribute = token
value = token | quoted-string
The type, subtype, and parameter attribute names are case-insensitive. Parameter values may or may not be case-sensitive, depending on what the parameter name means ๐ง. Linear white space (LWS) MUST NOT be used between the type and subtype, or between an attribute and its value ๐ซ. User agents that recognize the media-type MUST process the parameters for that MIME type as described by that type/subtype definition to the and inform the user of any problems discovered (or arrange to have them processed by any external applications the user agent uses for that type/subtype) ๐.
Note: some older HTTP applications do not recognize media type parameters. When sending data to older HTTP applications, implementations should only use media type parameters when they are required by that type/subtype definition.
Media-type values are registered with the Internet Assigned Number Authority (IANA). The media type registration process is outlined in RFC 2048 [17]. Using non-registered media types is discouraged ๐.
3.7.1 Canonicalization and Text Defaults โจ
okay so Internet media types get registered with a canonical form ๐ and in general, an entity-body sent through HTTP MUST be represented in that canonical form before it gets transmitted. the one exception is "text" types, which the next paragraph covers ๐ฆ
when it's in canonical form, media subtypes of "text" use CRLF as the line break. HTTP loosens this a bit ๐ธ it lets text media use a plain CR or a plain LF on its own as a line break, as long as it's done consistently across the whole entity-body. HTTP applications MUST accept CRLF, bare CR, and bare LF as line breaks in text media they receive over HTTP ๐ซถ and if the text uses a character set that doesn't use octets 13 and 10 for CR and LF (some multi-byte character sets do this), HTTP lets you use whatever octet sequences that character set defines for line breaks ๐ BUT this flexibility is only for text media in the entity-body. a bare CR or LF MUST NOT be swapped in for CRLF inside any HTTP control structures, like header fields and multipart boundaries ๐ โโ๏ธ
if an entity-body has a Content-Encoding, the underlying data MUST be in one of the forms above before it gets encoded ๐
the "charset" parameter tells you which character set (section 3.4) the data uses for some media types ๐ when the sender doesn't give an explicit charset, media subtypes of "text" are defined to default to "ISO-8859-1" when they come over HTTP. and data in any character set other than "ISO-8859-1" or its subsets MUST be labeled with a proper charset value ๐
ngl this part is so relatable ๐ญ some HTTP/1.0 software read a Content-Type header with no charset parameter as "recipient should guess" ๐ if a sender wants to avoid that, they MAY include a charset parameter even when the charset is ISO-8859-1, and they SHOULD do it when it's known it won't confuse the recipient โจ
unfortunately some older HTTP/1.0 clients couldn't handle an explicit charset parameter properly ๐ so HTTP/1.1 recipients MUST respect the charset label the sender gave them. and any user agents that can "guess" a charset MUST use the charset from the content-type field (if they support it) instead of the recipient's own preference when they first display a document ๐
3.7.2 Multipart Types ๐ง
MIME has a bunch of "multipart" types, which are encapsulations of one or more entities inside a single message-body ๐ they all share a common syntax, defined in MIME [7], and they MUST include a boundary parameter as part of the media type value. the message body is its own protocol element, so it MUST use only CRLF to represent line breaks between body-parts ๐ธ unlike regular MIME, the epilogue of any multipart message MUST be empty, and HTTP applications MUST NOT transmit the epilogue (even if the original multipart had one) ๐ โโ๏ธ
in HTTP, multipart body-parts MAY have header fields that matter for what that part means โจ a Content-Location header field (section 14.15) SHOULD be included in the body-part of each enclosed entity that can be identified by a URL ๐ฆ
generally, an HTTP user agent SHOULD act the same as, or similarly to, a MIME user agent would when it gets a multipart type ๐ and if an application gets a multipart subtype it doesn't recognize, it MUST treat it as "multipart/mixed" ๐ซถ
Note: "multipart/form-data" was specifically made for carrying form data that's meant to be processed with the POST request method, as described in RFC 1867 [15]. it's giving form data energy ๐โจ
3.8 Product Tokens ๐
product tokens let apps say who they are by software name and version ๐ most fields that use them also let you list sub-products that make up a big part of the app, separated by whitespace. by convention, the products are listed in order of how much they matter for identifying the app ๐
product = token ["/" product-version]
product-version = token
examples:
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
Server: Apache/0.8.4
product tokens should be short and to the point ๐ using them for advertising or other non-essential info is explicitly forbidden, no exceptions ๐ โโ๏ธ and even though any token character can show up in a product-version, this token SHOULD only be used for a version identifier (so successive versions of the same product SHOULD only differ in the product-version part of the product value) ๐
3.9 Quality Values ๐ธ
HTTP content negotiation (section 12) uses short "floating point" numbers to show how important ("weight") different negotiable parameters are ๐ฆ a weight gets normalized to a real number from 0 through 1, where 0 is the minimum and 1 is the maximum ๐ฅ HTTP/1.1 applications MUST NOT generate more than three digits after the decimal point ๐ user configuration of these values SHOULD also be limited the same way ๐
qvalue = ( "0" [ "." 0*3DIGIT ] )
| ( "1" [ "." 0*3("0") ] )
"Quality values" is kind of a misnomer ๐ญ these values just show the relative degradation in desired quality ๐ซถ
3.10 Language Tags ๐
a language tag identifies a natural language that humans speak, write, or otherwise use to share information with each other โจ computer languages are explicitly excluded ๐ โโ๏ธ HTTP uses language tags in the Accept-Language and Content-Language fields ๐
the syntax and registry of HTTP language tags is the same as the one defined by RFC 1766 [1] ๐ in short, a language tag has 1 or more parts: a primary language tag and a possibly empty series of subtags ๐
language-tag = primary-tag *( "-" subtag )
primary-tag = 1*8ALPHA
subtag = 1*8ALPHA
whitespace is not allowed inside the tag, and all tags are case-insensitive ๐ง the name space of language tags is administered by the IANA ๐ example tags include:
en, en-US, en-cockney, i-cherokee, x-pig-latin
where any two-letter primary-tag is an ISO 639 language abbreviation, and any two-letter initial subtag is an ISO 3166 country code ๐ธ (the last three tags above aren't registered tags. all but the last one are examples of tags that could be registered in the future ๐ฆ)
3.11 Entity Tags ๐
entity tags are used to compare two or more entities from the same requested resource ๐ HTTP/1.1 uses entity tags in the ETag (section 14.20), If-Match (section 14.25), If-None-Match (section 14.26), and If-Range (section 14.27) header fields ๐ซถ how they're used and compared as cache validators is in section 13.3.3 โจ an entity tag is an opaque quoted string, possibly prefixed by a weakness indicator ๐
entity-tag = [ weak ] opaque-tag
weak = "W/"
opaque-tag = quoted-string
a "strong entity tag" may be shared by two entities of a resource only if they are equivalent by octet equality ๐ฅ
a "weak entity tag," marked by the "W/" prefix, may be shared by two entities of a resource only if the entities are equivalent and could be swapped for each other with no significant change in semantics ๐ฆ a weak entity tag can only be used for weak comparison ๐
an entity tag MUST be unique across all versions of all entities associated with a particular resource ๐ a given entity tag value may be used for entities obtained by requests on different URIs, without implying anything about whether those entities are equivalent ๐
3.12 Range Units ๐ง
HTTP/1.1 lets a client ask for only part (a range of) the response entity to be included in the response ๐ HTTP/1.1 uses range units in the Range (section 14.36) and Content-Range (section 14.17) header fields ๐ an entity can be broken down into subranges based on different structural units โจ
range-unit = bytes-unit | other-range-unit
bytes-unit = "bytes"
other-range-unit = token
the only range unit HTTP/1.1 defines is "bytes" ๐ธ HTTP/1.1 implementations may ignore ranges specified with other units ๐ซถ and HTTP/1.1 was designed so that apps that don't depend on knowing about ranges can still work ๐
4 HTTP Message ๐
4.1 Message Types ๐ฆ
HTTP messages are made up of requests from client to server and responses from server to client ๐
HTTP-message = Request | Response ; HTTP/1.1 messages
Request (section 5) and Response (section 6) messages use the generic message format of RFC 822 [9] for transferring entities (the payload of the message) โจ both types of message have a start-line, one or more header fields (aka "headers"), an empty line (a line with nothing before the CRLF) that marks the end of the header fields, and an optional message-body ๐
generic-message = start-line
*message-header
CRLF
[ message-body ]
start-line = Request-Line | Status-Line
for the sake of robustness, servers SHOULD ignore any empty line(s) received where a Request-Line is expected ๐ in other words, if the server is reading the protocol stream at the start of a message and gets a CRLF first, it should ignore that CRLF ๐
Note: some buggy HTTP/1.0 client implementations send an extra CRLF after a POST request ๐ญ to restate what the BNF explicitly forbids, an HTTP/1.1 client must not put an extra CRLF before or after a request ๐ โโ๏ธ๐
4.2 Message Headers โจ
okay so header fields ๐
โ that's general-header (section 4.5), request-header (section 5.3), response-header (section 6.2), and entity-header (section 7.1) fields, and they all follow the same generic format as Section 3.1 of RFC 822 [9]. Each one is a name, then a colon (:), then the field value. Field names are case-insensitive ๐ฆ The value can start with any amount of LWS, but a single SP is the preferred vibe. You can also continue a header over multiple lines by starting each extra line with at least one SP or HT. And here's the important bit: applications SHOULD stick to "common form" when generating HTTP stuff ๐ซถ because some implementations are only ready for the common forms and will fail on anything fancier. Be a good citizen, bestie.
message-header = field-name ":" [ field-value ] CRLF
field-name = token
field-value = *( field-content | LWS )
field-content = <the OCTETs making up the field-value
and consisting of either *TEXT or combinations
of token, tspecials, and quoted-string>
The order that headers with different field names arrive in doesn't matter ๐ธ BUT it's "good practice" to send general-header fields first, then request-header or response-header fields, and wrap up with the entity-header fields. Very organized, very iconic.
Now the spicy part ๐ถ๏ธ Multiple message-header fields with the same field-name can show up in one message ONLY IF the whole field-value for that header is defined as a comma-separated list [i.e., #(values)]. Every single time, the multiple fields MUST be combinable into one "field-name: field-value" pair without changing what the message means, by appending each later field-value to the first one and separating them with commas. Since the order of same-named fields matters when you combine them, a proxy MUST NOT change the order of these field values when it forwards a message. Order is sacred here, no cap ๐ฅ
4.3 Message Body ๐
the message-body (if there is one) of an HTTP message is what carries the entity-body for the request or response. These two only differ when a transfer coding has been applied, which gets flagged by the Transfer-Encoding header field (section 14.40) ๐
message-body = entity-body
| <entity-body encoded as per Transfer-Encoding>
Here's the rule: Transfer-Encoding MUST be used to indicate any transfer codings an application has applied, so the message gets transferred safely and properly ๐ง It's a property of the message, not the entity, which means any application along the request/response chain can add or remove it. Main character energy for sure โจ
The rules for when a message-body is allowed are different for requests and responses, so let's split them up ๐ฆ
For requests, a message-body is signaled by including a Content-Length or Transfer-Encoding header field in the request's message-headers. A message-body MAY be included in a request only when the request method (section 5.1.1) allows an entity-body. ๐
For responses, it depends on BOTH the request method and the response status code (section 6.1.1) ๐ Every response to the HEAD request method MUST NOT include a message-body, even though the entity-header fields might make you think one is there. All 1xx (informational), 204 (no content), and 304 (not modified) responses MUST NOT include a message-body. Everything else DOES include a message-body, though it may be of zero length ๐
4.4 Message Length ๐
when a message-body comes with a message, its length is figured out by one of these, in order of precedence (the first one that applies wins, periodt ๐):
- Any response message which MUST NOT include a message-body (such as the 1xx, 204, and 304 responses and any response to a HEAD request) is always ended by the first empty line after the header fields, no matter which entity-header fields are in the message. ๐ญ
- If a
Transfer-Encodingheader field (section 14.40) is present and says the"chunked"transfer coding has been applied, then the length is defined by the chunked encoding (section 3.6). ๐ธ - If a
Content-Lengthheader field (section 14.14) is present, its value in bytes is the length of the message-body. ๐ - If the message uses the media type
"multipart/byteranges", which is self-delimiting, then that defines the length. This media type MUST NOT be used unless the sender knows the recipient can parse it. Also, a request with a Range header that has multiple byte-range specifiers implies the client can parsemultipart/byterangesresponses ๐ซถ - By the server closing the connection. (Closing the connection cannot be used to mark the end of a request body, because that would leave the server no way to send back a response. ๐)
For compatibility with HTTP/1.0 applications, HTTP/1.1 requests that contain a message-body MUST include a valid Content-Length header field, UNLESS the server is known to be HTTP/1.1 compliant. If a request has a message-body and no Content-Length, the server SHOULD respond with 400 (bad request) if it can't work out the length of the message, or with 411 (length required) if it wants to insist on a valid Content-Length. Strict but fair ๐
All HTTP/1.1 applications that receive entities MUST accept the "chunked" transfer coding (section 3.6). That lets this mechanism be used for messages whose length can't be known in advance, which is so useful โจ
Messages MUST NOT include both a Content-Length header field AND the "chunked" transfer coding. If both show up, the Content-Length MUST be ignored. Pick one, babe ๐ฅ
When a Content-Length is given in a message where a message-body is allowed, its field value MUST exactly match the number of OCTETs in the message-body. And HTTP/1.1 user agents MUST notify the user when an invalid length is received and detected. No hiding the bad news, bestie ๐
4.5 General Header Fields ๐ฆ
there are a few header fields that apply to both request and response messages, but they don't apply to the entity being transferred. They only apply to the message being sent, so they're basically the messages' own little accessories ๐
general-header = Cache-Control ; Section 14.9
| Connection ; Section 14.10
| Date ; Section 14.19
| Pragma ; Section 14.32
| Transfer-Encoding ; Section 14.40
| Upgrade ; Section 14.41
| Via ; Section 14.44
General-header field names can only be extended reliably together with a change in the protocol version ๐ New or experimental header fields may be given the semantics of general header fields if every party in the communication recognizes them as general-header fields. Unrecognized header fields are treated as entity-header fields. iykyk ๐ง
5 Request ๐
a request message from a client to a server includes, in its first line, the method to be applied to the resource, the identifier of the resource, and the protocol version in use. The whole shape looks like this ๐
Request = Request-Line ; Section 5.1
*( general-header ; Section 4.5
| request-header ; Section 5.3
| entity-header ) ; Section 7.1
CRLF
[ message-body ] ; Section 7.2
5.1 Request-Line โจ
the Request-Line starts with a method token, followed by the Request-URI and the protocol version, and it ends with CRLF. The elements are separated by SP characters. No CR or LF is allowed except in the final CRLF sequence. Very strict, very clean ๐ซถ
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
5.1.1 Method ๐ธ
the Method token says what should be done to the resource identified by the Request-URI. The method is case-sensitive, so get and GET are NOT the same girl ๐
Method = "OPTIONS" ; Section 9.2
| "GET" ; Section 9.3
| "HEAD" ; Section 9.4
| "POST" ; Section 9.5
| "PUT" ; Section 9.6
| "DELETE" ; Section 9.7
| "TRACE" ; Section 9.8
| extension-method
extension-method = token
A resource's allowed methods can be listed in an Allow header field (section 14.7). The response's return code always tells the client whether a method is allowed on a resource right now, because the allowed set can change on the fly ๐ฆ Servers SHOULD return status code 405 (Method Not Allowed) if the method is known to the server but not allowed for that resource, and 501 (Not Implemented) if the method is unrecognized or not implemented by the server. The methods a server knows can be listed in a Public response-header field (section 14.35) ๐
The methods GET and HEAD MUST be supported by all general-purpose servers. All other methods are optional. But if the methods above ARE implemented, they MUST be implemented with the same semantics as those in section 9 ๐ฅ
5.1.2. Request-URI ๐
okay so the Request-URI is a Uniform Resource Identifier (section 3.2) and it tells the server which resource the request is about ๐ฆ
Request-URI = "*" | absoluteURI | abs_path
there are three options for the Request-URI and which one you use depends on what kind of request you're sending ๐ the asterisk "*" means the request isn't about a particular resource, it's about the server itself, and you can only use it when the method doesn't have to apply to a resource. an example would be
OPTIONS * HTTP/1.1
the absoluteURI form is required when you're sending the request to a proxy ๐ซถ the proxy is asked to forward the request, or serve it from a valid cache, and send back the response. the proxy MAY forward the request on to another proxy or straight to the server named in the absoluteURI โจ but to avoid request loops, a proxy MUST be able to recognize all of its server names, including any aliases, local variations, and the numeric IP address ๐ญ an example Request-Line would be:
GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
so future versions of HTTP can switch to absoluteURIs in every request, all HTTP/1.1 servers MUST accept the absoluteURI form in requests ๐ even though HTTP/1.1 clients will only actually generate them for requests going to proxies
the most common form of Request-URI is the one used to reach a resource on an origin server or gateway ๐ in that case the absolute path of the URI MUST be transmitted (see section 3.2.1, abs_path) as the Request-URI, and the network location of the URI (net_loc) MUST be transmitted in a Host header field. for example, a client that wants to grab the resource above straight from the origin server would open a TCP connection to port 80 of the host "www.w3.org" and send these lines:
GET /pub/WWW/TheProject.html HTTP/1.1 Host: www.w3.org
and then the rest of the request โจ quick note: the absolute path cannot be empty. if there isn't one in the original URI, it MUST be given as "/" (the server root) ๐
if a proxy gets a request with no path in the Request-URI, and the method can support the asterisk form, then the last proxy on the request chain MUST forward the request with "*" as the final Request-URI ๐ง for example, this request
OPTIONS http://www.ics.uci.edu:8001 HTTP/1.1
would get forwarded by the proxy as
OPTIONS * HTTP/1.1 Host: www.ics.uci.edu:8001
after it connects to port 8001 of the host "www.ics.uci.edu" ๐
the Request-URI is sent in the format from section 3.2.1. the origin server MUST decode the Request-URI so it can properly understand the request ๐ and servers SHOULD respond to invalid Request-URIs with an appropriate status code
when proxies forward requests, they MUST NOT rewrite the "abs_path" part of a Request-URI in any way, no matter what their internal implementation does ๐ฅ the only exception is the one noted above, replacing a null abs_path with "*"
Note: The "no rewrite" rule prevents the proxy from changing the meaning of the request when the origin server is improperly using a non-reserved URL character for a reserved purpose. Implementers should be aware that some pre-HTTP/1.1 proxies have been known to rewrite the Request-URI.
5.2. The Resource Identified by a Request ๐ธ
HTTP/1.1 origin servers SHOULD be aware that the exact resource an Internet request is pointing at is determined by looking at both the Request-URI and the Host header field ๐
an origin server that doesn't let resources differ by requested host MAY ignore the Host header field value. (but see section 19.5.1 for other requirements on Host support in HTTP/1.1 ๐)
an origin server that DOES tell resources apart based on the host requested (sometimes called virtual hosts or vanity hostnames) MUST use these rules to work out the requested resource on an HTTP/1.1 request, and it's giving very organized energy ๐
- If Request-URI is an absoluteURI, the host is part of the Request-URI. Any Host header field value in the request MUST be ignored.
- If the Request-URI is not an absoluteURI, and the request includes a Host header field, the host is determined by the Host header field value.
- If the host as determined by rule 1 or 2 is not a valid host on the server, the response MUST be a 400 (Bad Request) error message.
recipients of an HTTP/1.0 request that has no Host header field MAY try heuristics (like checking the URI path for something unique to a particular host) to figure out which exact resource is being asked for ๐ต๏ธโโ๏ธ
5.3. Request Header Fields ๐
the request-header fields let the client pass extra info about the request, and about the client itself, over to the server โจ they act as request modifiers, kind of like the parameters you pass into a programming language method call ๐
request-header = Accept ; Section 14.1
| Accept-Charset ; Section 14.2 |
|---|
| Accept-Encoding ; Section 14.3 |
| Accept-Language ; Section 14.4 |
| Authorization ; Section 14.8 |
| From ; Section 14.22 |
| Host ; Section 14.23 |
| If-Modified-Since ; Section 14.24 |
| If-Match ; Section 14.25 |
| If-None-Match ; Section 14.26 |
| If-Range ; Section 14.27 |
| If-Unmodified-Since ; Section 14.28 |
| Max-Forwards ; Section 14.31 |
| Proxy-Authorization ; Section 14.34 |
| Range ; Section 14.36 |
| Referer ; Section 14.37 |
| User-Agent ; Section 14.42 |
request-header field names can only be extended reliably in combination with a change in the protocol version ๐ฆ however, new or experimental header fields MAY be given the semantics of request-header fields if all parties in the communication recognize them as request-header fields. unrecognized header fields are treated as entity-header fields ๐
6. Response ๐
after a server receives and interprets a request message, it responds with an HTTP response message ๐ซถ
Response = Status-Line ; Section 6.1 *( general-header ; Section 4.5
| response-header ; Section 6.2 |
|---|
| entity-header ) ; Section 7.1 |
CRLF [ message-body ] ; Section 7.2
6.1. Status-Line ๐
the first line of a Response message is the Status-Line, which is made of the protocol version, then a numeric status code, then its matching textual phrase, with each element separated by SP characters ๐ง no CR or LF is allowed except in the final CRLF sequence ๐
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
6.1.1. Status Code and Reason Phrase ๐ธ
the Status-Code is a 3-digit integer result code for how the attempt to understand and satisfy the request went ๐ these codes are fully defined in section 10. the Reason-Phrase is meant to be a short textual description of the Status-Code. the Status-Code is for automata (machines!) and the Reason-Phrase is for the human user ๐ค the client doesn't have to examine or display the Reason-Phrase ๐
the first digit of the Status-Code defines the class of response ๐ฅ the last two digits don't have any categorization role. there are 5 values for the first digit:
- 1xx: Informational - Request received, continuing process
- 2xx: Success - The action was successfully received, understood, and accepted
- 3xx: Redirection - Further action must be taken in order to complete the request
- 4xx: Client Error - The request contains bad syntax or cannot be fulfilled
- 5xx: Server Error - The server failed to fulfill an apparently valid request
here are the individual numeric status codes defined for HTTP/1.1, plus an example set of matching Reason-Phrases ๐ the reason phrases listed here are only recommended, and they can be swapped for local equivalents without affecting the protocol โจ
Status-Code = "100" ; Continue
| "101" ; Switching Protocols |
|---|
| "200" ; OK |
| "201" ; Created |
| "202" ; Accepted |
| "203" ; Non-Authoritative Information |
| "204" ; No Content |
| "205" ; Reset Content |
| "206" ; Partial Content |
| "300" ; Multiple Choices |
| "301" ; Moved Permanently |
| "302" ; Moved Temporarily |
| "303" ; See Other |
| "304" ; Not Modified |
| "305" ; Use Proxy |
| "400" ; Bad Request |
| "401" ; Unauthorized |
| "402" ; Payment Required |
| "403" ; Forbidden |
| "404" ; Not Found |
| "405" ; Method Not Allowed |
| "406" ; Not Acceptable |
| "407" ; Proxy Authentication Required |
| "408" ; Request Time-out |
| "409" ; Conflict |
| "410" ; Gone |
| "411" ; Length Required |
| "412" ; Precondition Failed |
| "413" ; Request Entity Too Large |
| "414" ; Request-URI Too Large |
| "415" ; Unsupported Media Type |
| "500" ; Internal Server Error |
| "501" ; Not Implemented |
| "502" ; Bad Gateway |
| "503" ; Service Unavailable |
| "504" ; Gateway Time-out |
| "505" ; HTTP Version not supported |
| extension-code |
extension-code = 3DIGIT
Reason-Phrase = *<TEXT, excluding CR, LF>
HTTP status codes are extensible ๐ HTTP applications don't have to understand every registered status code, though understanding them is obviously desirable ๐ however, applications MUST understand the class of any status code, as shown by the first digit, and treat any unrecognized response as equivalent to the x00 status code of that class, with one exception: an unrecognized response MUST NOT be cached ๐ โโ๏ธ for example, if a client gets an unrecognized status code of 431, it can safely assume something was wrong with its request and treat the response as if it had gotten a 400 status code ๐ญ in cases like this, user agents SHOULD show the user the entity returned with the response, since that entity is likely to include human-readable info explaining the unusual status ๐ซถ
6.2. Response Header Fields ๐
Okay so response headers are how the server sneaks in extra info that just doesn't fit in the Status-Line ๐ Think of it as the server giving you the tea on itself and on what you can do next with the resource at the Request-URI โจ
response-header = Age ; Section 14.6
| Location ; Section 14.30
| Proxy-Authenticate ; Section 14.33
| Public ; Section 14.35
| Retry-After ; Section 14.38
| Server ; Section 14.39
| Vary ; Section 14.43
| Warning ; Section 14.45
| WWW-Authenticate ; Section 14.46
Real talk, response header names can only be extended reliably alongside a protocol version change ๐ฆ BUT new or experimental header fields MAY be given response-header semantics, as long as every party in the conversation recognizes them as response headers ๐ And if nobody recognizes a header, it gets treated as an entity-header field, so it's not lost in the void ๐ง
7. Entity โจ
Okay bestie, here's the deal: Request and Response messages MAY carry an entity, as long as the request method or response status code doesn't say otherwise ๐ซถ An entity is made up of entity-header fields and an entity-body, though some responses only bring the entity-headers to the party ๐
Quick heads up, in this section "sender" and "recipient" just mean whoever is the client or the server, depending on who's sending and who's receiving the entity ๐ธ
7.1. Entity Header Fields ๐
These fields are optional metainformation about the entity-body, or if there's no body, about the resource the request identified ๐
entity-header = Allow ; Section 14.7
| Content-Base ; Section 14.11
| Content-Encoding ; Section 14.12
| Content-Language ; Section 14.13
| Content-Length ; Section 14.14
| Content-Location ; Section 14.15
| Content-MD5 ; Section 14.16
| Content-Range ; Section 14.17
| Content-Type ; Section 14.18
| ETag ; Section 14.20
| Expires ; Section 14.21
| Last-Modified ; Section 14.29
| extension-header
extension-header = message-header
The extension-header thing lets you define extra entity-header fields without changing the protocol ๐ฅ But you can't assume the recipient will recognize them, ngl ๐ Unrecognized header fields SHOULD be ignored by the recipient and forwarded by proxies ๐
7.2. Entity Body ๐ฆ
The entity-body (if there is one) in an HTTP request or response is in whatever format and encoding the entity-header fields say it's in ๐
entity-body = *OCTET
An entity-body only shows up when a message-body is there too, as covered in section 4.3 โจ To get the entity-body, you decode whatever Transfer-Encoding was applied to the message-body, so the transfer stays safe and proper ๐ซถ
7.2.1. Type ๐
When a message includes an entity-body, its data type comes from the Content-Type and Content-Encoding header fields. Together they make a two-layer, ordered encoding model, and it's giving very specific ๐
entity-body := Content-Encoding( Content-Type( data ) )
Content-Type tells you the media type of the underlying data ๐ Content-Encoding can name any extra content codings applied to the data, usually for compression, which are a property of the requested resource ๐๏ธ There is no default encoding, so don't go looking for one ๐
Any HTTP/1.1 message with an entity-body SHOULD include a Content-Type header field that defines the media type of that body ๐ If and only if the media type isn't given by a Content-Type field, the recipient MAY try to guess it by inspecting the content and/or the name extension(s) of the URL used to identify the resource ๐ If the media type is still unknown, the recipient SHOULD treat it as type "application/octet-stream" ๐ง
7.2.2. Length ๐ธ
The length of an entity-body is the length of the message-body after any transfer codings have been removed ๐ Section 4.4 explains how the length of a message-body gets figured out ๐
8. Connections โจ
8.1. Persistent Connections ๐ฆ
8.1.1. Purpose ๐
Before persistent connections, every URL needed its own separate TCP connection ๐ญ That meant more load on HTTP servers and congestion on the Internet, which was not it ๐ Inline images and other associated data often mean a client has to hit the same server a bunch of times in a short window, so the performance problems were real ๐ฅ Analyses of these are available in [30][27], and analysis plus results from a prototype implementation are in [26] ๐
Persistent HTTP connections come with a bunch of perks, bestie ๐
- By opening and closing fewer TCP connections, CPU time gets saved, and so does the memory used for TCP protocol control blocks ๐
- HTTP requests and responses can be pipelined on a connection ๐ Pipelining lets a client make multiple requests without waiting for each response, so a single TCP connection gets used way more efficiently, with much lower elapsed time โญ
- Network congestion goes down because there are fewer packets from TCP opens, and TCP gets enough time to figure out the congestion state of the network ๐
- HTTP can evolve more gracefully, since errors can be reported without the penalty of closing the TCP connection ๐ฆ Clients using future versions of HTTP might optimistically try a new feature, and if they're talking to an older server, they can retry with the old semantics after an error is reported ๐ซถ
HTTP implementations SHOULD implement persistent connections โจ
8.1.2. Overall Operation ๐
Here's the big difference between HTTP/1.1 and earlier versions: persistent connections are the default behavior for any HTTP connection ๐ Unless something says otherwise, the client can assume the server will keep a persistent connection open for it ๐ฆ
Persistent connections also give the client and server a way to signal that a TCP connection should close ๐ธ That signal goes through the Connection header field ๐จ Once a close has been signaled, the client MUST not send any more requests on that connection ๐ โโ๏ธ
8.1.2.1. Negotiation ๐
Hmm, heading depth note: this is ### per the format rules, so it's written below.
Okay so an HTTP/1.1 server MAY assume an HTTP/1.1 client wants a persistent connection, unless the request had a Connection header including the connection-token close ๐ If the server decides to close the connection right after sending the response, it SHOULD send a Connection header including the connection-token close ๐ฅ
An HTTP/1.1 client MAY expect a connection to stay open, but it decides whether to keep it open based on whether the server's response has a Connection header with the connection-token close ๐ If the client doesn't want to keep the connection for more than that one request, it SHOULD send a Connection header including the connection-token close โจ
If either the client or the server sends the close token in the Connection header, that request becomes the last one on the connection ๐ซถ
Clients and servers SHOULD NOT assume a persistent connection is maintained for HTTP versions less than 1.1 unless it's explicitly signaled ๐ See section 19.7.1 for more on backwards compatibility with HTTP/1.0 clients ๐
To stay persistent, every message on the connection has to have a self-defined message length, meaning one not defined by the connection closing, as described in section 4.4 ๐
8.1.2.2. Pipelining ๐ง
A client that supports persistent connections MAY "pipeline" its requests, which means sending multiple requests without waiting for each response ๐ A server MUST send its responses to those requests in the same order the requests were received ๐ฌ
Clients that assume persistent connections and pipeline right after connection establishment SHOULD be ready to retry their connection if the first pipelined attempt fails ๐ If a client does retry, it MUST NOT pipeline until it knows the connection is persistent ๐ โโ๏ธ Clients MUST also be ready to resend their requests if the server closes the connection before sending all of the corresponding responses ๐ญ
8.1.3. Proxy Servers ๐ธ
It's especially important that proxies correctly implement the properties of the Connection header field as specified in 14.2.1 ๐
The proxy server MUST signal persistent connections separately with its clients and with the origin servers (or other proxy servers) it connects to ๐ Each persistent connection applies to only one transport link ๐ฆ
A proxy server MUST NOT establish a persistent connection with an HTTP/1.0 client ๐
8.1.4. Practical Considerations ๐
Servers usually have some time-out value past which they stop maintaining an inactive connection โฐ Proxy servers might set this higher, since the client is probably making more connections through the same server ๐ Using persistent connections puts no requirements on how long this time-out is, for either the client or the server โจ
When a client or server wants to time-out, it SHOULD issue a graceful close on the transport connection ๐ Clients and servers SHOULD both constantly watch for the other side closing the transport, and respond to it as appropriate ๐ If a client or server doesn't notice the other side's close promptly, it could cause unnecessary resource drain on the network ๐ฉ
A client, server, or proxy MAY close the transport connection at any time ๐ For example, a client MAY have started sending a new request at the exact moment the server decided to close the "idle" connection ๐ณ From the server's point of view the connection was closed while it was idle, but from the client's point of view a request was in progress ๐ซ
So clients, servers, and proxies MUST be able to recover from asynchronous close events ๐ ๏ธ Client software SHOULD reopen the transport connection and retransmit the aborted request without user interaction, as long as the request method is idempotent (see section 9.1.2) ๐ Other methods MUST NOT be automatically retried, although user agents MAY offer a human operator the choice of retrying the request ๐โโ๏ธ
That said, this automatic retry SHOULD NOT be repeated if the second request fails ๐
Servers SHOULD always respond to at least one request per connection, if at all possible โจ Servers SHOULD NOT close a connection in the middle of transmitting a response, unless a network or client failure is suspected ๐ซ
Clients that use persistent connections SHOULD limit how many simultaneous connections they maintain to a given server ๐ A single-user client SHOULD maintain AT MOST 2 connections with any server or proxy ๐ซถ A proxy SHOULD use up to 2*N connections to another server or proxy, where N is the number of simultaneously active users ๐ These guidelines exist to improve HTTP response times and avoid congestion of the Internet or other networks ๐ง
8.2. Message Transmission Requirements ๐
Okay so the general requirements are basically the golden rules of HTTP/1.1 connections ๐
- HTTP/1.1 servers SHOULD keep persistent connections alive ๐ซถ and lean on TCP's flow control to handle temporary overloads, instead of slamming connections shut and hoping clients come back to retry. ngl that second move can make network congestion way worse ๐
- An HTTP/1.1 (or later) client sending a message-body SHOULD keep an eye on the network connection for an error status while it's still sending the request ๐ If the client sees an error status, it SHOULD immediately stop sending the body. If the body is going out with a "chunked" encoding (section 3.6), a zero length chunk and empty footer MAY be used to prematurely mark the end of the message โจ If the body was preceded by a Content-Length header, the client MUST close the connection.
- An HTTP/1.1 (or later) client MUST be prepared to accept a 100 (Continue) status followed by a regular response ๐
- An HTTP/1.1 (or later) server that gets a request from a HTTP/1.0 (or earlier) client MUST NOT transmit the 100 (continue) response ๐ it SHOULD either wait for the request to be completed normally (thus avoiding an interrupted request) or close the connection prematurely.
Upon receiving a method subject to these requirements from an HTTP/1.1 (or later) client, an HTTP/1.1 (or later) server MUST either respond with 100 (Continue) status and continue to read from the input stream, or respond with an error status. If it responds with an error status, it MAY close the transport (TCP) connection or it MAY continue to read and discard the rest of the request. It MUST NOT perform the requested method if it returns an error status ๐ซ
Clients SHOULD remember the version number of at least the most recently used server ๐ง if an HTTP/1.1 client has seen an HTTP/1.1 or later response from the server, and it sees the connection close before receiving any status from the server, the client SHOULD retry the request without user interaction so long as the request method is idempotent (see section 9.1.2) ๐ other methods MUST NOT be automatically retried, although user agents MAY offer a human operator the choice of retrying the request.. If the client does retry the request, the client:
- MUST first send the request header fields, and then
- MUST wait for the server to respond with either a 100 (Continue) response, in which case the client should continue, or with an error status ๐ซง
If an HTTP/1.1 client has not seen an HTTP/1.1 or later response from the server, it should assume that the server implements HTTP/1.0 or older and will not use the 100 (Continue) response ๐ค If in this case the client sees the connection close before receiving any status from the server, the client SHOULD retry the request. If the client does retry the request to this HTTP/1.0 server, it should use the following "binary exponential backoff" algorithm to be assured of obtaining a reliable response ๐ธ
- Initiate a new connection to the server
- Transmit the request-headers
- Initialize a variable R to the estimated round-trip time to the server (e.g., based on the time it took to establish the connection), or to a constant value of 5 seconds if the round-trip time is not available.
- Compute
T = R * (2**N), where N is the number of previous retries of this request. - Wait either for an error response from the server, or for T seconds (whichever comes first)
- If no error response is received, after T seconds transmit the body of the request.
- If client sees that the connection is closed prematurely, repeat from step 1 until the request is accepted, an error response is received, or the user becomes impatient and terminates the retry process. ๐ค
No matter what the server version, if an error status is received, the client:
- MUST NOT continue and
- MUST close the connection if it has not completed sending the message.
An HTTP/1.1 (or later) client that sees the connection close after receiving a 100 (Continue) but before receiving any other status SHOULD retry the request, and need not wait for 100 (Continue) response (but MAY do so if this simplifies the implementation) ๐
9 Method Definitions ๐
The set of common methods for HTTP/1.1 is defined below. Although this set can be expanded, additional methods cannot be assumed to share the same semantics for separately extended clients and servers ๐ง
The Host request-header field (section 14.23) MUST accompany all HTTP/1.1 requests ๐
9.1 Safe and Idempotent Methods
9.1.1 Safe Methods
Implementers should be aware that the software represents the user in their interactions over the Internet, and should be careful to allow the user to be aware of any actions they may take which may have an unexpected significance to themselves or others ๐ซถ
In particular, the convention has been established that the GET and HEAD methods should never have the significance of taking an action other than retrieval. These methods should be considered "safe." This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested โจ
Naturally, it is not possible to ensure that the server does not generate side-effects as a result of performing a GET request; in fact, some dynamic resources consider that a feature ๐ The important distinction here is that the user did not request the side-effects, so therefore cannot be held accountable for them ๐
9.1.2 Idempotent Methods
Methods may also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property ๐
9.2 OPTIONS
The OPTIONS method represents a request for information about the communication options available on the request/response chain identified by the Request-URI. This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval ๐
Unless the server's response is an error, the response MUST NOT include entity information other than what can be considered as communication options (e.g., Allow is appropriate, but Content-Type is not). Responses to this method are not cachable ๐ซ
If the Request-URI is an asterisk ("*"), the OPTIONS request is intended to apply to the server as a whole. A 200 response SHOULD include any header fields which indicate optional features implemented by the server (e.g., Public), including any extensions not defined by this specification, in addition to any applicable general or response-header fields. As described in section 5.1.2, an "OPTIONS *" request can be applied through a proxy by specifying the destination server in the Request-URI without any path information ๐
If the Request-URI is not an asterisk, the OPTIONS request applies only to the options that are available when communicating with that resource. A 200 response SHOULD include any header fields which indicate optional features implemented by the server and applicable to that resource (e.g., Allow), including any extensions not defined by this specification, in addition to any applicable general or response-header fields. If the OPTIONS request passes through a proxy, the proxy MUST edit the response to exclude those options which apply to a proxy's capabilities and which are known to be unavailable through that proxy ๐งน
9.3 GET
The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity in the response and not the source text of the process, unless that text happens to be the output of the process ๐ฆ
The semantics of the GET method change to a "conditional GET" if the request message includes an If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, or If-Range header field. A conditional GET method requests that the entity be transferred only under the circumstances described by the conditional header field(s). The conditional GET method is intended to reduce unnecessary network usage by allowing cached entities to be refreshed without requiring multiple requests or transferring data already held by the client ๐ฆ
The semantics of the GET method change to a "partial GET" if the request message includes a Range header field. A partial GET requests that only part of the entity be transferred, as described in section 14.36. The partial GET method is intended to reduce unnecessary network usage by allowing partially-retrieved entities to be completed without transferring data already held by the client ๐งฉ
The response to a GET request is cachable if and only if it meets the requirements for HTTP caching described in section 13 ๐
9.4 HEAD
The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification ๐
The response to a HEAD request may be cachable in the sense that the information contained in the response may be used to update a previously cached entity from that resource. If the new field values indicate that the cached entity differs from the current entity (as would be indicated by a change in Content-Length, Content-MD5, ETag or Last-Modified), then the cache MUST treat the cache entry as stale ๐ซ
9.5 POST
okay bestie, POST is the method that says "hey server, please accept this entity as a brand new subordinate of the resource in my Request-Line!" ๐ The Request-URI is the boss, and the entity you send is its new little helper. ๐ The vibe is that one method covers a bunch of different jobs:
- Annotating an existing resource ๐
- Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles ๐ฎ
- Handing over a block of data, like the result of submitting a form, to a data-handling process ๐
- Extending a database through an append operation ๐๏ธ
What POST actually does is up to the server, and it usually depends on the Request-URI. โจ The posted entity is subordinate to that URI the same way a file belongs to the directory holding it, a news article belongs to the newsgroup it's posted to, or a record belongs to a database. ๐ง
Sometimes a POST doesn't end up making a resource you can name with a URI. ๐คทโโ๏ธ In that case, 200 (OK) or 204 (No Content) is the right response status. Which one depends on whether the response includes an entity that describes the result. ๐
If a resource has been created on the origin server, the response SHOULD be 201 (Created). It should contain an entity that describes the status of the request and refers to the new resource, plus a Location header (see section 14.30). ๐ฆ Main character energy!
Responses to this method are not cachable, unless the response includes appropriate Cache-Control or Expires header fields. ๐ The only exception is that the 303 (See Other) response can send the user agent off to retrieve a cachable resource. ๐
POST requests must obey the message transmission requirements set out in section 8.2. ๐
9.6 PUT
Okay, PUT is basically "please store this enclosed entity under the Request-URI I just gave you." ๐ If the Request-URI already points at a resource, the enclosed entity SHOULD be treated as a modified version of the one living on the origin server. โจ
If the Request-URI doesn't point to an existing resource, and the requesting user agent can define that URI as a new resource, the origin server can create it. ๐ธ When a new resource is created, the origin server MUST tell the user agent with a 201 (Created) response. If an existing resource gets modified instead, either 200 (OK) or 204 (No Content) SHOULD be sent to say the request went through. ๐
If the resource can't be created or modified at that Request-URI, an appropriate error response SHOULD be given, one that reflects what went wrong. ๐ญ And the recipient of the entity MUST NOT ignore any Content-* headers (like Content-Range) that it doesn't understand or implement. In that case it MUST return a 501 (Not Implemented) response. ๐ No ignoring headers, bestie!
If the request goes through a cache and the Request-URI identifies one or more currently cached entities, those entries should be treated as stale. ๐ง Responses to this method are not cachable.
Here's the big difference between POST and PUT, and it's all about the Request-URI. ๐ In a POST, the URI identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. ๐ฅ In a PUT, the URI identifies the entity enclosed with the request. The user agent knows exactly what URI it means, so the server MUST NOT try to apply the request to some other resource. ๐ซ If the server wants the request applied to a different URI, it MUST send a 301 (Moved Permanently) response. The user agent MAY then decide for itself whether or not to redirect the request. ๐ฆ
A single resource MAY be identified by many different URIs. ๐ For example, an article might have one URI for "the current version" and a separate URI for each particular version. In that case, a PUT on a general URI may result in several other URIs being defined by the origin server. ๐ง
HTTP/1.1 doesn't define how a PUT method affects the state of an origin server. ๐คทโโ๏ธ
PUT requests must obey the message transmission requirements set out in section 8.2. ๐
9.7 DELETE
DELETE is the "please get rid of this resource" method. ๐๏ธ It requests that the origin server delete the resource identified by the Request-URI. This method MAY be overridden by human intervention (or other means) on the origin server. ๐ The client can't be guaranteed that the operation was actually carried out, even if the status code says it completed successfully. ๐ฌ Still, the server SHOULD NOT indicate success unless, at the time it responds, it intends to delete the resource or move it somewhere inaccessible. ๐
A successful response SHOULD be 200 (OK) if it includes an entity describing the status. It SHOULD be 202 (Accepted) if the action hasn't been enacted yet, or 204 (No Content) if the response is OK but has no entity. โจ
If the request goes through a cache and the Request-URI identifies one or more currently cached entities, those entries should be treated as stale. ๐ง Responses to this method are not cachable.
9.8 TRACE
TRACE is basically a remote, application-layer loop-back of the request message. ๐ช The final recipient SHOULD reflect the message it received back to the client as the entity-body of a 200 (OK) response. The final recipient is either the origin server, or the first proxy or gateway to receive a Max-Forwards value of zero (0) in the request (see section 14.31). ๐ A TRACE request MUST NOT include an entity. ๐ซ
TRACE lets the client see what's arriving at the other end of the request chain, and use that info for testing or diagnostics. ๐งช The Via header field (section 14.44) is especially iconic here, because it acts as a trace of the request chain. ๐ The Max-Forwards header field lets the client limit how long the request chain can get, which is handy for testing a chain of proxies that's forwarding messages in an infinite loop. ๐
If it succeeds, the response SHOULD contain the entire request message in the entity-body, with a Content-Type of message/http. ๐ Responses to this method MUST NOT be cached. ๐
โโ๏ธ
10 Status Code Definitions โจ
Every Status-Code gets described below, including which method(s) it can follow and any metainformation the response needs. ๐ Let's go, bestie! ๐
10.1 Informational 1xx
This class of status code is for a provisional response. It only has the Status-Line and optional headers, and it ends with an empty line. ๐ HTTP/1.0 didn't define any 1xx status codes, so servers MUST NOT send a 1xx response to an HTTP/1.0 client, except under experimental conditions. ๐งช Don't do it, babe!
10.1.1 100 Continue
The client may continue with its request. ๐ธ This interim response tells the client that the initial part of the request has been received and hasn't been rejected by the server yet. โ The client SHOULD continue by sending the rest of the request. If the request is already complete, it can ignore this response. ๐ The server MUST send a final response once the request has been completed. ๐ฏ
10.1.2 101 Switching Protocols
Here the server understands the client's request and is willing to comply with it, via the Upgrade message header field (section 14.41). ๐ฆ It's a change in the application protocol being used on this connection. The server switches to the protocols named in the response's Upgrade header field immediately after the empty line that ends the 101 response. ๐
Only switch protocols when it's actually worth it! โจ Switching to a newer version of HTTP is advantageous over older versions, and switching to a real-time, synchronous protocol may be advantageous when delivering resources that use those features. ๐
10.2 Successful 2xx
This class of status code means the client's request was successfully received, understood, and accepted. ๐ฅณ Yasss! ๐
10.2.1 200 OK
The request has succeeded. ๐ What comes back depends on the method used in the request. For example:
GET: an entity corresponding to the requested resource is sent in the response ๐ฆHEAD: the entity-header fields corresponding to the requested resource are sent in the response without any message-body ๐งพPOST: an entity describing or containing the result of the action ๐TRACE: an entity containing the request message as received by the end server ๐ช
10.2.2 201 Created
The request has been fulfilled and a new resource was created. ๐ The new resource can be referenced by the URI(s) returned in the response entity, and the most specific URL for it is given by a Location header field. ๐ The origin server MUST create the resource before it returns the 201 status code. โ ๏ธ If the action can't be carried out immediately, the server should respond with 202 (Accepted) instead. โณ
10.2.3 202 Accepted
The request has been accepted for processing, but the processing hasn't been completed yet. โฐ The request MAY or MAY NOT eventually be acted upon, since it MAY be disallowed when processing actually happens. ๐คทโโ๏ธ There's no way to re-send a status code from an asynchronous operation like this. ๐
The 202 response is intentionally non-committal. ๐ซถ Its purpose is to let a server accept a request for some other process (maybe a batch job that only runs once a day) without making the user agent's connection stay open until that process finishes. ๐ The entity returned with this response SHOULD include an indication of the request's current status, plus either a pointer to a status monitor or an estimate of when the user can expect the request to be fulfilled. ๐
10.2.4 203 Non-Authoritative Information
The metainformation in the returned entity-header isn't the definitive set from the origin server. It was gathered from a local or third-party copy instead. ๐งณ The set presented MAY be a subset or a superset of the original version. For example, including local annotation info about the resource MAY result in a superset of the metainformation the origin server knows. ๐ Using this response code isn't required, and it's only appropriate when the response would otherwise have been 200 (OK). ๐
10.2.5 204 No Content
The server has fulfilled the request, but there's no new information to send back. ๐ซฅ If the client is a user agent, it SHOULD NOT change its document view from the one that caused the request to be sent. ๐ช This response is mainly meant to let input for actions take place without changing the user agent's active document view. โจ The response MAY include new metainformation in the form of entity-headers, which SHOULD apply to the document currently in the user agent's active view. ๐
The 204 response MUST NOT include a message-body, so it always ends at the first empty line after the header fields. ๐ โโ๏ธ๐
10.2.6 205 Reset Content
Okay bestie, so the server has fulfilled the request and the user agent SHOULD reset the document view that sent the request ๐งนโจ This response is mainly there so you can type in some input, and then the form gets cleared so you can easily start another input action ๐ The response MUST NOT include an entity ๐ โโ๏ธ
10.2.7 206 Partial Content
Okay this one is giving partial vibes ๐ฆ The server has fulfilled the partial GET request for the resource. The request must have included a Range header field (section 14.36) indicating the desired range ๐ The response MUST include either a Content-Range header field (section 14.17) indicating the range included with this response, or a multipart/byteranges Content-Type including Content-Range fields for each part ๐ If multipart/byteranges is not used, the Content-Length header field in the response MUST match the actual number of OCTETs transmitted in the message-body ๐ข
A cache that does not support the Range and Content-Range headers MUST NOT cache 206 (Partial) responses ๐ No cap, that one is a hard rule ๐
10.3 Redirection 3xx
Redirection is the class where the user agent has to go do more stuff to finish the request ๐งญ The action required MAY be carried out by the user agent without interaction with the user if and only if the method used in the second request is GET or HEAD ๐ธ A user agent SHOULD NOT automatically redirect a request more than 5 times, since such redirections usually indicate an infinite loop ๐๐ญ
10.3.1 300 Multiple Choices
The requested resource matches any one of a set of representations, each with its own specific location ๐ท Agent-driven negotiation information (section 12) is provided so the user (or user agent) can pick a preferred representation and redirect the request to that location ๐
Unless it was a HEAD request, the response SHOULD include an entity containing a list of resource characteristics and locations the user or user agent can choose from, picking the one that's most appropriate ๐ The entity format is specified by the media type in the Content-Type header field ๐ Depending on the format and the user agent's capabilities, the selection may be done automatically ๐ค However, this specification does not define any standard for that automatic selection ๐ โโ๏ธ
If the server has a preferred choice of representation, it SHOULD include the specific URL for that representation in the Location field, and user agents MAY use the Location field value for automatic redirection ๐ง This response is cachable unless indicated otherwise ๐
10.3.2 301 Moved Permanently
The requested resource has a new permanent URI now ๐ โจ Future references SHOULD use one of the returned URIs ๐ Clients with link editing capabilities SHOULD automatically re-link references to the Request-URI to one or more of the new references the server returns, where possible ๐ช This response is cachable unless indicated otherwise ๐พ
If the new URI is a location, its URL SHOULD be given by the Location field in the response ๐ Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s) ๐
If a 301 status code comes back for a request that isn't GET or HEAD, the user agent MUST NOT automatically redirect the request unless the user confirms it ๐ That's because it might change the conditions under which the request was issued ๐ฌ
Note: When automatically redirecting a POST request after receiving a 301 status code, some existing HTTP/1.0 user agents will erroneously change it into a GET request. ๐ซฃ
10.3.3 302 Moved Temporarily
The requested resource is temporarily living under a different URI ๐ค๏ธ Since the redirection may change on occasion, the client SHOULD keep using the Request-URI for future requests ๐ This response is only cachable if a Cache-Control or Expires header field says so ๐
If the new URI is a location, its URL SHOULD be given by the Location field in the response ๐ Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s) ๐
If a 302 status code comes back for a request that isn't GET or HEAD, the user agent MUST NOT automatically redirect the request unless the user confirms it ๐ That's because it might change the conditions under which the request was issued ๐ฌ
Note: When automatically redirecting a POST request after receiving a 302 status code, some existing HTTP/1.0 user agents will erroneously change it into a GET request. ๐ซฃ
10.3.4 303 See Other
The response to the request can be found under a different URI and SHOULD be retrieved using a GET method on that resource ๐ This one mostly exists so a POST-activated script can send the user agent over to a selected resource ๐ฏ The new URI is not a substitute reference for the originally requested resource ๐ โโ๏ธ The 303 response is not cachable, but the response to the second (redirected) request MAY be cachable ๐
If the new URI is a location, its URL SHOULD be given by the Location field in the response ๐ Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s) ๐
10.3.5 304 Not Modified
If the client sent a conditional GET request and access is allowed, but the document hasn't changed, the server SHOULD respond with this status code ๐ฅฑ The response MUST NOT contain a message-body ๐ซ
The response MUST include the following header fields:
- Date
- ETag and/or Content-Location, if the header would have been sent in a 200 response to the same request
- Expires, Cache-Control, and/or Vary, if the field-value might differ from that sent in any previous response for the same variant
If the conditional GET used a strong cache validator (see section 13.3.3), the response SHOULD NOT include other entity-headers ๐ช Otherwise (the conditional GET used a weak validator), the response MUST NOT include other entity-headers, which prevents inconsistencies between cached entity-bodies and updated headers ๐งฉ
If a 304 response shows up for an entity that isn't currently cached, the cache MUST disregard the response and repeat the request without the conditional ๐ If a cache uses a received 304 response to update a cache entry, the cache MUST update the entry to reflect any new field values given in the response ๐
The 304 response MUST NOT include a message-body, so it always ends at the first empty line after the header fields ๐
10.3.6 305 Use Proxy
The requested resource MUST be accessed through the proxy given by the Location field ๐ช The Location field gives the URL of the proxy ๐บ๏ธ The recipient is expected to repeat the request via the proxy ๐
10.4 Client Error 4xx
The 4xx class is for when the client seems to have messed up ๐ Except when responding to a HEAD request, the server SHOULD include an entity explaining the error, and whether it's a temporary or permanent condition ๐ These status codes apply to any request method ๐ User agents SHOULD display any included entity to the user ๐
Note: If the client is sending data, a server implementation using TCP should be careful to ensure that the client acknowledges receipt of the packet(s) containing the response, before the server closes the input connection. If the client continues sending data to the server after the close, the server's TCP stack will send a reset packet to the client, which may erase the client's unacknowledged input buffers before they can be read and interpreted by the HTTP application. ๐ฑ
10.4.1 400 Bad Request
The server couldn't understand the request because the syntax is malformed ๐คทโโ๏ธ The client SHOULD NOT repeat the request without modifications ๐ซ
10.4.2 401 Unauthorized
The request needs user authentication ๐ The response MUST include a WWW-Authenticate header field (section 14.46) containing a challenge that applies to the requested resource ๐ซ The client MAY repeat the request with a suitable Authorization header field (section 14.8) ๐ If the request already included Authorization credentials, the 401 response means authorization was refused for those credentials ๐ โโ๏ธ If the 401 response has the same challenge as the prior response, and the user agent already tried authentication at least once, then the user SHOULD be shown the entity given in the response, since it MAY include useful diagnostic info ๐ฉบ HTTP access authentication is explained in section 11 ๐
10.4.3 402 Payment Required
This code is reserved for future use ๐ฎ
10.4.4 403 Forbidden
The server understood the request but is refusing to fulfill it ๐ Authorization won't help, and the request SHOULD NOT be repeated ๐ โโ๏ธ If the request method was not HEAD and the server wants to make public why the request wasn't fulfilled, it SHOULD describe the reason for the refusal in the entity ๐ฃ This status code is commonly used when the server doesn't want to reveal exactly why the request was refused, or when no other response fits ๐ค
10.4.5 404 Not Found
The server hasn't found anything matching the Request-URI ๐ No indication is given of whether the condition is temporary or permanent ๐ค
If the server doesn't want to share this info with the client, the status code 403 (Forbidden) can be used instead ๐ The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address ๐ชฆ
10.4.6 405 Method Not Allowed
The method in the Request-Line isn't allowed for the resource identified by the Request-URI ๐ท The response MUST include an Allow header containing a list of valid methods for the requested resource ๐
10.4.7 406 Not Acceptable
The resource identified by the request can only generate response entities with content characteristics that aren't acceptable according to the accept headers sent in the request ๐ฌ
Unless it was a HEAD request, the response SHOULD include an entity containing a list of available entity characteristics and locations the user or user agent can choose from, picking the most appropriate one ๐ The entity format is specified by the media type in the Content-Type header field ๐ Depending on the format and the user agent's capabilities, the selection may be done automatically ๐ค However, this specification does not define any standard for that automatic selection ๐ โโ๏ธ
Note: HTTP/1.1 servers are allowed to return responses that aren't acceptable according to the accept headers sent in the request. In some cases, this may even be preferable to sending a 406 response. User agents are encouraged to inspect the headers of an incoming response to determine if it is acceptable. If the response could be unacceptable, a user agent SHOULD temporarily stop receipt of more data and query the user for a decision on further actions. ๐ง๐
10.4.8 407 Proxy Authentication Required ๐
okay bestie, 407 is basically the 401's cousin, but this one is for the proxy ๐ง. The client MUST first authenticate itself with the proxy ๐
, so no sneaking past the bouncer. The proxy MUST return a Proxy-Authenticate header field (section 14.33) with a challenge that applies to the proxy for the requested resource ๐. Then the client MAY repeat the request with a suitable Proxy-Authorization header field (section 14.34). HTTP access authentication is explained in section 11 โจ, so scroll down, it's giving.
10.4.9 408 Request Timeout โฐ
the client took too long to send its request, and the server got tired of waiting ๐. The client MAY repeat the request without modifications at any later time ๐ธ.
10.4.10 409 Conflict ๐ฌ
the request couldn't be completed because it clashes with the resource's current state. This code is only allowed when the user might actually be able to sort out the conflict and resubmit the request. The response body SHOULD include enough info for the user to recognize where the conflict came from ๐. Ideally the response would have enough detail for the user or user agent to fix the problem, but that may not be possible, and it's not required ๐ซถ.
Conflicts usually pop up with PUT requests ๐. If versioning is in play and the entity being PUT has changes that clash with an earlier (third-party) request, the server MAY use the 409 to say it can't finish the request. In that case the response entity SHOULD contain a list of the differences between the two versions, in a format defined by the response Content-Type ๐.
10.4.11 410 Gone ๐
the resource isn't available on the server anymore, and no forwarding address is known. This condition SHOULD be considered permanent. Clients with link editing capabilities SHOULD delete references to the Request-URI after user approval. If the server doesn't know, or has no way to figure out, whether the condition is permanent, 404 (Not Found) SHOULD be used instead. This response is cachable unless indicated otherwise ๐๏ธ.
The 410 is mainly there to help with web maintenance. It tells the recipient that the resource is gone on purpose and that the server owners want remote links to it removed ๐งน. This is super common for limited-time promos and for stuff belonging to people who've left the team at the server's site. You don't have to mark every permanently unavailable resource as "gone", and you don't have to keep the mark forever. That's up to the server owner ๐.
10.4.12 411 Length Required ๐
the server won't accept the request without a defined Content-Length. The client MAY repeat the request if it adds a valid Content-Length header field containing the length of the message-body in the request message ๐.
10.4.13 412 Precondition Failed ๐
the precondition in one or more of the request-header fields evaluated to false when the server tested it. This lets the client put preconditions on the current resource metainformation (header field data), so the requested method can't accidentally hit a resource other than the one intended ๐ฏ.
10.4.14 413 Request Entity Too Large ๐ฆ
the server is refusing to process the request because the request entity is bigger than the server is willing or able to handle. It may close the connection to stop the client from continuing ๐ช.
If the condition is temporary, the server SHOULD include a Retry-After header field to say it's temporary and after what time the client can try again โณ.
10.4.15 414 Request-URI Too Long ๐
the server is refusing to service the request because the Request-URI is longer than the server is willing to interpret. This is a rare one, and it usually happens when a client wrongly turned a POST into a GET with long query info, when the client fell into a URL "black hole" of redirection (e.g., a redirected URL prefix that points to a suffix of itself), or when the server is under attack from a client trying to exploit security holes in servers that use fixed-length buffers for reading or manipulating the Request-URI ๐จ. Scary stuff, bestie.
10.4.16 415 Unsupported Media Type ๐๏ธ
the server is refusing to service the request because the request's entity is in a format the requested resource doesn't support for the requested method ๐.
10.5 Server Error 5xx ๐ญ
Status codes starting with the digit "5" mean the server knows it messed up, or it can't perform the request at all. Except when responding to a HEAD request, the server SHOULD include an entity explaining the error and whether it's a temporary or permanent condition. User agents SHOULD display any included entity to the user. These codes apply to any request method ๐.
10.5.1 500 Internal Server Error ๐ฅ
the server ran into an unexpected condition that stopped it from fulfilling the request.
10.5.2 501 Not Implemented ๐คท
the server doesn't support the functionality the request needs. This is the right response when the server doesn't recognize the request method and can't support it for any resource.
10.5.3 502 Bad Gateway ๐
while acting as a gateway or proxy, the server got an invalid response from the upstream server it contacted while trying to fulfill the request.
10.5.4 503 Service Unavailable ๐ ๏ธ
the server can't handle the request right now because it's temporarily overloaded or under maintenance. That means the situation is temporary and should get better after some delay. If the delay is known, it may be indicated in a Retry-After header. If no Retry-After is given, the client SHOULD handle the response the same way it would handle a 500 response.
Note: Having the 503 status code doesn't mean a server must use it when it gets overloaded. Some servers may just prefer to refuse the connection outright ๐ โโ๏ธ.
10.5.5 504 Gateway Timeout โณ
while acting as a gateway or proxy, the server didn't get a timely response from the upstream server it contacted to complete the request.
10.5.6 505 HTTP Version Not Supported ๐
the server doesn't support, or won't support, the HTTP protocol version used in the request message. It's saying it's unable or unwilling to complete the request using the same major version as the client, as described in section 3.1, and is sending this error message instead. The response SHOULD contain an entity explaining why that version isn't supported and which other protocols that server does support.
11 Access Authentication ๐
HTTP has a simple challenge-response authentication mechanism which MAY be used by a server to challenge a client request, and by a client to provide authentication information. It uses an extensible, case-insensitive token to name the authentication scheme, followed by a comma-separated list of attribute-value pairs that carry the parameters needed to achieve authentication via that scheme ๐.
auth-scheme = token
auth-param = token "=" quoted-string
The 401 (Unauthorized) response is used by an origin server to challenge the authorization of a user agent. This response MUST include a WWW-Authenticate header field containing at least one challenge applicable to the requested resource ๐ชช.
challenge = auth-scheme 1*SP realm *( "," auth-param )
realm = "realm" "=" realm-value
realm-value = quoted-string
The realm attribute (case-insensitive) is required for all authentication schemes that issue a challenge. The realm value (case-sensitive), combined with the canonical root URL (see section 5.1.2) of the server being accessed, defines the protection space ๐ฐ. Realms let the protected resources on a server be split into a set of protection spaces, each with its own authentication scheme and/or authorization database. The realm value is a string, usually assigned by the origin server, and it may have extra semantics specific to the authentication scheme ๐.
A user agent that wants to authenticate itself with a server (usually, but not necessarily, after getting a 401 or 411 response) MAY do so by including an Authorization header field with the request. The Authorization field value holds credentials containing the user agent's authentication info for the realm of the requested resource โจ.
credentials = basic-credentials
| auth-scheme #auth-param
The domain over which a user agent can automatically apply credentials is set by the protection space. If a prior request was authorized, the same credentials MAY be reused for all other requests within that protection space, for a period determined by the authentication scheme, its parameters, and/or user preference. Unless the authentication scheme defines otherwise, a single protection space can't extend outside the scope of its server ๐ง.
If the server doesn't want to accept the credentials sent with a request, it SHOULD return a 401 (Unauthorized) response. The response MUST include a WWW-Authenticate header field containing the (possibly new) challenge applicable to the requested resource, along with an entity explaining the refusal ๐
โโ๏ธ.
HTTP doesn't limit apps to this simple challenge-response mechanism for access authentication. Additional mechanisms MAY be used, such as encryption at the transport level or via message encapsulation, and with additional header fields specifying authentication information. However, these additional mechanisms are not defined by this specification ๐.
Proxies MUST be completely transparent regarding user agent authentication. That is, they MUST forward the WWW-Authenticate and Authorization headers untouched, and follow the rules found in section 14.8 ๐ซถ.
HTTP/1.1 lets a client pass authentication information to and from a proxy via the Proxy-Authenticate and Proxy-Authorization headers ๐.
11.1. Basic Authentication Scheme ๐
okay so the "basic" scheme is built on a super simple idea: the user agent has to prove who it is with a user-ID and a password for each realm ๐ The realm is an opaque string, which means you can only check whether two realms are equal. No peeking inside ๐ซถ The server only services the request if it can validate the user-ID and password for the protection space of the Request-URI. And there are no optional authentication parameters, so no extra knobs here ๐
When an unauthorized request comes in for a URI inside the protection space, the server MAY respond with a challenge that looks like this:
WWW-Authenticate: Basic realm="WallyWorld"
where "WallyWorld" is the string the server assigned to identify the protection space of the Request-URI ๐ธ
To get authorization, the client sends the userid and password, separated by a single colon (":") character, inside a base64 encoded string in the credentials ๐ง
basic-credentials = "Basic" SP basic-cookie
basic-cookie = <base64 [7] encoding of user-pass,
except not limited to 76 char/line>
user-pass = userid ":" password
userid = *<TEXT excluding ":">
password = *TEXT
Userids might be case sensitive ๐
If the user agent wishes to send the userid "Aladdin" and password "open sesame", it would use the following header field:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
See section 15 for security considerations associated with Basic authentication. Section 15 is where the security considerations for Basic auth live, and they are seriously important, bestie ๐
11.2. Digest Authentication Scheme ๐
A digest authentication for HTTP is specified in RFC 2069 [32].
12. Content Negotiation โจ
okay so most HTTP responses include an entity with information meant to be read by a human user ๐ Naturally, you want to give the user the "best available" entity for their request. The tea is that servers and caches can't always tell what "best" means, because not every user has the same preferences, and not every user agent can render every entity type ๐ญ That's why HTTP has several mechanisms for "content negotiation": the process of picking the best representation for a given response when there are multiple representations available ๐ฆ
Note: This is not called "format negotiation" because the alternate representations may be of the same media type, but use different capabilities of that type, be in different languages, etc.
Any response containing an entity-body MAY be subject to negotiation, including error responses ๐
There are two kinds of content negotiation possible in HTTP: server-driven and agent-driven negotiation. They're orthogonal, so you can use them separately or together โจ One combo, called transparent negotiation, happens when a cache uses the agent-driven negotiation information from the origin server to provide server-driven negotiation for later requests ๐ฅ
12.1. Server-driven Negotiation ๐
If the selection of the best representation for a response is made by an algorithm at the server, it's called server-driven negotiation. Selection is based on the available representations of the response (the dimensions over which it can vary, e.g. language, content-coding, etc.) and on the contents of particular header fields in the request message, or on other information about the request (such as the network address of the client) ๐
Server-driven negotiation is a win when the algorithm for choosing among the representations is hard to describe to the user agent, or when the server wants to send its "best guess" along with the first response. That way it can skip the round-trip delay of a follow-up request, if the "best guess" is good enough for the user. To improve the server's guess, the user agent MAY include request header fields (Accept, Accept-Language, Accept-Encoding, etc.) that describe its preferences for such a response ๐
Server-driven negotiation has disadvantages, though ๐
- It is impossible for the server to accurately determine what might be "best" for any given user, since that would require complete knowledge of both the capabilities of the user agent and the intended use for the response (e.g., does the user want to view it on screen or print it on paper?).
- Having the user agent describe its capabilities in every request can be both very inefficient (given that only a small percentage of responses have multiple representations) and a potential violation of the user's privacy.
- It complicates the implementation of an origin server and the algorithms for generating responses to a request.
- It may limit a public cache's ability to use the same response for multiple user's requests.
HTTP/1.1 includes the following request-header fields for enabling server-driven negotiation through description of user agent capabilities and user preferences: Accept (section 14.1), Accept-Charset (section 14.2), Accept-Encoding (section 14.3), Accept-Language (section 14.4), and User-Agent (section 14.42). However, an origin server is not limited to these dimensions and MAY vary the response based on any aspect of the request, including information outside the request-header fields or within extension header fields not defined by this specification ๐ง
HTTP/1.1 origin servers MUST include an appropriate Vary header field (section 14.43) in any cachable response based on server-driven negotiation. The Vary header field describes the dimensions over which the response might vary (i.e. the dimensions over which the origin server picks its "best guess" response from multiple representations) ๐
HTTP/1.1 public caches MUST recognize the Vary header field when it is included in a response, and obey the requirements described in section 13.6, which covers the interactions between caching and content negotiation ๐ซถ
12.2. Agent-driven Negotiation ๐ฆ
With agent-driven negotiation, the user agent does the selecting of the best representation after it gets an initial response from the origin server. Selection is based on a list of the available representations of the response, included within the header fields (this specification reserves the field-name Alternates, as described in appendix 19.6.2.1) or the entity-body of the initial response, with each representation identified by its own URI. Selection may be performed automatically (if the user agent is capable of doing so) or manually, with the user picking from a generated (possibly hypertext) menu ๐
Agent-driven negotiation is a great fit when the response would vary over commonly-used dimensions (such as type, language, or encoding), when the origin server can't figure out a user agent's capabilities from the request, and generally when public caches are used to spread out server load and reduce network usage โจ
Agent-driven negotiation has one main downside: it needs a second request to get the best alternate representation. That second request is only efficient when caching is used. Also, this specification doesn't define any mechanism for automatic selection, though it also doesn't prevent one from being developed as an extension and used within HTTP/1.1 ๐ธ
HTTP/1.1 defines the 300 (Multiple Choices) and 406 (Not Acceptable) status codes for enabling agent-driven negotiation when the server is unwilling or unable to provide a varying response using server-driven negotiation ๐
12.3. Transparent Negotiation ๐ง
Transparent negotiation is a combo of server-driven and agent-driven negotiation. When a cache gets a form of the list of available representations (like in agent-driven negotiation) and the cache completely understands the dimensions of variance, the cache can do server-driven negotiation on behalf of the origin server for later requests on that resource ๐ฅ
Transparent negotiation is a big win because it spreads out the negotiation work that would otherwise fall on the origin server, and it removes the second-request delay of agent-driven negotiation when the cache correctly guesses the right response ๐
This specification doesn't define any mechanism for transparent negotiation, though it also doesn't prevent one from being developed as an extension and used within HTTP/1.1. An HTTP/1.1 cache performing transparent negotiation MUST include a Vary header field in the response (defining the dimensions of its variance) if it is cachable, to make sure it interoperates correctly with all HTTP/1.1 clients. The agent-driven negotiation information supplied by the origin server SHOULD be included with the transparently negotiated response ๐
13. Caching in HTTP โจ
okay bestie, HTTP is typically used for distributed information systems ๐, and performance can be seriously improved with response caches ๐. HTTP/1.1 has a bunch of built-in elements to make caching work as well as possible ๐ . They're inextricable from the rest of the protocol (they're stuck together ๐ซถ) and they interact with each other, so it's useful to explain the basic caching design separately from the detailed stuff on methods, headers, response codes, etc.
Caching would be useless if it didn't actually boost performance ๐ญ. The goal in HTTP/1.1 is to skip sending requests in lots of cases, and to skip sending full responses in lots of other cases. The first one cuts down on network round-trips for many operations, and we use an "expiration" mechanism for it (see section 13.2) ๐ฆ. The second one saves network bandwidth, and we use a "validation" mechanism for that (see section 13.3) ๐.
Performance, availability, and disconnected operation all need us to be able to relax semantic transparency a little ๐ธ. HTTP/1.1 lets origin servers, caches, and clients explicitly reduce transparency when they have to. BUT non-transparent operation can confuse non-expert users, and it can clash with certain server applications (like the ones for ordering merchandise ๐๏ธ), so the protocol requires that transparency be relaxed:
- only by an explicit protocol-level request when relaxed by client or origin server
- only with an explicit warning to the end user when relaxed by cache or client
So HTTP/1.1 gives us these important elements:
- Protocol features that provide full semantic transparency when all parties need it.
- Protocol features that let an origin server or user agent explicitly request and control non-transparent operation.
- Protocol features that let a cache attach warnings to responses that don't preserve the requested approximation of semantic transparency.
The big principle here is that clients need to be able to detect any potential relaxation of semantic transparency ๐.
Note: The server, cache, or client implementer may run into design decisions that this specification doesn't explicitly cover ๐ค. If a decision might affect semantic transparency, the implementer ought to err on the side of keeping transparency, unless a careful and complete analysis shows significant benefits in breaking it.
13.1.1 Cache Correctness
A correct cache MUST respond to a request with the most up-to-date response it holds that is appropriate to the request (see sections 13.2.5, 13.2.6, and 13.12) and that meets one of the following conditions ๐:
- It has been checked for equivalence with what the origin server would have returned, by revalidating the response with the origin server (section 13.3);
- It is "fresh enough" (see section 13.2). In the default case, this means it meets the least restrictive freshness requirement of the client, server, and cache (see section 14.9). If the origin server specifies so, it's the origin server's freshness requirement alone ๐;
- It includes a warning if the freshness demand of the client or the origin server is violated (see section 13.1.5 and 14.45);
- It is an appropriate 304 (Not Modified), 305 (Proxy Redirect), or error (4xx or 5xx) response message.
If the cache can't communicate with the origin server, then a correct cache SHOULD respond as above, as long as the response can be correctly served from the cache. If it can't do that, it MUST return an error or a warning saying there was a communication failure ๐.
If a cache gets a response (either a whole response or a 304 (Not Modified) response) that it would normally forward to the requesting client, and that response is no longer fresh, the cache SHOULD forward it anyway without adding a new Warning (but it also shouldn't remove any Warning headers that are already there) ๐ซ . A cache SHOULD NOT try to revalidate a response just because it went stale in transit, because that could lead to an infinite loop ๐. A user agent that gets a stale response without a Warning MAY show a warning indication to the user โจ.
13.1.2 Warnings
Whenever a cache returns a response that is neither first-hand nor "fresh enough" (in the sense of condition 2 in section 13.1.1), it must attach a warning to that effect, using a Warning response-header. This warning lets clients take appropriate action ๐จ.
Warnings can be used for other purposes too, both cache-related and not. Using a warning instead of an error status code is what tells these responses apart from true failures ๐ฆ.
Warnings are always cacheable, because they never weaken the transparency of a response. That means warnings can be passed to HTTP/1.0 caches safely, and those caches will just pass the warning along as an entity-header in the response ๐ .
Warnings are assigned numbers between 0 and 99. This specification defines the code numbers and meanings of each currently assigned warning, so a client or cache can take automated action in some (but not all) cases ๐ค.
Warnings also carry a warning text. The text can be in any appropriate natural language (maybe based on the client's Accept headers), and it can include an optional indication of what character set is used ๐.
Multiple warnings can be attached to a response, either by the origin server or by a cache, including several with the same code number. For example, a server might send the same warning with texts in both English and Basque ๐ธ.
When there are multiple warnings on a response, showing all of them to the user might not be practical or reasonable ๐ฉ. This version of HTTP doesn't set strict priority rules for deciding which warnings to display and in what order, but it does suggest some heuristics ๐ง.
The Warning header and the currently defined warnings are described in section 14.45.
13.1.3 Cache-control Mechanisms
The basic cache mechanisms in HTTP/1.1 (server-specified expiration times and validators) act as implicit directives to caches. Sometimes a server or client needs to give the HTTP caches explicit directives, and that's what the Cache-Control header is for ๐.
The Cache-Control header lets a client or server send a variety of directives in either requests or responses. These directives typically override the default caching algorithms. As a general rule, if there's any apparent conflict between header values, the most restrictive interpretation should be applied (meaning the one most likely to preserve semantic transparency) ๐. BUT in some cases, Cache-Control directives are explicitly specified as weakening the approximation of semantic transparency (for example, "max-stale" or "public") ๐.
The Cache-Control directives are described in detail in section 14.9 ๐.
13.1.4 Explicit User Agent Warnings
Lots of user agents let users override the basic caching mechanisms. For example, a user agent might let someone say that cached entities (even explicitly stale ones) are never validated. Or a user agent might habitually add Cache-Control: max-stale=3600 to every request ๐. The user should have to explicitly ask for either non-transparent behavior or behavior that makes caching abnormally ineffective ๐ซถ.
If the user has overridden the basic caching mechanisms, the user agent should explicitly tell the user whenever this results in showing information that might not meet the server's transparency requirements (especially if the displayed entity is known to be stale) ๐. Since the protocol normally lets the user agent figure out whether responses are stale, this indication only needs to appear when that actually happens โจ. It doesn't have to be a dialog box. It could be an icon (like a picture of a rotting fish ๐) or some other visual indicator ๐.
If the user has overridden the caching mechanisms in a way that would abnormally reduce the effectiveness of caches, the user agent should keep showing an indication (like a picture of currency in flames ๐ฅ๐ธ) the whole time, so the user doesn't accidentally eat up excess resources or suffer from excessive latency ๐ญ.
13.1.5 Exceptions to the Rules and Warnings
Sometimes the operator of a cache might choose to configure it to return stale responses even when clients didn't ask for them ๐คจ. This shouldn't be decided lightly, but it may be necessary for reasons of availability or performance, especially when the cache is poorly connected to the origin server ๐ง๏ธ. Whenever a cache returns a stale response, it MUST mark it as such (using a Warning header). That lets the client software alert the user that there might be a potential problem ๐ฉ.
It also lets the user agent take steps to get a first-hand or fresh response. For this reason, a cache SHOULD NOT return a stale response if the client explicitly asks for a first-hand or fresh one, unless it's impossible to comply for technical or policy reasons ๐ โโ๏ธ.
13.1.6 Client-controlled Behavior
The origin server is the primary source of expiration information (and intermediate caches are a secondary source, through their contribution to the age of a response) ๐ง. But sometimes the client needs to control whether a cache returns a cached response without validating it ๐. Clients do this using several directives of the Cache-Control header ๐ .
A client's request can specify the maximum age it's willing to accept for an unvalidated response. Specifying a value of zero forces the cache(s) to revalidate all responses ๐. A client can also specify the minimum time remaining before a response expires. Both of these options add constraints on cache behavior, so they can't further relax the cache's approximation of semantic transparency ๐.
A client can also say it will accept stale responses, up to some maximum amount of staleness. This loosens the constraints on caches, so it may break the origin server's specified constraints on semantic transparency, but it may be needed to support disconnected operation or high availability when connectivity is poor ๐ถ๐.
13.2. Expiration Model ๐ฐ๏ธ
13.2.1 Server-Specified Expiration ๐ธ
okay bestie, caches are at their absolute best when they never have to bug the origin server at all ๐ The main way to skip it is for the origin to hand over an explicit expiration time in the future, which basically says "yep, this response is good to reuse until then." So a cache can serve a fresh response without even asking the server first โจ
Servers pick future expiration times because they believe the entity won't change in a semantically significant way before that time hits ๐ฆ When the server picks its times carefully, this keeps semantic transparency intact, and it's honestly so iconic.
The expiration mechanism only applies to responses taken from a cache. It does NOT apply to first-hand responses that get forwarded straight to the client who asked ๐
If an origin server wants to force a semantically transparent cache to validate every request, it can give an explicit expiration time in the past. That makes the response always stale, so the cache SHOULD validate it before using it for later requests. For a stricter way to force revalidation, check section 14.9.4 ๐
If an origin server wants to force any HTTP/1.1 cache, no matter how it's configured, to validate every request, it should use the "must-revalidate" Cache-Control directive (see section 14.9). Main character energy ๐
Servers specify explicit expiration times using either the Expires header, or the max-age directive of the Cache-Control header.
An expiration time can't be used to make a user agent refresh its display or reload a resource. Its semantics only apply to caching mechanisms, and those only need to check a resource's expiration status when a new request for that resource is initiated. For the difference between caches and history mechanisms, see section 13.13 ๐
13.2.2 Heuristic Expiration ๐ง
Since origin servers don't always give explicit expiration times, HTTP caches usually assign heuristic expiration times. They use algorithms that look at other header values (such as the Last-Modified time) to estimate a plausible expiration time ๐ The HTTP/1.1 spec doesn't provide specific algorithms, but it does impose worst-case constraints on their results.
Heuristic expiration times can compromise semantic transparency, so they should be used cautiously, and we really encourage origin servers to provide explicit expiration times as much as possible ๐ซถ
13.2.3 Age Calculations ๐ฆ
To know if a cached entry is fresh, a cache needs to know whether its age exceeds its freshness lifetime. We'll talk about calculating the lifetime in section 13.2.4. This section is about working out the age of a response or cache entry ๐
In this discussion, "now" means "the current value of the clock at the host performing the calculation." Hosts that use HTTP, especially origin servers and caches, should use NTP [28] or some similar protocol to sync their clocks to a globally accurate time standard โฐ
HTTP/1.1 requires origin servers to send a Date header with every response, giving the time the response was generated. We use "date_value" to mean the value of the Date header, in a form that's good for arithmetic.
HTTP/1.1 uses the Age response-header to help pass age info between caches. The Age value is the sender's estimate of the amount of time since the response was generated at the origin server. For a cached response that's been revalidated with the origin server, the Age value is based on the time of revalidation, not the original response ๐ฅ
Basically, the Age value is the sum of the time the response has been sitting in each cache along the path from the origin server, plus the time it spent in transit on network paths ๐
We use "age_value" to mean the value of the Age header, in a form that's good for arithmetic.
A response's age can be calculated in two totally independent ways:
- now minus date_value, if the local clock is reasonably well synchronized to the origin server's clock. If the result is negative, the result is replaced by zero.
- age_value, if all of the caches along the response path implement HTTP/1.1.
Since we have two independent ways to compute a response's age when it's received, we can combine them like this:
corrected_received_age = max(now - date_value, age_value)
and as long as we have either nearly synchronized clocks or all-HTTP/1.1 paths, one gets a reliable (conservative) result ๐ฏ
Note that this correction is applied at each HTTP/1.1 cache along the path, so if there's an HTTP/1.0 cache in the path, the correct received age is still computed as long as the receiving cache's clock is nearly in sync. We don't need end-to-end clock synchronization (although it's good to have), and there's no explicit clock synchronization step ๐ง
Because of network-imposed delays, some significant interval can pass between the moment a server generates a response and the moment it's received at the next outbound cache or client. If uncorrected, this delay could result in improperly low ages ๐
The request that resulted in the returned Age value must have been initiated before that Age value was generated. So we can correct for network delays by recording the time the request was initiated. Then, when an Age value is received, it MUST be interpreted relative to the time the request was initiated, not the time the response was received. This algorithm results in conservative behavior no matter how much delay is experienced. So, we compute:
corrected_initial_age = corrected_received_age
+ (now - request_time)
where "request_time" is the time (according to the local clock) when the request that elicited this response was sent ๐
Summary of the age calculation algorithm, when a cache receives a response:
/*
* age_value
* is the value of Age: header received by the cache with
* this response.
* date_value
* is the value of the origin server's Date: header
* request_time
* is the (local) time when the cache made the request
* that resulted in this cached response
* response_time
* is the (local) time when the cache received the
* response
* now
* is the current (local) time
*/
apparent_age = max(0, response_time - date_value);
corrected_received_age = max(apparent_age, age_value);
response_delay = response_time - request_time;
corrected_initial_age = corrected_received_age + response_delay;
resident_time = now - response_time;
current_age = corrected_initial_age + resident_time;
When a cache sends a response, it must add to the corrected_initial_age the amount of time the response was resident locally. It must then transmit this total age, using the Age header, to the next recipient cache ๐ฆ
Note that a client cannot reliably tell that a response is first-hand. But the presence of an Age header indicates that a response is definitely NOT first-hand. Also, if the Date in a response is earlier than the client's local request time, the response is probably not first-hand (in the absence of serious clock skew) ๐ต๏ธโโ๏ธ
13.2.4 Expiration Calculations ๐
To decide whether a response is fresh or stale, we need to compare its freshness lifetime to its age. The age is calculated as described in section 13.2.3. This section explains how to calculate the freshness lifetime and how to tell if a response has expired. The values below can be represented in any form that's good for arithmetic ๐งฎ
"expires_value" is the value of the Expires header. "max_age_value" is the number of seconds carried by the max-age directive of the Cache-Control header in a response (see section 14.10.
The max-age directive takes priority over Expires. So if max-age is present in a response, the calculation is simply:
freshness_lifetime = max_age_value
Otherwise, if Expires is present in the response, the calculation is:
freshness_lifetime = expires_value - date_value
Neither of these calculations is vulnerable to clock skew, since all of the information comes from the origin server ๐ธ
If neither Expires nor Cache-Control: max-age appears in the response, and the response doesn't include other restrictions on caching, the cache MAY compute a freshness lifetime using a heuristic. If the value is greater than 24 hours, the cache must attach Warning 13 to any response whose age is more than 24 hours, if such a warning hasn't already been added โ ๏ธ
Also, if the response does have a Last-Modified time, the heuristic expiration value SHOULD be no more than some fraction of the interval since that time. A typical setting for this fraction might be 10% ๐
The calculation to determine if a response has expired is pretty simple:
response_is_fresh = (freshness_lifetime > current_age)
13.2.5 Disambiguating Expiration Values ๐
Because expiration values are assigned optimistically, it's possible for two caches to contain fresh values for the same resource that are different ๐
If a client performing a retrieval receives a non-first-hand response for a request that was already fresh in its own cache, and the Date header in its existing cache entry is newer than the Date on the new response, then the client MAY ignore the response. If so, it MAY retry the request with a "Cache-Control: max-age=0" directive (see section 14.9), to force a check with the origin server ๐
If a cache has two fresh responses for the same representation with different validators, it MUST use the one with the more recent Date header. This can happen because the cache is pooling responses from other caches, or because a client asked for a reload or a revalidation of an apparently fresh cache entry. Periodt ๐
13.2.6 Disambiguating Multiple Responses โจ
okay so here's the tea ๐ซ a client can be getting responses through multiple paths, which means some responses go through one group of caches and others go through a totally different group. so the responses can show up in a different order than the origin server actually sent them ๐ญ the goal is for the client to use the most recently generated response, even if older ones still look fresh. main character energy only ๐
neither the entity tag nor the expiration value can set the order, bestie, because a later response can intentionally have an earlier expiration time ๐ so what's the move? the HTTP/1.1 spec requires Date headers on every response, and Date values are ordered to a granularity of one second ๐ฐ๏ธ that's the key.
when a client tries to revalidate a cache entry and the response has a Date header that appears older than the one for the existing entry, then the client SHOULD repeat the request unconditionally ๐ and include:
Cache-Control: max-age=0
this forces any intermediate caches to validate their copies directly with the origin server, or:
Cache-Control: no-cache
this forces any intermediate caches to grab a brand new copy from the origin server ๐ซถ
if the Date values are equal, the client may use either response (or may, if it's being extremely prudent, request a new response ๐ง). and servers MUST NOT depend on clients being able to pick deterministically between responses generated during the same second, if their expiration times overlap. no vibes-based decision making here, fr fr ๐
13.3 Validation Model ๐
so a cache has a stale entry and wants to serve it to a client. first it has to check in with the origin server (or maybe an intermediate cache with a fresh response) to see if the entry is still usable. this is called "validating" the cache entry ๐ฆ we don't want to pay the cost of resending the full response if the cached copy is still good, and we also don't want to eat an extra round trip if the cached copy is invalid. so HTTP/1.1 supports conditional methods ๐
the key features for conditional methods are the ones about "cache validators." when an origin server generates a full response, it attaches some kind of validator to it, and that gets stored with the cache entry. when a client (a user agent or a proxy cache) makes a conditional request for a resource it has a cache entry for, it includes the associated validator in the request ๐ง
the server then checks that validator against the current validator for the entity. if they match, it responds with a special status code (usually 304 (Not Modified)) and no entity-body ๐ธ otherwise it returns a full response, entity-body included. so we skip sending the full response when the validator matches, and we skip the extra round trip when it doesn't. iconic ๐
Note: the comparison functions used to decide if validators match are defined in section 13.3.3.
in HTTP/1.1, a conditional request looks exactly like a normal request for the same resource, except it carries a special header (which includes the validator) that quietly turns the method (usually GET) into a conditional โจ
the protocol has both positive and negative senses of cache-validating conditions. so you can ask for a method to be performed if and only if a validator matches, or if and only if no validators match ๐ซง
Note: a response that lacks a validator may still be cached, and served from cache until it expires, unless a Cache-Control directive explicitly prohibits this. however, a cache cannot do a conditional retrieval if it doesn't have a validator for the entity, which means it won't be refreshable after it expires ๐ญ
13.3.1 Last-modified Dates ๐
the Last-Modified entity-header field value is often used as a cache validator. in simple terms, a cache entry is considered valid if the entity hasn't been modified since the Last-Modified value ๐
13.3.2 Entity Tag Cache Validators ๐ท๏ธ
the ETag entity-header field value, an entity tag, gives you an "opaque" cache validator. this can allow more reliable validation when it's inconvenient to store modification dates, when the one-second resolution of HTTP date values isn't enough, or when the origin server wants to avoid certain paradoxes that can come up with modification dates ๐
entity tags are described in section 3.11. the headers used with entity tags are described in sections 14.20, 14.25, 14.26 and 14.43 ๐
13.3.3 Weak and Strong Validators ๐
since both origin servers and caches compare two validators to decide whether they represent the same or different entities, you'd normally expect that if the entity (the entity-body or any entity-headers) changes in any way, the associated validator changes too. if that's true, we call it a "strong validator" ๐ช
but sometimes a server prefers to change the validator only on semantically significant changes, not when insignificant parts of the entity change. a validator that doesn't always change when the resource changes is a "weak validator" ๐ซถ
entity tags are normally "strong validators," but the protocol gives you a way to tag an entity tag as "weak." think of a strong validator as one that changes whenever the bits of an entity change, while a weak one changes whenever the meaning of an entity changes ๐ง another way to see it: a strong validator is part of an identifier for one specific entity, while a weak validator is part of an identifier for a set of semantically equivalent entities ๐ฆ
Note: One example of a strong validator is an integer that is incremented in stable storage every time an entity is changed. An entity's modification time, if represented with one-second resolution, could be a weak validator, since it is possible that the resource may be modified twice during a single second. Support for weak validators is optional; however, weak validators allow for more efficient caching of equivalent objects. for example, a hit counter on a site is probably good enough if it's updated every few days or weeks, and any value during that period is likely "good enough" to be equivalent ๐ข A "use" of a validator is either when a client generates a request and includes the validator in a validating header field, or when a server compares two validators.
strong validators are usable in any context. weak validators are only usable in contexts that don't depend on exact equality of an entity. for example, either kind works for a conditional GET of a full entity. but only a strong validator works for a sub-range retrieval, because otherwise the client might end up with an internally inconsistent entity ๐
the only function HTTP/1.1 defines on validators is comparison. there are two validator comparison functions, depending on whether the comparison context allows weak validators or not:
- The strong comparison function: in order to be considered equal, both validators must be identical in every way, and neither may be weak.
- The weak comparison function: in order to be considered equal, both validators must be identical in every way, but either or both of them may be tagged as "weak" without affecting the result.
the weak comparison function MAY be used for simple (non-subrange) GET requests. the strong comparison function MUST be used in all other cases ๐
an entity tag is strong unless it's explicitly tagged as weak. section 3.11 gives the syntax for entity tags ๐ท๏ธ
a Last-Modified time, when used as a validator in a request, is implicitly weak unless it's possible to deduce that it's strong, using the following rules ๐งฉ
- The validator is being compared by an origin server to the actual current validator for the entity, and,
- That origin server reliably knows that the associated entity did not change twice during the second covered by the presented validator.
or
- The validator is about to be used by a client in an If-Modified-Since or If-Unmodified-Since header, because the client has a cache entry for the associated entity, and
- That cache entry includes a Date value, which gives the time when the origin server sent the original response, and
- The presented Last-Modified time is at least 60 seconds before the Date value.
or
- The validator is being compared by an intermediate cache to the validator stored in its cache entry for the entity, and
- That cache entry includes a Date value, which gives the time when the origin server sent the original response, and
- The presented Last-Modified time is at least 60 seconds before the Date value.
this method relies on the fact that if two different responses were sent by the origin server during the same second, but both had the same Last-Modified time, then at least one of those responses would have a Date value equal to its Last-Modified time. the arbitrary 60-second limit guards against the possibility that the Date and Last-Modified values come from different clocks, or get generated at somewhat different times during the preparation of the response. an implementation may use a value larger than 60 seconds, if it's believed that 60 seconds is too short โฑ๏ธ
if a client wants to do a sub-range retrieval on a value for which it only has a Last-Modified time and no opaque validator, it may do this only if the Last-Modified time is strong in the sense described here ๐ซง
a cache or origin server receiving a cache-conditional request, other than a full-body GET request, MUST use the strong comparison function to evaluate the condition ๐ก๏ธ
these rules let HTTP/1.1 caches and clients safely do sub-range retrievals on values that were obtained from HTTP/1.0 servers ๐ฅนโจ
13.3.4 Rules for When to Use Entity Tags and Last-modified Dates โจ
okay bestie, we're setting up a squad of rules and recommendations ๐ for origin servers, clients, and caches about when each validator type is used and what for ๐
HTTP/1.1 origin servers:
- SHOULD send an entity tag validator unless it is not feasible to generate one. ๐ท๏ธ
- MAY send a weak entity tag instead of a strong entity tag, if performance considerations support the use of weak entity tags, or if it is unfeasible to send a strong entity tag. ๐ธ
- SHOULD send a Last-Modified value if it is feasible to send one, unless the risk of a breakdown in semantic transparency that could result from using this date in an If-Modified-Since header would lead to serious problems. ๐ง
In other words, the preferred behavior for an HTTP/1.1 origin server is to send both a strong entity tag and a Last-Modified value. ๐
In order to be legal, a strong entity tag MUST change whenever the associated entity value changes in any way. A weak entity tag SHOULD change whenever the associated entity changes in a semantically significant way. ๐ฅ
Note: in order to provide semantically transparent caching, an origin server must avoid reusing a specific strong entity tag value for two different entities, or reusing a specific weak entity tag value for two semantically different entities. Cache entries may persist for arbitrarily long periods, regardless of expiration times, so it may be inappropriate to expect that a cache will never again attempt to validate an entry using a validator that it obtained at some point in the past. ๐
HTTP/1.1 clients:
- If an entity tag has been provided by the origin server, MUST use that entity tag in any cache-conditional request (using
If-MatchorIf-None-Match). ๐ - If only a Last-Modified value has been provided by the origin server, SHOULD use that value in non-subrange cache-conditional requests (using
If-Modified-Since). ๐ฆ - If only a Last-Modified value has been provided by an HTTP/1.0 origin server, MAY use that value in subrange cache-conditional requests (using
If-Unmodified-Since:). The user agent should provide a way to disable this, in case of difficulty. ๐ - If both an entity tag and a Last-Modified value have been provided by the origin server, SHOULD use both validators in cache-conditional requests. This allows both HTTP/1.0 and HTTP/1.1 caches to respond appropriately. ๐ซถ
An HTTP/1.1 cache, upon receiving a request, MUST use the most restrictive validator when deciding whether the client's cache entry matches the cache's own cache entry. This is only an issue when the request contains both an entity tag and a last-modified-date validator (If-Modified-Since or If-Unmodified-Since). ๐ง
A note on rationale: the general principle behind these rules is that HTTP/1.1 servers and clients should transmit as much non-redundant information as is available in their responses and requests. HTTP/1.1 systems receiving this information will make the most conservative assumptions about the validators they receive. ๐
HTTP/1.0 clients and caches will ignore entity tags. Generally, last-modified values received or used by these systems will support transparent and efficient caching, and so HTTP/1.1 origin servers should provide Last-Modified values. In those rare cases where the use of a Last-Modified value as a validator by an HTTP/1.0 system could result in a serious problem, then HTTP/1.1 origin servers should not provide one. ๐
13.3.5 Non-validating Conditionals โจ
the whole principle behind entity tags is that only the service author knows the semantics of a resource well enough to pick an appropriate cache validation mechanism ๐ง and specifying any validator comparison function more complex than byte-equality would open up a can of worms. So comparisons of any other headers (except Last-Modified, for compatibility with HTTP/1.0) are never used for purposes of validating a cache entry. ๐ โโ๏ธ
13.4 Response Cachability ๐
unless a Cache-Control (section 14.9) directive specifically constrains it, a caching system may always store a successful response (see section 13.8) as a cache entry, may return it without validation if it is fresh, and may return it after successful validation. If there is neither a cache validator nor an explicit expiration time associated with a response, we do not expect it to be cached, but certain caches may violate this expectation (for example, when little or no network connectivity is available). A client can usually detect that such a response was taken from a cache by comparing the Date header to the current time. ๐ต๏ธโโ๏ธ
Note that some HTTP/1.0 caches are known to violate this expectation without providing any Warning. ๐ญ
however, in some cases it may be inappropriate for a cache to retain an entity, or to return it in response to a subsequent request. This may be because absolute semantic transparency is deemed necessary by the service author, or because of security or privacy considerations. Certain Cache-Control directives are therefore provided so that the server can indicate that certain resource entities, or portions thereof, may not be cached regardless of other considerations. ๐
Note that section 14.8 normally prevents a shared cache from saving and returning a response to a previous request if that request included an Authorization header. ๐ก๏ธ
A response received with a status code of 200, 203, 206, 300, 301 or 410 may be stored by a cache and used in reply to a subsequent request, subject to the expiration mechanism, unless a Cache-Control directive prohibits caching. However, a cache that does not support the Range and Content-Range headers MUST NOT cache 206 (Partial Content) responses. ๐
A response received with any other status code MUST NOT be returned in a reply to a subsequent request unless there are Cache-Control directives or another header(s) that explicitly allow it. For example, these include the following: an Expires header (section 14.21); a "max-age", "must-revalidate", "proxy-revalidate", "public" or "private" Cache-Control directive (section 14.9). ๐ซ
13.5 Constructing Responses From Caches ๐ง
the whole point of an HTTP cache is to store information received in responses, for use in answering future requests ๐ค In many cases, a cache simply returns the appropriate parts of a response to the requester. However, if the cache holds a cache entry based on a previous response, it may have to combine parts of a new response with what is held in the cache entry. โจ
13.5.1 End-to-end and Hop-by-hop Headers ๐ฆ
for defining how caches and non-caching proxies behave, we split HTTP headers into two categories:
- End-to-end headers, which must be transmitted to the ultimate recipient of a request or response. End-to-end headers in responses must be stored as part of a cache entry and transmitted in any response formed from a cache entry. ๐ฌ
- Hop-by-hop headers, which are meaningful only for a single transport-level connection, and are not stored by caches or forwarded by proxies. ๐ช
The following HTTP/1.1 headers are hop-by-hop headers:
ConnectionKeep-AlivePublicProxy-AuthenticateTransfer-EncodingUpgrade
All other headers defined by HTTP/1.1 are end-to-end headers. ๐
Hop-by-hop headers introduced in future versions of HTTP MUST be listed in a Connection header, as described in section 14.10. ๐
13.5.2 Non-modifiable Headers ๐
some features of HTTP/1.1, like Digest Authentication, depend on the value of certain end-to-end headers ๐ A cache or non-caching proxy SHOULD NOT modify an end-to-end header unless the definition of that header requires or specifically allows that. โ ๏ธ
A cache or non-caching proxy MUST NOT modify any of the following fields in a request or response, nor may it add any of these fields if not already present: ๐
Content-LocationETagExpiresLast-Modified
A cache or non-caching proxy MUST NOT modify or add any of the following fields in a response that contains the no-transform Cache-Control directive, or in any request: ๐ท
Content-EncodingContent-LengthContent-RangeContent-Type
A cache or non-caching proxy MAY modify or add these fields in a response that does not include no-transform, but if it does so, it MUST add a Warning 14 (Transformation applied) if one does not already appear in the response. ๐จ
Warning: unnecessary modification of end-to-end headers may cause authentication failures if stronger authentication mechanisms are introduced in later versions of HTTP. Such authentication mechanisms may rely on the values of header fields not listed here. ๐จ
13.5.3 Combining Headers ๐งฉ
When a cache makes a validating request to a server, and the server provides a 304 (Not Modified) response, the cache must construct a response to send to the requesting client. The cache uses the entity-body stored in the cache entry as the entity-body of this outgoing response. The end-to-end headers stored in the cache entry are used for the constructed response, except that any end-to-end headers provided in the 304 response MUST replace the corresponding headers from the cache entry. Unless the cache decides to remove the cache entry, it MUST also replace the end-to-end headers stored with the cache entry with corresponding headers received in the incoming response. ๐ซ
in other words, the set of end-to-end headers received in the incoming response overrides all corresponding end-to-end headers stored with the cache entry. The cache may add Warning headers (see section 14.45) to this set. ๐
If a header field-name in the incoming response matches more than one header in the cache entry, all such old headers are replaced. ๐
Note: this rule allows an origin server to use a 304 (Not Modified) response to update any header associated with a previous response for the same entity, although it might not always be meaningful or correct to do so. This rule does not allow an origin server to use a 304 (not Modified) response to entirely delete a header that it had provided with a previous response. ๐
13.5.4 Combining Byte Ranges ๐ฐ
a response may transfer only a subrange of the bytes of an entity-body, either because the request included one or more Range specifications, or because a connection was broken prematurely. After several such transfers, a cache may have received several ranges of the same entity-body. ๐ง
If a cache has a stored non-empty set of subranges for an entity, and an incoming response transfers another subrange, the cache MAY combine the new subrange with the existing set if both the following conditions are met: ๐ค
- Both the incoming response and the cache entry must have a cache validator.
- The two cache validators must match using the strong comparison function (see section 13.3.3).
If either requirement is not meant, the cache must use only the most recent partial response (based on the Date values transmitted with every response, and using the incoming response if these values are equal or missing), and must discard the other partial information. ๐๏ธ
13.6 Caching Negotiated Responses ๐
okay so server-driven content negotiation (section 12) is when the server picks which version of a resource to send, and you can spot it because the response has a Vary header field ๐ that changes what a cache is allowed to do with the response for later requests, so pay attention bestie ๐ง
A server MUST use the Vary header field (section 14.43) to tell a cache which header field dimensions were used to pick among multiple representations of a cachable response. A cache may use the selected representation (the entity included with that particular response) to answer later requests on that resource, but only when those requests have the same or equivalent values for every header field listed in the Vary response-header. Requests with a different value for one or more of those header fields get forwarded toward the origin server ๐
If an entity tag was assigned to the representation, the forwarded request SHOULD be conditional and include the entity tags in an If-None-Match header field, pulled from all of its cache entries for the Request-URI ๐ซถ this tells the server which entities the cache is already holding, so if one of them matches the requested entity, the server can send back a 304 (Not Modified) response with the ETag header and let the cache know which entry is the right one. If the entity-tag of the new response matches an existing entry, the new response SHOULD be used to update that entry's header fields, and the result MUST be returned to the client โจ
The Vary header field can also tell the cache that the representation was picked using criteria that go beyond the request-headers. In that case, a cache MUST NOT use the response to answer a later request unless it relays the new request to the origin server as a conditional request and the server replies with 304 (Not Modified), including an entity tag or Content-Location that shows which entity should be used ๐
If any existing cache entry only holds partial content for its entity, that entry's entity-tag SHOULD NOT be included in the If-None-Match header, unless the request is for a range that the entry could fully satisfy ๐งฉ
If a cache gets a successful response whose Content-Location matches an existing cache entry for the same Request-URI, whose entity-tag is different from that entry's, and whose Date is more recent than the entry's, then the existing entry SHOULD NOT be returned for future requests, and should be deleted from the cache ๐๏ธ bye bye old entry
13.7 Shared and Non-Shared Caches ๐
for security and privacy reasons, we have to split caches into two groups: "shared" and "non-shared" ๐ซฃ a non-shared cache is one that only a single user can access, and access in this case SHOULD be enforced by appropriate security mechanisms. Every other cache counts as "shared." Other sections of this specification put some rules on how shared caches work, so they don't leak privacy or break access controls ๐
13.8 Errors or Incomplete Response Cache Behavior ๐
if a cache gets an incomplete response (like one with fewer bytes of data than the Content-Length header says), the cache may store it, BUT it MUST treat it as a partial response. Partial responses can be combined as described in section 13.5.4, and the result might be a full response or might still be partial ๐งฉ A cache MUST NOT return a partial response to a client without explicitly marking it as such, using the 206 (Partial Content) status code. A cache MUST NOT return a partial response using a status code of 200 (OK) โ
Okay, and if a cache gets a 5xx response while it's trying to revalidate an entry, it has two options: it can forward that response to the requesting client, or it can act like the server never responded at all ๐คทโโ๏ธ In the second case, it MAY return a previously received response, unless the cached entry includes the must-revalidate Cache-Control directive (see section 14.9).
13.9 Side Effects of GET and HEAD ๐
unless the origin server explicitly prohibits caching of its responses, using GET and HEAD on any resources SHOULD NOT have side effects that would cause wrong behavior if those responses come from a cache. They can still have side effects, but a cache doesn't have to think about those side effects when it makes caching decisions. Caches are always expected to respect an origin server's explicit restrictions on caching ๐
there's one exception to this, and it's giving old-school drama ๐ญ some applications used GETs and HEADs with query URLs (the ones with a "?" in the rel_path part) to do stuff with big side effects. So caches MUST NOT treat responses from those URLs as fresh unless the server gives an explicit expiration time. This specifically means that responses from HTTP/1.0 servers for such URIs should not be taken from a cache. See section 9.1.1 for related information ๐
13.10 Invalidation After Updates or Deletions ๐ฅ
certain methods running at the origin server can make one or more existing cache entries non-transparently invalid. Those entries might still count as "fresh," but they don't accurately show what the origin server would return for a new request ๐ฌ
Honestly there's no way for HTTP to guarantee that every one of those cache entries gets marked invalid. For example, the request that changed things at the origin server might never have gone through the proxy where a cache entry is stored. BUT several rules help cut down on the chance of messing things up ๐ซถ
In this section, the phrase "invalidate an entity" means that the cache should either remove all instances of that entity from its storage, or mark them as "invalid" so they need a mandatory revalidation before they can be returned for a later request ๐งน
Some HTTP methods may invalidate an entity. This is either the entity referred to by the Request-URI, or the entity referred to by the Location or Content-Location response-headers (if they're present). These methods are:
PUTDELETEPOST
to prevent denial of service attacks, an invalidation based on the URI in a Location or Content-Location header MUST only be performed if the host part is the same as in the Request-URI ๐ก๏ธ
13.11 Write-Through Mandatory โ๏ธ
all methods that might change the origin server's resources MUST be written through to the origin server. Right now that includes every method except GET and HEAD. A cache MUST NOT reply to such a request from a client before it has sent the request to the inbound server and gotten a matching response back from that server. This doesn't stop a cache from sending a 100 (Continue) response before the inbound server has replied ๐ธ
The alternative, known as "write-back" or "copy-back" caching, is not allowed in HTTP/1.1. Keeping updates consistent is hard, and there are real problems if the server, cache, or network fails before a write-back happens ๐ต
13.12 Cache Replacement ๐
if a new cachable response (see sections 14.9.2, 13.2.5, 13.2.6 and 13.8) comes in from a resource while existing responses for that same resource are cached, the cache SHOULD use the new response to answer the current request. It may store it in cache storage and, if it meets all the other requirements, use it to respond to any future requests that would have gotten the old response before ๐ If it does put the new response into cache storage, it should follow the rules in section 13.5.3.
Note: a new response with an older Date header value than the existing cached responses is not cachable. Don't let the old one overwrite the fresh tea โ
13.13 History Lists ๐
user agents often have history mechanisms, like "Back" buttons and history lists, that can be used to redisplay an entity retrieved earlier in a session ๐งโโ๏ธ
History mechanisms and caches are totally different things ๐ Specifically, history mechanisms SHOULD NOT try to show a semantically transparent view of a resource's current state. Instead, a history mechanism is meant to show exactly what the user saw at the time the resource was retrieved ๐ธ
By default, an expiration time does not apply to history mechanisms. If the entity is still in storage, a history mechanism should display it even if the entity has expired, unless the user has specifically configured the agent to refresh expired history documents ๐
This should not be read as stopping the history mechanism from telling the user that a view may be stale ๐
Note: if history list mechanisms unnecessarily stop users from viewing stale resources, service authors will tend to avoid HTTP expiration controls and cache controls when they'd otherwise like to use them. Service authors may think it's important that users never see error or warning messages when they use navigation controls (such as BACK) to view previously fetched resources. Even when such resources ought not to be cached, or ought to expire quickly, user interface considerations may push service authors to use other ways of preventing caching (e.g. "once-only" URLs) so they don't suffer from improperly functioning history mechanisms ๐ญ
14 Header Field Definitions ๐
This section defines the syntax and semantics of all standard HTTP/1.1 header fields. For entity-header fields, both sender and recipient refer to either the client or the server, depending on who sends and who receives the entity ๐
14.1 Accept ๐
okay so the Accept request-header field is how a client tells the server which media types it's cool receiving back in the response ๐ like when you only want a tiny set of types, say you're asking for an in-line image, and you literally don't want anything else ๐
Accept = "Accept" ":"
#( media-range [ accept-params ] )
media-range = ( "*/*"
| ( type "/" "*" )
| ( type "/" subtype )
) *( ";" parameter )
accept-params = ";" "q" "=" qvalue *( accept-extension )
accept-extension = ";" token [ "=" ( token | quoted-string ) ]
The asterisk "" is how you group media types into ranges ๐ฆ so "/" means all media types and "type/" means all subtypes of that type. The media-range MAY include media type parameters that apply to that range โจ
Each media-range MAY be followed by one or more accept-params, starting with the "q" parameter for a relative quality factor ๐ธ The first "q" parameter (if any) is what separates the media-range parameters from the accept-params. Quality factors let the user or user agent show how much they prefer that media-range, using the qvalue scale from 0 to 1 (section 3.9). The default value is q=1 ๐
Note: Using the "q" parameter name to split media type parameters from Accept extension parameters is due to historical practice ๐ This means a media type parameter named "q" can't be used with a media range. Such an event is believed to be unlikely, given the lack of any "q" parameters in the IANA media type registry and the rare usage of any media type parameters in Accept. Future media types should be discouraged from registering any parameter named "q".
Here's the example:
Accept: audio/*; q=0.2, audio/basic
This one SHOULD be interpreted as "I prefer audio/basic, but send me any audio type if it is the best available after an 80% mark-down in quality." ๐ญ If no Accept header field is present, then it is assumed that the client accepts all media types. If an Accept header field is present, and the server cannot send a response which is acceptable according to the combined Accept field value, then the server SHOULD send a 406 (not acceptable) response ๐
A more elaborate example is:
Accept: text/plain; q=0.5, text/html,
text/x-dvi; q=0.8, text/x-c
Verbally, this is giving "text/html and text/x-c are the preferred media types, but if they do not exist, then send the text/x-dvi entity, and if that does not exist, send the text/plain entity." main character energy ๐
Media ranges can be overridden by more specific media ranges or specific media types. If more than one media range applies to a given type, the most specific reference has precedence ๐ง For example:
Accept: text/*, text/html, text/html;level=1, */*
have the following precedence:
1) text/html;level=1
2) text/html
3) text/*
4) */*
The media type quality factor for a given type is determined by finding the media range with the highest precedence which matches that type ๐ For example:
Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
text/html;level=2;q=0.4, */*;q=0.5
would cause the following values to be associated:
text/html;level=1 = 1
text/html = 0.7
text/plain = 0.3
image/jpeg = 0.5
text/html;level=2 = 0.4
text/html;level=3 = 0.7
Note: A user agent may be provided with a default set of quality values for certain media ranges. However, unless the user agent is a closed system which cannot interact with other rendering agents, this default set should be configurable by the user ๐
14.2 Accept-Charset ๐
The Accept-Charset request-header field is how you tell the server which character sets are acceptable for the response ๐ธ Clients that can understand fancier or special-purpose character sets use this to signal that to a server that can represent documents in those sets. The ISO-8859-1 character set can be assumed to be acceptable to all user agents โจ
Accept-Charset = "Accept-Charset" ":"
1#( charset [ ";" "q" "=" qvalue ] )
Character set values are described in section 3.4. Each charset may be given an associated quality value that shows the user's preference for that charset. The default value is q=1. An example is:
Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
If no Accept-Charset header is present, the default is that any character set is acceptable ๐ฆ If an Accept-Charset header is present, and the server cannot send a response that is acceptable according to that header, then the server SHOULD send an error response with the 406 (not acceptable) status code ๐ญ though sending an unacceptable response is also allowed ๐
14.3 Accept-Encoding ๐ง
The Accept-Encoding request-header field is similar to Accept, but it restricts the content-coding values (section 14.12) that are acceptable in the response ๐
Accept-Encoding = "Accept-Encoding" ":"
#( content-coding )
An example of its use is:
Accept-Encoding: compress, gzip
If no Accept-Encoding header is present in a request, the server MAY assume that the client will accept any content coding ๐ If an Accept-Encoding header is present, and the server cannot send a response which is acceptable according to it, then the server SHOULD send an error response with the 406 (Not Acceptable) status code ๐
An empty Accept-Encoding value indicates none are acceptable. ๐
14.4 Accept-Language ๐ธ
The Accept-Language request-header field is similar to Accept, but it restricts the set of natural languages that are preferred as a response to the request ๐
Accept-Language = "Accept-Language" ":"
1#( language-range [ ";" "q" "=" qvalue ] )
language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )
Each language-range MAY be given an associated quality value that represents an estimate of the user's preference for the languages specified by that range ๐ฆ The quality value defaults to "q=1". For example:
Accept-Language: da, en-gb;q=0.8, en;q=0.7
This would mean: "I prefer Danish, but will accept British English and other types of English." โจ A language-range matches a language-tag if it exactly equals the tag, or if it exactly equals a prefix of the tag such that the first tag character following the prefix is "-". The special range "*", if present in the Accept-Language field, matches every tag not matched by any other range present in that field ๐
Note: This use of a prefix matching rule does not imply that language tags are assigned to languages in such a way that it is always true that if a user understands a language with a certain tag, then this user will also understand all languages with tags for which this tag is a prefix. The prefix rule simply allows the use of prefix tags if this is the case.
The language quality factor assigned to a language-tag by the Accept-Language field is the quality value of the longest language-range in the field that matches the language-tag ๐ง If no language-range in the field matches the tag, the language quality factor assigned is 0. If no Accept-Language header is present in the request, the server SHOULD assume that all languages are equally acceptable. If an Accept-Language header is present, then all languages which are assigned a quality factor greater than 0 are acceptable ๐
It may be contrary to the privacy expectations of the user to send an Accept-Language header with the complete linguistic preferences of the user in every request ๐ฅ For a discussion of this issue, see section 15.7.
Note: As intelligibility is highly dependent on the individual user, it is recommended that client applications make the choice of linguistic preference available to the user. If the choice is not made available, then the Accept-Language header field must not be given in the request. ๐ซถ
14.5 Accept-Ranges ๐
The Accept-Ranges response-header field lets the server say whether it accepts range requests for a resource ๐ฆ
Accept-Ranges = "Accept-Ranges" ":" acceptable-ranges
acceptable-ranges = 1#range-unit | "none"
Origin servers that accept byte-range requests MAY send:
Accept-Ranges: bytes
but they are not required to do so โจ Clients MAY generate byte-range requests without having received this header for the resource involved ๐
Servers that do not accept any kind of range request for a resource MAY send:
Accept-Ranges: none
to advise the client not to attempt a range request ๐
14.6 Age ๐
The Age response-header field conveys the sender's estimate of the amount of time since the response (or its revalidation) was generated at the origin server โฐ A cached response is "fresh" if its age does not exceed its freshness lifetime. Age values are calculated as specified in section 13.2.3 ๐
Age = "Age" ":" age-value
age-value = delta-seconds
Age values are non-negative decimal integers, representing time in seconds ๐ง
If a cache receives a value larger than the largest positive integer it can represent, or if any of its age calculations overflows, it MUST transmit an Age header with a value of 2147483648 (2^31) ๐ญ HTTP/1.1 caches MUST send an Age header in every response. Caches SHOULD use an arithmetic type of at least 31 bits of range ๐ฅ
14.7 Allow ๐
The Allow entity-header field lists the set of methods supported by the resource identified by the Request-URI ๐ The purpose of this field is strictly to inform the recipient of valid methods associated with the resource. An Allow header field MUST be present in a 405 (Method Not Allowed) response ๐
Allow = "Allow" ":" 1#method
Example of use:
Allow: GET, HEAD, PUT
This field cannot prevent a client from trying other methods ๐ However, the indications given by the Allow header field value SHOULD be followed. The actual set of allowed methods is defined by the origin server at the time of each request ๐ฆ
The Allow header field MAY be provided with a PUT request to recommend the methods to be supported by the new or modified resource โจ The server is not required to support these methods and SHOULD include an Allow header in the response giving the actual supported methods ๐
A proxy MUST NOT modify the Allow header field even if it does not understand all the methods specified, since the user agent MAY have other means of communicating with the origin server ๐ซถ
The Allow header field does not indicate what methods are implemented at the server level. Servers MAY use the Public response-header field (section 14.35) to describe what methods are implemented on the server as a whole ๐ธ
14.8 Authorization โจ
okay bestie, so a user agent that wants to prove who it is to a server can do that by adding an Authorization request-header field to the request ๐. It usually does this after getting a 401 response, but not always. MAY is the magic word here, so it's totally optional ๐ . The value is the credentials, which hold the user agent's login info for the realm of the resource it's asking for.
Authorization = "Authorization" ":" credentials
HTTP access authentication gets its own deep dive in section 11 ๐ง . If a request is authenticated and a realm is named, the same credentials SHOULD be valid for every other request in that realm. That's the vibe we want, no drama ๐ซถ.
okay now the important part ๐ค when a shared cache (see section 13.7) gets a request with an Authorization field, it MUST NOT hand that response back to any other request. the only exceptions are these three:
- if the response has the
proxy-revalidateCache-Control directive, the cache MAY use it to answer a later request. BUT a proxy cache MUST revalidate it with the origin server first, using the request headers from the new request so the origin server can authenticate that new request ๐. - if the response has the
must-revalidateCache-Control directive, the cache MAY use it to answer a later request. BUT all caches MUST revalidate it with the origin server first, using the request headers from the new request so the origin server can authenticate it ๐. - if the response has the
publicCache-Control directive, it may be returned for any later request ๐.
14.9 Cache-Control ๐
the Cache-Control general-header field is how you set directives that MUST be obeyed by every caching mechanism along the request/response chain ๐ฃ. These directives are there to stop caches from messing with the request or response, and they usually override the default caching rules. Cache directives are one-way, so a directive in a request doesn't mean the same directive should show up in the response ๐ฆ.
๐ Note: HTTP/1.0 caches might not support Cache-Control at all, and they may only understand Pragma: no-cache (see section 14.32).
a proxy or gateway MUST pass cache directives along, even if it doesn't care about them itself, since they might matter to everyone else on the chain ๐ซถ. You also can't target a directive at one specific cache.
Cache-Control = "Cache-Control" ":" 1#cache-directive
cache-directive = cache-request-directive
| cache-response-directive
cache-request-directive =
"no-cache" [ "=" <"> 1#field-name <"> ]
| "no-store"
| "max-age" "=" delta-seconds
| "max-stale" [ "=" delta-seconds ]
| "min-fresh" "=" delta-seconds
| "only-if-cached"
| cache-extension
cache-response-directive =
"public"
| "private" [ "=" <"> 1#field-name <"> ]
| "no-cache" [ "=" <"> 1#field-name <"> ]
| "no-store"
| "no-transform"
| "must-revalidate"
| "proxy-revalidate"
| "max-age" "=" delta-seconds
| cache-extension
cache-extension = token [ "=" ( token | quoted-string ) ]
when a directive shows up with no 1#field-name parameter, it covers the whole request or response ๐ธ. when it DOES have a 1#field-name parameter, it only applies to those named fields and not the rest of the message. this is the extensibility trick ๐ง, so future HTTP versions can apply these directives to header fields that HTTP/1.1 never defined.
the cache-control directives fall into these general categories:
- Restrictions on what is cachable; these may only be imposed by the origin server.
- Restrictions on what may be stored by a cache; these may be imposed by either the origin server or the user agent.
- Modifications of the basic expiration mechanism; these may be imposed by either the origin server or the user agent.
- Controls over cache revalidation and reload; these may only be imposed by a user agent.
- Control over transformation of entities.
- Extensions to the caching system.
14.9.1 What is Cachable ๐
by default, a response is cachable if the request method, the request header fields, and the response status all say it is ๐. section 13.4 sums up those defaults. these Cache-Control response directives let an origin server override the default:
public
- this says the response is cachable by any cache, even if it would normally be non-cachable or only cachable in a non-shared cache ๐. (See also Authorization, section 14.8, for additional details.)
private
- this says all or part of the response is meant for ONE user and MUST NOT be stored by a shared cache ๐. the origin server is basically saying those parts are only for one person and aren't a valid answer for anyone else. a private (non-shared) cache is allowed to store it.
โจ Note: this use of the word private only controls WHERE the response can be cached. It can't guarantee the privacy of the message content.
no-cache
- this says all or part of the response MUST NOT be cached ANYWHERE ๐ซ. it stops caching even in caches that were set up to serve stale responses to clients.
๐ Note: most HTTP/1.0 caches won't recognize or follow this directive.
14.9.2 What May be Stored by Caches ๐
the no-store directive exists to stop sensitive info from being accidentally released or kept around (like on backup tapes ๐ผ). it covers the whole message and can show up in a request or a response. if it's in a request, a cache MUST NOT store any part of that request or any response to it. if it's in a response, a cache MUST NOT store any part of that response or the request that triggered it. this applies to both shared and non-shared caches ๐ โโ๏ธ. "MUST NOT store" here means the cache MUST NOT deliberately save the info to non-volatile storage, and it MUST make a best-effort attempt to clear it from volatile storage as quickly as possible after forwarding it.
even with this directive on a response, users can still save it outside the caching system (like with a "Save As" dialog ๐พ). history buffers may also keep these responses as part of how they normally work.
this directive is for people and service authors who are worried about info leaking through unexpected access to cache data structures ๐. it can help privacy in some cases, BUT we really need to say it is NOT in any way a reliable or sufficient privacy mechanism ๐ญ. malicious or compromised caches may ignore it, and communications networks may be open to eavesdropping ๐ต๏ธโโ๏ธ.
14.9.3 Modifications of the Basic Expiration Mechanism โฐ
the origin server can set an entity's expiration time with the Expires header (see section 14.21) ๐ . or it can use the max-age directive in a response instead.
if a response has BOTH an Expires header AND a max-age directive, max-age wins, even when Expires is stricter ๐. this lets an origin server give an HTTP/1.1 (or later) cache a longer expiration time than an HTTP/1.0 cache. it's handy if some HTTP/1.0 caches miscalculate ages or expiration times, maybe because their clocks are out of sync ๐ฐ๏ธ.
๐ Note: most older caches that don't follow this spec don't support any Cache-Control directives at all. If an origin server wants a directive that limits caching by an HTTP/1.1-compliant cache without fully blocking it, it can rely on the rule that max-age overrides Expires, and on the fact that non-HTTP/1.1-compliant caches ignore max-age ๐ง .
user agents can also tweak the basic expiration mechanism with these request directives:
max-age
- the client is happy to take a response whose age is no more than the given seconds โฑ๏ธ. unless a max-stale directive is also there, the client won't accept a stale response.
min-fresh
- the client will accept a response whose freshness lifetime is at least its current age plus the given seconds ๐ฟ. basically, it wants a response that stays fresh for at least that many more seconds.
max-stale
- the client will accept a response that's already past its expiration time ๐ฅ. if max-stale has a value, the client accepts a response that's past expiration by no more than that many seconds. if there's no value, the client will take a stale response of ANY age ๐.
if a cache returns a stale response, either because of a max-stale directive on the request or because the cache is set up to override the response's expiration time, the cache MUST attach a Warning header to that stale response, using Warning 10 (Response is stale) โ ๏ธ.
14.9.4. Cache Revalidation and Reload Controls โจ
Okay so sometimes a user agent wants or needs a cache to revalidate its cache entry with the origin server (and not just with the next cache along the path to the origin server), or to reload its cache entry from the origin server. End-to-end revalidation may be necessary if either the cache or the origin server has overestimated the expiration time of the cached response. End-to-end reload may be necessary if the cache entry has become corrupted for some reason ๐.
End-to-end revalidation may be requested either when the client does not have its own local cached copy, in which case we call it "unspecified end-to-end revalidation", or when the client does have a local cached copy, in which case we call it "specific end-to-end revalidation." ๐ฆ
The client can specify these three kinds of action using Cache-Control request directives:
End-to-end reload ๐ The request includes a "no-cache" Cache-Control directive or, for compatibility with HTTP/1.0 clients, Pragma: no-cache. No field names may be included with the no-cache directive in a request. The server MUST NOT use a cached copy when responding to such a request.
Specific end-to-end revalidation ๐ The request includes a "max-age=0" Cache-Control directive, which forces each cache along the path to the origin server to revalidate its own entry, if any, with the next cache or server. The initial request includes a cache-validating conditional with the client's current validator.
Unspecified end-to-end revalidation ๐ธ The request includes "max-age=0" Cache-Control directive, which forces each cache along the path to the origin server to revalidate its own entry, if any, with the next cache or server. The initial request does not include a cache-validating conditional; the first cache along the path (if any) that holds a cache entry for this resource includes a cache-validating conditional with its current validator.
When an intermediate cache is forced, by means of a max-age=0 directive, to revalidate its own cache entry, and the client has supplied its own validator in the request, the supplied validator may differ from the validator currently stored with the cache entry. In this case, the cache may use either validator in making its own request without affecting semantic transparency. ๐ซถ
However, the choice of validator may affect performance. The best approach is for the intermediate cache to use its own validator when making its request. If the server replies with 304 (Not Modified), then the cache should return its now validated copy to the client with a 200 (OK) response. If the server replies with a new entity and cache validator, however, the intermediate cache should compare the returned validator with the one provided in the client's request, using the strong comparison function. If the client's validator is equal to the origin server's, then the intermediate cache simply returns 304 (Not Modified). Otherwise, it returns the new entity with a 200 (OK) response. โจ
If a request includes the no-cache directive, it should not include min-fresh, max-stale, or max-age.
In some cases, such as times of extremely poor network connectivity, a client may want a cache to return only those responses that it currently has stored, and not to reload or revalidate with the origin server. To do this, the client may include the only-if-cached directive in a request. If it receives this directive, a cache SHOULD either respond using a cached entry that is consistent with the other constraints of the request, or respond with a 504 (Gateway Timeout) status. However, if a group of caches is being operated as a unified system with good internal connectivity, such a request MAY be forwarded within that group of caches. ๐
Because a cache may be configured to ignore a server's specified expiration time, and because a client request may include a max-stale directive (which has a similar effect), the protocol also includes a mechanism for the origin server to require revalidation of a cache entry on any subsequent use. When the must-revalidate directive is present in a response received by a cache, that cache MUST NOT use the entry after it becomes stale to respond to a subsequent request without first revalidating it with the origin server. (I.e., the cache must do an end-to-end revalidation every time, if, based solely on the origin server's Expires or max-age value, the cached response is stale.) ๐
The must-revalidate directive is necessary to support reliable operation for certain protocol features. In all circumstances an HTTP/1.1 cache MUST obey the must-revalidate directive; in particular, if the cache cannot reach the origin server for any reason, it MUST generate a 504 (Gateway Timeout) response. ๐ซ
Servers should send the must-revalidate directive if and only if failure to revalidate a request on the entity could result in incorrect operation, such as a silently unexecuted financial transaction. Recipients MUST NOT take any automated action that violates this directive, and MUST NOT automatically provide an unvalidated copy of the entity if revalidation fails. ๐ธ
Although this is not recommended, user agents operating under severe connectivity constraints may violate this directive but, if so, MUST explicitly warn the user that an unvalidated response has been provided. The warning MUST be provided on each unvalidated access, and SHOULD require explicit user confirmation. โ ๏ธ
The proxy-revalidate directive has the same meaning as the must-revalidate directive, except that it does not apply to non-shared user agent caches. It can be used on a response to an authenticated request to permit the user's cache to store and later return the response without needing to revalidate it (since it has already been authenticated once by that user), while still requiring proxies that service many users to revalidate each time (in order to make sure that each user has been authenticated). Note that such authenticated responses also need the public cache control directive in order to allow them to be cached at all. ๐
14.9.5. No-Transform Directive ๐
Implementers of intermediate caches (proxies) have found it useful to convert the media type of certain entity bodies. A proxy might, for example, convert between image formats in order to save cache space or to reduce the amount of traffic on a slow link. HTTP has to date been silent on these transformations. ๐ผ๏ธ
Serious operational problems have already occurred, however, when these transformations have been applied to entity bodies intended for certain kinds of applications. For example, applications for medical imaging, scientific data analysis and those using end-to-end authentication, all depend on receiving an entity body that is bit for bit identical to the original entity-body. ๐ฉบ
Therefore, if a response includes the no-transform directive, an intermediate cache or proxy MUST NOT change those headers that are listed in section 13.5.2 as being subject to the no-transform directive. This implies that the cache or proxy must not change any aspect of the entity-body that is specified by these headers. ๐ โโ๏ธ
14.9.6. Cache Control Extensions ๐งฉ
The Cache-Control header field can be extended through the use of one or more cache-extension tokens, each with an optional assigned value. Informational extensions (those which do not require a change in cache behavior) may be added without changing the semantics of other directives. Behavioral extensions are designed to work by acting as modifiers to the existing base of cache directives. Both the new directive and the standard directive are supplied, such that applications which do not understand the new directive will default to the behavior specified by the standard directive, and those that understand the new directive will recognize it as modifying the requirements associated with the standard directive. In this way, extensions to the Cache-Control directives can be made without requiring changes to the base protocol. ๐ง
This extension mechanism depends on a HTTP cache obeying all of the cache-control directives defined for its native HTTP-version, obeying certain extensions, and ignoring all directives that it does not understand. ๐ค
For example, consider a hypothetical new response directive called "community" which acts as a modifier to the "private" directive. We define this new directive to mean that, in addition to any non-shared cache, any cache which is shared only by members of the community named within its value may cache the response. An origin server wishing to allow the "UCI" community to use an otherwise private response in their shared cache(s) may do so by including:
Cache-Control: private, community="UCI"
A cache seeing this header field will act correctly even if the cache does not understand the "community" cache-extension, since it will also see and understand the "private" directive and thus default to the safe behavior. ๐ฅฐ
Unrecognized cache-directives MUST be ignored; it is assumed that any cache-directive likely to be unrecognized by an HTTP/1.1 cache will be combined with standard directives (or the response's default cachability) such that the cache behavior will remain minimally correct even if the cache does not understand the extension(s). ๐
14.10. Connection ๐
The Connection general-header field allows the sender to specify options that are desired for that particular connection and MUST NOT be communicated by proxies over further connections. ๐
The Connection header has the following grammar:
Connection-header = "Connection" ":" 1#(connection-token)
connection-token = token
HTTP/1.1 proxies MUST parse the Connection header field before a message is forwarded and, for each connection-token in this field, remove any header field(s) from the message with the same name as the connection-token. Connection options are signaled by the presence of a connection-token in the Connection header field, not by any corresponding additional header field(s), since the additional header field may not be sent if there are no parameters associated with that connection option. HTTP/1.1 defines the "close" connection option for the sender to signal that the connection will be closed after completion of the response. For example:
Connection: close
in either the request or the response header fields indicates that the connection should not be considered persistent (section 8.1) after the current request/response is complete. ๐ช
HTTP/1.1 applications that do not support persistent connections MUST include the "close" connection option in every message. ๐โโ๏ธ
14.11. Content-Base ๐
The Content-Base entity-header field may be used to specify the base URI for resolving relative URLs within the entity. This header field is described as Base in RFC 1808, which is expected to be revised. ๐บ๏ธ
Content-Base = "Content-Base" ":" absoluteURI
If no Content-Base field is present, the base URI of an entity is defined either by its Content-Location (if that Content-Location URI is an absolute URI) or the URI used to initiate the request, in that order of precedence. Note, however, that the base URI of the contents within the entity-body may be redefined within that entity-body. ๐ฏ
14.12 Content-Encoding ๐
okay so Content-Encoding is a modifier that sits on top of the media-type โจ when it shows up, its value tells you which extra content codings got applied to the entity-body, which means which decoding steps you MUST run to get back the media-type named in Content-Type. it's mainly there so a doc can get compressed without losing its identity as whatever media type it really is ๐
Content-Encoding = "Content-Encoding" ":" 1#content-coding
Content codings are defined in section 3.5. an example looks like this ๐
Content-Encoding: gzip
Content-Encoding is a characteristic of the entity identified by the Request-URI. usually the entity-body is stored with this encoding and only gets decoded right before rendering or something similar ๐ซถ
If multiple encodings have been applied to an entity, the content codings MUST be listed in the order in which they were applied ๐ฅ
Additional information about the encoding parameters MAY be provided by other entity-header fields not defined by this specification โจ
14.13 Content-Language ๐
the Content-Language entity-header field describes the natural language(s) of the intended audience for the enclosed entity ๐ง and lowkey, this may not be the same as every language used inside the entity-body, so keep that in mind ๐
Content-Language = "Content-Language" ":" 1#language-tag
Language tags are defined in section 3.10. the main point of Content-Language is to let a user identify and tell entities apart based on their own preferred language ๐ so if the body is only meant for Danish readers, the field is
Content-Language: da
if no Content-Language is specified, the default is that the content is meant for every language audience ๐ฆ that could mean the sender doesn't think it's specific to any natural language, or that the sender just doesn't know who it's for, which is a very real vibe ๐
Multiple languages MAY be listed for content meant for multiple audiences. for example, a rendition of the "Treaty of Waitangi," shown side by side in the original Maori and English versions, would call for
Content-Language: mi, en
BUT just because there are multiple languages in an entity doesn't mean it's for multiple linguistic audiences ๐ take a beginner's language primer, like "A First Lesson in Latin," which is clearly meant for an English-literate audience. in that case, the Content-Language should only include "en" ๐
Content-Language may be applied to any media type. it is not limited to textual documents, so go wild ๐ธ
14.14 Content-Length ๐ง
the Content-Length entity-header field tells you the size of the message-body, in decimal octets, that gets sent to the recipient. or, when the method is HEAD, it's the size of the entity-body that would have been sent if the request had been a GET โจ
Content-Length = "Content-Length" ":" 1*DIGIT
an example is ๐
Content-Length: 3495
Applications SHOULD use this field to indicate the size of the message-body to be transferred, no matter what the media type of the entity is ๐ the recipient has to be able to reliably figure out where HTTP/1.1 requests with an entity-body end. for instance, that works if the request has a valid Content-Length field, uses Transfer-Encoding: chunked, or has a multipart body ๐ซถ
Any Content-Length greater than or equal to zero is a valid value ๐ฅ Section 4.4 explains how to work out the length of a message-body if no Content-Length is given ๐
Note: The meaning of this field is significantly different from the corresponding definition in MIME, where it is an optional field used within the "message/external-body" content-type. In HTTP, it SHOULD be sent whenever the message's length can be determined prior to being transferred. ๐
14.15 Content-Location ๐ฆ
the Content-Location entity-header field can be used to supply the resource location for the entity that's enclosed in the message โจ when a resource has multiple entities attached, and those entities actually have their own separate locations you can use to reach them individually, the server should provide a Content-Location for the particular variant that gets returned ๐ง and a server SHOULD also provide a Content-Location for the resource that matches the response entity ๐
Content-Location = "Content-Location" ":"
( absoluteURI | relativeURI )
if there's no Content-Base header field, the value of Content-Location also defines the base URL for the entity (see section 14.11) ๐
The Content-Location value is NOT a replacement for the original requested URI ๐ it's only a statement of where the resource for this particular entity lives at the time of the request. Future requests MAY use the Content-Location URI if they want to identify the source of that particular entity ๐
A cache cannot assume that an entity with a Content-Location that's different from the URI used to retrieve it can be used to answer later requests on that Content-Location URI ๐ however, Content-Location can be used to tell apart multiple entities retrieved from a single requested resource, as described in section 13.6 ๐ฅ
If the Content-Location is a relative URI, it gets interpreted relative to any Content-Base URI in the response. if no Content-Base is provided, the relative URI is interpreted relative to the Request-URI ๐
14.16 Content-MD5 ๐ฅ
the Content-MD5 entity-header field, as defined in RFC 1864 [23], is an MD5 digest of the entity-body. its job is to give you an end-to-end message integrity check (MIC) of the entity-body ๐ (Note: a MIC is good for catching accidental changes to the entity-body in transit, but it is NOT proof against malicious attacks. stay sus ๐)
Content-MD5 = "Content-MD5" ":" md5-digest
md5-digest = <base64 of 128 bit MD5 digest as per RFC 1864>
The Content-MD5 header field may be generated by an origin server to act as an integrity check of the entity-body โจ only origin servers may generate it. proxies and gateways MUST NOT generate it, because that would wreck its value as an end-to-end integrity check ๐ญ any recipient of the entity-body, including gateways and proxies, MAY check that the digest value in this header field matches the entity-body as received ๐ซถ
The MD5 digest is computed over the content of the entity-body, including any Content-Encoding that has been applied, but NOT including any Transfer-Encoding that may have been applied to the message-body. if the message comes in with a Transfer-Encoding, that encoding must be removed before checking the Content-MD5 value against the received entity ๐ง
So the digest ends up being computed on the octets of the entity-body exactly as, and in the order that, they would be sent if no Transfer-Encoding were being applied ๐
HTTP extends RFC 1864 to permit the digest to be computed for MIME composite media-types (e.g., multipart/* and message/rfc822), but that does NOT change how the digest is computed as defined in the paragraph above ๐
Note: There are several consequences of this. The entity-body for composite types may contain many body-parts, each with its own MIME and HTTP headers (including Content-MD5, Content-Transfer-Encoding, and Content-Encoding headers). If a body-part has a Content-Transfer-Encoding or Content-Encoding header, it is assumed that the content of the body-part has had the encoding applied, and the body-part is included in the Content-MD5 digest as is -- i.e., after the application. The Transfer-Encoding header field is not allowed within body-parts. ๐
Note: while the definition of Content-MD5 is exactly the same for HTTP as in RFC 1864 for MIME entity-bodies, there are several ways in which the application of Content-MD5 to HTTP entity-bodies differs from its application to MIME entity-bodies. One is that HTTP, unlike MIME, does not use Content-Transfer-Encoding, and does use Transfer-Encoding and Content-Encoding. Another is that HTTP more frequently uses binary content types than MIME, so it is worth noting that, in such cases, the byte order used to compute the digest is the transmission byte order defined for the type. Lastly, HTTP allows transmission of text types with any of several line break conventions and not just the canonical form using CRLF. Conversion of all line breaks to CRLF should not be done before computing or checking the digest: the line break convention used in the text actually transmitted should be left unaltered when computing the digest. ๐ฆ
14.17 Content-Range โจ
okay bestie, so Content-Range is the header that says "this is just a slice, and here's exactly where it goes in the big picture" ๐งฉ Whenever a server sends a partial entity-body, it has to show both the range it's covering and the total length of the whole entity-body ๐
Content-Range = "Content-Range" ":" content-range-spec
content-range-spec = byte-content-range-spec
byte-content-range-spec = bytes-unit SP first-byte-pos "-"
last-byte-pos "/" entity-length
entity-length = 1*DIGIT
ngl this is giving main character energy ๐ Unlike byte-ranges-specifier values, a byte-content-range-spec can only cover one range, and it has to use absolute byte positions for both the first and last byte of that range ๐ฆ
A byte-content-range-spec is invalid if its last-byte-pos is less than its first-byte-pos, or if its entity-length is less than or equal to its last-byte-pos. ๐ The recipient of an invalid byte-content-range-spec MUST ignore it and any content transferred along with it. No exceptions, periodt ๐ซ
Here are some examples, assuming the entity has a total of 1234 bytes:
- The first 500 bytes:
bytes 0-499/1234
- The second 500 bytes:
bytes 500-999/1234
- All except for the first 500 bytes:
bytes 500-1233/1234
- The last 500 bytes:
bytes 734-1233/1234
When an HTTP message carries the content of a single range (like a response to a request for one range, or a request for a set of ranges that overlap with no holes), that content gets sent with a Content-Range header, plus a Content-Length header showing how many bytes were actually transferred ๐ธ For example:
HTTP/1.1 206 Partial content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Range: bytes 21010-47021/47022
Content-Length: 26012
Content-Type: image/gif
When an HTTP message carries the content of multiple ranges (like a response to a request for several non-overlapping ranges), those get sent as a multipart MIME message ๐ง This spec defines the multipart MIME content-type for this job as "multipart/byteranges". See appendix 19.2 for its definition ๐
A client that can't decode a MIME multipart/byteranges message should not ask for multiple byte-ranges in a single request. ๐
When a client asks for multiple byte-ranges in one request, the server SHOULD return them in the same order they appeared in the request โจ
If the server ignores a byte-range-spec because it's invalid, the server should treat the request as if the invalid Range header field didn't exist. (Normally that means returning a 200 response with the full entity ๐) The reason is that a client only makes such an invalid request when the entity is smaller than the entity retrieved by a prior request, so it's basically a sign the file shrank ๐ฅน
14.18 Content-Type ๐
The Content-Type entity-header field tells the recipient the media type of the entity-body. If the method is HEAD, it tells you the media type that would have been sent if the request had been a GET ๐
Content-Type = "Content-Type" ":" media-type
Media types are defined in section 3.7. Here's an example of the field:
Content-Type: text/html; charset=ISO-8859-4
If you want more on how to figure out the media type of an entity, check out section 7.2.1 ๐
14.19 Date ๐๏ธ
The Date general-header field shows the date and time when the message was originated. It has the same semantics as orig-date in RFC 822. The field value is an HTTP-date, as described in section 3.3.1 ๐ฐ๏ธ
Date = "Date" ":" HTTP-date
Here's an example:
Date: Tue, 15 Nov 1994 08:12:31 GMT
If a message comes in over a direct connection with the user agent (for requests) or the origin server (for responses), the receiver can assume the date is the current date on their end ๐ But the date matters a lot for evaluating cached responses, since it's what the origin believes. That's why origin servers MUST include a Date header field in all responses ๐ซถ Clients SHOULD only send a Date header field in messages that have an entity-body, like PUT and POST requests, and even then it's optional. A received message that doesn't have a Date header field SHOULD be assigned one by the recipient if that recipient is going to cache the message or gateway it through a protocol that requires a Date ๐
In theory, the date SHOULD represent the moment right before the entity is generated. In practice though, the date can be generated at any time during the message's origination without changing its semantic value โณ
The format of Date is an absolute date and time as defined by HTTP-date in section 3.3. It MUST be sent in RFC1123 [8]-date format ๐
14.20 ETag ๐ท๏ธ
The ETag entity-header field defines the entity tag for the associated entity. The headers used with entity tags are described in sections 14.20, 14.25, 14.26 and 14.43. You can use the entity tag to compare with other entities from the same resource (see section 13.3.2) ๐
ETag = "ETag" ":" entity-tag
Examples:
ETag: "xyzzy"
ETag: W/"xyzzy"
ETag: ""
14.21 Expires โฐ
The Expires entity-header field gives the date and time after which the response should be considered stale. A stale cache entry can't normally be returned by a cache (whether it's a proxy cache or a user agent cache) unless it's validated with the origin server first, or with an intermediate cache that has a fresh copy of the entity. See section 13.2 for more on the expiration model ๐
The presence of an Expires field doesn't mean the original resource will change or cease to exist at, before, or after that time ๐
The format is an absolute date and time as defined by HTTP-date in section 3.3. It MUST be in RFC1123-date format ๐
Expires = "Expires" ":" HTTP-date
An example:
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Note: if a response includes a Cache-Control field with the max-age directive, that directive overrides the Expires field.
HTTP/1.1 clients and caches MUST treat other invalid date formats, especially including the value "0", as being in the past (i.e., "already expired") ๐
To mark a response as "already expired," an origin server should use an Expires date that's equal to the Date header value. (Check the rules for expiration calculations in section 13.2.4 ๐งฎ)
To mark a response as "never expires," an origin server should use an Expires date about one year from the time the response is sent. HTTP/1.1 servers should not send Expires dates more than one year in the future ๐ฆ
If a response would otherwise be non-cacheable by default, but it has an Expires header with a date in the future, that means the response is cachable, unless a Cache-Control header field (section 14.9) says otherwise ๐ธ
14.22 From ๐ฌ
The From request-header field, if given, SHOULD contain an Internet e-mail address for the human user who controls the requesting user agent. The address SHOULD be machine-usable, as defined by mailbox in RFC 822 (as updated by RFC 1123 ) ๐
From = "From" ":" mailbox
An example:
From: webmaster@w3.org
This header field MAY be used for logging purposes and as a way to identify where invalid or unwanted requests are coming from. It SHOULD NOT be used as an insecure form of access protection ๐ The meaning of this field is that the request is being performed on behalf of the person listed, who takes responsibility for the method performed. Robot agents in particular SHOULD include this header, so the person running the robot can be contacted if something goes wrong on the receiving end ๐ค
The Internet e-mail address in this field MAY be separate from the Internet host that issued the request. For example, when a request goes through a proxy, the original issuer's address SHOULD be used ๐ง
Note: The client SHOULD not send the From header field without the user's approval, since it may conflict with the user's privacy interests or their site's security policy. It is strongly recommended that the user be able to disable, enable, and modify the value of this field at any time prior to a request. ๐ซฃ
14.23 Host ๐
The Host request-header field specifies the Internet host and port number of the resource being requested. It's taken from the original URL the user gave, or from the referring resource (usually an HTTP URL, as described in section 3.2.2) ๐บ๏ธ The Host field value MUST represent the network location of the origin server or gateway given by the original URL. This is what lets the origin server or gateway tell apart URLs that look the same internally, like the root "/" URL of a server hosting multiple host names on a single IP address ๐
Host = "Host" ":" host [ ":" port ] ; Section 3.2.2
A "host" with no trailing port information implies the default port for the service requested (for example, "80" for an HTTP URL). So a request on the origin server for <http://www.w3.org/pub/WWW/> MUST include:
GET /pub/WWW/ HTTP/1.1
Host: www.w3.org
A client MUST include a Host header field in all HTTP/1.1 request messages on the Internet (that is, any message corresponding to a request for a URL that includes an Internet host address for the service being requested) ๐ซถ If the Host field isn't already there, an HTTP/1.1 proxy MUST add a Host field to the request message before forwarding it on the Internet. All Internet-based HTTP/1.1 servers MUST respond with a 400 status code to any HTTP/1.1 request message that lacks a Host header field ๐จ
See sections 5.2 and 19.5.1 for other requirements relating to Host โจ
14.24 If-Modified-Since ๐ฐ๏ธ
okay so the If-Modified-Since request-header field is used with the GET method to make it conditional ๐ basically, if the requested variant hasn't been modified since the time in this field, the server won't send the entity back. Instead it sends a 304 (not modified) response with no message-body โจ
If-Modified-Since = "If-Modified-Since" ":" HTTP-date
an example of the field:
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
a GET with an If-Modified-Since header and no Range header asks for the identified entity to be transferred only if it's been modified since the date in If-Modified-Since ๐ the algorithm for figuring this out has these cases:
a) If the request would normally result in anything other than a 200 (OK) status, or if the passed If-Modified-Since date is invalid, the response is exactly the same as a normal GET. A date that's later than the server's current time is invalid ๐ โโ๏ธ
b) If the variant has been modified since the If-Modified-Since date, the response is exactly the same as a normal GET.
c) If the variant has not been modified since a valid If-Modified-Since date, the server MUST return a 304 (Not Modified) response.
the whole point of this feature is letting caches update efficiently with a minimum amount of transaction overhead ๐ฆ
Note that the Range request-header field modifies the meaning of If-Modified-Since; see section 14.36 for full details.
Note that If-Modified-Since times are interpreted by the server, whose clock may not be synchronized with the client. ๐ฐ๏ธ
Note that if a client uses an arbitrary date in the If-Modified-Since header instead of a date taken from the Last-Modified header for the same request, the client should be aware that this date is interpreted using the server's understanding of time ๐ง the client should also consider unsynchronized clocks and rounding problems caused by the different encodings of time between client and server. This includes the possibility of race conditions if the document has changed between the time it was first requested and the If-Modified-Since date of a later request, and the possibility of clock-skew-related problems if the If-Modified-Since date comes from the client's clock without correction to the server's clock. Corrections for different time bases between client and server are at best approximate due to network latency ๐ญ
14.25 If-Match ๐ฅ
the If-Match request-header field is used with a method to make it conditional. a client that has one or more entities previously obtained from the resource can check that one of those entities is still current by including a list of their associated entity tags in the If-Match header field ๐ the purpose of this feature is efficient updates of cached information with minimal transaction overhead. it's also used on updating requests to stop an accidental change to the wrong version of a resource ๐ as a special case, the value "*" matches any current entity of the resource.
If-Match = "If-Match" ":" ( "*" | 1#entity-tag )
if any of the entity tags match the entity tag of the entity that would have been returned in the response to a similar GET request (without the If-Match header) on that resource, or if "*" is given and any current entity exists for that resource, then the server MAY perform the requested method as if the If-Match header field did not exist ๐
a server MUST use the strong comparison function (see section 3.11) to compare the entity tags in If-Match.
if none of the entity tags match, or if "*" is given and no current entity exists, the server MUST NOT perform the requested method, and MUST return a 412 (Precondition Failed) response ๐ this is most useful when the client wants to stop an updating method, like PUT, from changing a resource that changed since the client last grabbed it.
if the request would, without the If-Match header field, result in anything other than a 2xx status, then the If-Match header MUST be ignored.
the meaning of "If-Match: *" is that the method SHOULD be performed if the representation selected by the origin server (or by a cache, possibly using the Vary mechanism, see section 14.43) exists, and MUST NOT be performed if the representation does not exist ๐
a request intended to update a resource (e.g., a PUT) MAY include an If-Match header field to signal that the request method MUST NOT be applied if the entity corresponding to the If-Match value (a single entity tag) is no longer a representation of that resource. this lets the user say they don't want the request to succeed if the resource has been changed without their knowledge ๐ซถ examples:
If-Match: "xyzzy"
If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-Match: *
14.26 If-None-Match ๐ธ
the If-None-Match request-header field is used with a method to make it conditional. a client that has one or more entities previously obtained from the resource can check that none of those entities is current by including a list of their associated entity tags in the If-None-Match header field โจ the purpose is the same as always: efficient updates of cached information with minimal transaction overhead. it's also used on updating requests to prevent an accidental change to a resource that wasn't known to exist ๐ง
as a special case, the value "*" matches any current entity of the resource.
If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag )
if any of the entity tags match the entity tag of the entity that would have been returned in the response to a similar GET request (without the If-None-Match header) on that resource, or if "*" is given and any current entity exists for that resource, then the server MUST NOT perform the requested method. instead, if the request method was GET or HEAD, the server SHOULD respond with a 304 (Not Modified) response, including the cache-related entity-header fields (particularly ETag) of one of the entities that matched. for all other request methods, the server MUST respond with a status of 412 (Precondition Failed) ๐
โโ๏ธ
see section 13.3.3 for the rules on how to determine if two entity tags match. the weak comparison function can only be used with GET or HEAD requests ๐ฆ
if none of the entity tags match, or if "*" is given and no current entity exists, then the server MAY perform the requested method as if the If-None-Match header field did not exist.
if the request would, without the If-None-Match header field, result in anything other than a 2xx status, then the If-None-Match header MUST be ignored.
the meaning of "If-None-Match: *" is that the method MUST NOT be performed if the representation selected by the origin server (or by a cache, possibly using the Vary mechanism, see section 14.43) exists, and SHOULD be performed if the representation does not exist. this feature may be useful in preventing races between PUT operations ๐โโ๏ธ
examples:
If-None-Match: "xyzzy"
If-None-Match: W/"xyzzy"
If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"
If-None-Match: *
14.27 If-Range ๐
okay so say a client has a partial copy of an entity in its cache and wants an up-to-date copy of the whole entity ๐ it could use the Range request-header with a conditional GET (using either or both of If-Unmodified-Since and If-Match). but if the condition fails because the entity was modified, the client would then have to make a second request to get the entire current entity-body. ugh, so much extra work ๐ฉ
the If-Range header lets a client "short-circuit" that second request โญ informally, its meaning is `if the entity is unchanged, send me the part(s) that I am missing; otherwise, send me the entire new entity.'
If-Range = "If-Range" ":" ( entity-tag | HTTP-date )
if the client has no entity tag for an entity, but does have a Last-Modified date, it may use that date in an If-Range header. (The server can distinguish between a valid HTTP-date and any form of entity-tag by examining no more than two characters.) the If-Range header should only be used together with a Range header, and must be ignored if the request does not include a Range header, or if the server does not support the sub-range operation ๐งฉ
if the entity tag given in the If-Range header matches the current entity tag for the entity, then the server should provide the specified sub-range of the entity using a 206 (Partial content) response ๐ if the entity tag does not match, then the server should return the entire entity using a 200 (OK) response.
14.28 If-Unmodified-Since ๐
the If-Unmodified-Since request-header field is used with a method to make it conditional. if the requested resource has not been modified since the time in this field, the server should perform the requested operation as if the If-Unmodified-Since header weren't there โจ
if the requested variant has been modified since the specified time, the server MUST NOT perform the requested operation, and MUST return a 412 (Precondition Failed) ๐ โโ๏ธ
If-Unmodified-Since = "If-Unmodified-Since" ":" HTTP-date
an example of the field:
If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
if the request would normally (i.e., without the If-Unmodified-Since header) result in anything other than a 2xx status, the If-Unmodified-Since header should be ignored.
if the specified date is invalid, the header is ignored ๐ซ
14.29 Last-Modified ๐
the Last-Modified entity-header field tells you the date and time when the origin server believes the variant was last modified ๐ฐ๏ธ
Last-Modified = "Last-Modified" ":" HTTP-date
an example of its use:
Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
what this header means depends on the implementation of the origin server and the nature of the original resource ๐ง for files, it might just be the file system last-modified time. for entities with dynamically included parts, it might be the most recent of the last-modify times for its component parts. for database gateways, it might be the last-update timestamp of the record. for virtual objects, it might be the last time the internal state changed ๐
an origin server MUST NOT send a Last-Modified date which is later than the server's time of message origination. in cases where the resource's last modification would point to some time in the future, the server MUST replace that date with the message origination date ๐
an origin server should get the Last-Modified value of the entity as close as possible to the time it generates the Date value of its response. this lets a recipient make an accurate assessment of the entity's modification time, especially if the entity changes near the time the response is generated ๐ฆ
HTTP/1.1 servers SHOULD send Last-Modified whenever feasible. ๐ธ
14.30 Location โจ
okay so the Location response-header field is how a server tells you to go somewhere other than the Request-URI ๐ฆ, either to finish your request or to find a brand new resource. for 201 (Created) responses, Location is the address of the new resource your request just made, which is so iconic ๐. for 3xx responses, the location SHOULD indicate the server's preferred URL for automatic redirection to the resource. the field value is one single absolute URL, no cap ๐
Location = "Location" ":" absoluteURI
an example is:
Location: http://www.w3.org/pub/WWW/People.html
๐ bestie, the Content-Location header field (section 14.15) is different from Location ๐ซถ. Content-Location identifies the original location of the entity enclosed in the request. so it's totally possible for a response to have header fields for both Location and Content-Location ๐. also see section 13.10 for cache requirements of some methods ๐ง
14.31 Max-Forwards ๐ง
the Max-Forwards request-header field can be used with the TRACE method (section 14.31) to limit how many proxies or gateways can forward the request to the next inbound server ๐ . this is so useful when a client is trying to trace a request chain that seems to be failing or looping mid-chain ๐ญ.
Max-Forwards = "Max-Forwards" ":" 1*DIGIT
the Max-Forwards value is a decimal integer showing how many more times this request message may be forwarded ๐.
every proxy or gateway that receives a TRACE request with a Max-Forwards header field SHOULD check and update its value before forwarding it ๐ฅ. if the received value is zero (0), the recipient SHOULD NOT forward the request. instead, it SHOULD respond as the final recipient with a 200 (OK) response containing the received request message as the response entity-body (as described in section 9.8) ๐. if the received Max-Forwards value is greater than zero, then the forwarded message SHOULD contain an updated Max-Forwards field with a value decremented by one (1) โจ.
the Max-Forwards header field SHOULD be ignored for all other methods defined by this specification, and for any extension methods where it isn't explicitly referred to as part of that method definition ๐.
14.32 Pragma ๐
the Pragma general-header field is used to include implementation-specific directives that may apply to any recipient along the request/response chain ๐ฆ. all pragma directives specify optional behavior from the viewpoint of the protocol, but some systems MAY require that behavior be consistent with the directives ๐.
Pragma = "Pragma" ":" 1#pragma-directive
pragma-directive = "no-cache" | extension-pragma
extension-pragma = token [ "=" ( token | quoted-string ) ]
when the no-cache directive is in a request message, an application SHOULD forward the request toward the origin server, even if it has a cached copy of what's being requested ๐ง. this pragma directive has the same semantics as the no-cache cache-directive (see section 14.9), and it's defined here for backwards compatibility with HTTP/1.0 ๐ฐ๏ธ. clients SHOULD include both header fields when a no-cache request is sent to a server that isn't known to be HTTP/1.1 compliant ๐.
pragma directives MUST be passed through by a proxy or gateway application, regardless of their significance to that application ๐ซถ, since the directives may be applicable to all recipients along the request/response chain. you can't specify a pragma for one specific recipient ๐ โโ๏ธ. however, any pragma directive that isn't relevant to a recipient SHOULD be ignored by that recipient ๐ธ.
HTTP/1.1 clients SHOULD NOT send the Pragma request-header ๐ซ. HTTP/1.1 caches SHOULD treat Pragma: no-cache as if the client had sent Cache-Control: no-cache โจ. no new Pragma directives will be defined in HTTP, so this one's kinda the final boss ๐.
14.33 Proxy-Authenticate ๐ธ
the Proxy-Authenticate response-header field MUST be included as part of a 407 (Proxy Authentication Required) response ๐. the field value is a challenge that shows the authentication scheme and parameters that apply to the proxy for this Request-URI ๐.
Proxy-Authenticate = "Proxy-Authenticate" ":" challenge
the HTTP access authentication process is described in section 11 ๐ง. unlike WWW-Authenticate, the Proxy-Authenticate header field only applies to the current connection, so it SHOULD NOT be passed on to downstream clients ๐ โโ๏ธ. the only exception is that an intermediate proxy might need its own credentials, so it asks the downstream client for them. in some circumstances that looks like the proxy is forwarding the Proxy-Authenticate header field, but it's really not ๐ญ.
14.34 Proxy-Authorization ๐
the Proxy-Authorization request-header field lets the client identify itself (or its user) to a proxy that requires authentication ๐ซถ. the field value is credentials holding the user agent's authentication info for the proxy and/or the realm of the resource being requested ๐ฆ.
Proxy-Authorization = "Proxy-Authorization" ":" credentials
the HTTP access authentication process is described in section 11 ๐ . unlike Authorization, the Proxy-Authorization header field only applies to the next outbound proxy that demanded authentication using the Proxy-Authenticate field ๐. when multiple proxies are chained together, the Proxy-Authorization header field gets consumed by the first outbound proxy that was expecting credentials ๐. a proxy MAY relay the credentials from the client request to the next proxy, if that's how the proxies cooperatively authenticate a given request ๐ค.
14.35 Public ๐
the Public response-header field lists the set of methods the server supports โจ. its whole purpose is to tell the recipient what the server can do regarding unusual methods ๐ง. the methods listed may or may not apply to the Request-URI, and the Allow header field (section 14.7) MAY be used to show which methods are allowed for a particular URI ๐.
Public = "Public" ":" 1#method
example of use:
Public: OPTIONS, MGET, MHEAD, GET, HEAD
this header field only applies to the server directly connected to the client, which is the nearest neighbor in a chain of connections ๐ซถ. if the response goes through a proxy, the proxy MUST either remove the Public header field or replace it with one that applies to its own capabilities ๐ฅ.
14.36 Range ๐
14.36.1 Byte Ranges ๐ฆ
since all HTTP entities are represented in HTTP messages as sequences of bytes, the concept of a byte range makes sense for any HTTP entity โจ. (however, not all clients and servers need to support byte-range operations ๐ .)
byte range specifications in HTTP apply to the sequence of bytes in the entity-body, which isn't necessarily the same as the message-body ๐ง.
a byte range operation can specify a single range of bytes, or a set of ranges within a single entity ๐ธ.
ranges-specifier = byte-ranges-specifier
byte-ranges-specifier = bytes-unit "=" byte-range-set
byte-range-set = 1#( byte-range-spec | suffix-byte-range-spec )
byte-range-spec = first-byte-pos "-" [last-byte-pos]
first-byte-pos = 1*DIGIT
last-byte-pos = 1*DIGIT
the first-byte-pos value in a byte-range-spec gives the byte-offset of the first byte in a range ๐. the last-byte-pos value gives the byte-offset of the last byte in the range, which means the byte positions specified are inclusive ๐. byte offsets start at zero ๐ง.
if the last-byte-pos value is present, it must be greater than or equal to the first-byte-pos in that byte-range-spec, or the byte-range-spec is invalid ๐ โโ๏ธ. the recipient of an invalid byte-range-spec must ignore it ๐๏ธ.
if the last-byte-pos value is absent, or if the value is greater than or equal to the current length of the entity-body, last-byte-pos is taken to be equal to one less than the current length of the entity-body in bytes ๐.
by choosing its last-byte-pos, a client can limit how many bytes it retrieves without knowing the size of the entity ๐ซถ.
suffix-byte-range-spec = "-" suffix-length
suffix-length = 1*DIGIT
a suffix-byte-range-spec specifies the suffix of the entity-body, with a length given by the suffix-length value ๐. (in other words, this form asks for the last N bytes of an entity-body.) if the entity is shorter than the specified suffix-length, the entire entity-body is used ๐ฆ.
examples of byte-ranges-specifier values (assuming an entity-body of length 10000):
- the first 500 bytes (byte offsets 0-499, inclusive):
bytes=0-499
- the second 500 bytes (byte offsets 500-999, inclusive):
bytes=500-999
- the final 500 bytes (byte offsets 9500-9999, inclusive):
bytes=-500
- or:
bytes=9500-
- the first and last bytes only (bytes 0 and 9999):
bytes=0-0,-1
- several legal but not canonical specifications of the second 500 bytes (byte offsets 500-999, inclusive):
bytes=500-600,601-999
bytes=500-700,601-999
14.36.2 Range Retrieval Requests ๐
HTTP retrieval requests using conditional or unconditional GET methods may ask for one or more sub-ranges of the entity, instead of the whole thing ๐ง. they do this with the Range request header, which applies to the entity returned as the result of the request ๐:
Range = "Range" ":" ranges-specifier
a server MAY ignore the Range header ๐. however, HTTP/1.1 origin servers and intermediate caches SHOULD support byte ranges when possible, since Range supports efficient recovery from partially failed transfers and efficient partial retrieval of large entities ๐ฅ.
if the server supports the Range header and the specified range or ranges are appropriate for the entity:
- the presence of a Range header in an unconditional GET changes what gets returned if the GET is otherwise successful. in other words, the response carries a status code of 206 (Partial Content) instead of 200 (OK) โจ.
- the presence of a Range header in a conditional GET (a request using one or both of If-Modified-Since and If-None-Match, or one or both of If-Unmodified-Since and If-Match) changes what gets returned if the GET is otherwise successful and the condition is true. it doesn't affect the 304 (Not Modified) response returned if the conditional is false ๐ธ.
in some cases, it may be more appropriate to use the If-Range header (see section 14.27) in addition to the Range header ๐ฆ.
if a proxy that supports ranges receives a Range request, forwards the request to an inbound server, and receives an entire entity in reply, it SHOULD only return the requested range to its client ๐ซถ. it SHOULD store the entire received response in its cache, if that's consistent with its cache allocation policies ๐ .
14.37 Referer โจ
okay bestie, so the Referer request-header field lets the client tell the server (for the server's benefit ๐ ) the address (URI) of the resource the Request-URI was obtained from. that's the "referrer" ๐ฆ yes the header is misspelled, and no we are not fixing it, it's iconic actually ๐ญ servers can use it to make lists of back-links for interest, logging, optimized caching, etc. ๐ธ it also helps trace obsolete or mistyped links for maintenance. the big rule is that the Referer field MUST NOT be sent if the Request-URI came from a source with no URI of its own, like input from the user's keyboard โจ๏ธ no URI, no referer, periodt ๐ โโ๏ธ
Referer = "Referer" ":" ( absoluteURI | relativeURI )
Example:
Referer: http://www.w3.org/hypertext/DataSources/Overview.html
so if the field value is a partial URI, it SHOULD be interpreted relative to the Request-URI ๐ง and the URI MUST NOT include a fragment โจ
Note: Because the source of a link may be private information or may reveal an otherwise private information source, it is strongly recommended that the user be able to select whether or not the Referer field is sent. For example, a browser client could have a toggle switch for browsing openly/anonymously, which would respectively enable/disable the sending of Referer and From information. ๐๐
14.38 Retry-After ๐
the Retry-After response-header field can be used with a 503 (Service Unavailable) response to say how long the service is expected to be unavailable to the requesting client โณ the value can be either an HTTP-date or an integer number of seconds (in decimal) after the time of the response. very organized, very mature ๐
Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds )
two examples of its use:
Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
Retry-After: 120
in the latter example, the delay is 2 minutes โฐ literally just wait 2 minutes bestie ๐ซถ
14.39 Server ๐
the Server response-header field contains info about the software the origin server used to handle the request ๐ the field can hold multiple product tokens (section 3.8) and comments that identify the server and any significant subproducts. the product tokens are listed in order of how significant they are for identifying the application, so the most important one goes first ๐
Server = "Server" ":" 1*( product | comment )
Example:
Server: CERN/3.0 libwww/2.17
if the response is being forwarded through a proxy, the proxy application MUST NOT modify the Server response-header ๐ โโ๏ธ instead, it SHOULD include a Via field (as described in section 14.44) ๐ฆ
Note: Revealing the specific software version of the server may allow the server machine to become more vulnerable to attacks against software that is known to contain security holes. Server implementers are encouraged to make this field a configurable option. ๐๐จ this one is serious bestie, don't just leave the version lying around for hackers to find ๐ญ
14.40 Transfer-Encoding ๐
the Transfer-Encoding general-header field tells you what (if any) kind of transformation has been applied to the message body so it can be sent safely between the sender and the recipient โจ this is different from Content-Encoding, because the transfer coding is a property of the message, not of the entity ๐
Transfer-Encoding = "Transfer-Encoding" ":" 1#transfer-
coding
transfer codings are defined in section 3.6 ๐ an example:
Transfer-Encoding: chunked
fair warning though: a lot of older HTTP/1.0 applications don't understand the Transfer-Encoding header ๐ญ
14.41 Upgrade ๐
the Upgrade general-header lets the client say which additional communication protocols it supports and would like to use, if the server finds it appropriate to switch protocols ๐ฆ the server MUST use the Upgrade header field within a 101 (Switching Protocols) response to show which protocol(s) are being switched to โจ
Upgrade = "Upgrade" ":" 1#product
for example:
Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
the Upgrade header field is meant to be a simple way to transition from HTTP/1.1 to some other, incompatible protocol ๐ธ the client advertises that it wants another protocol, like a later version of HTTP with a higher major version number, even though the current request is made using HTTP/1.1. so it starts the request in the more commonly supported protocol while telling the server it'd love a "better" protocol if one is available ๐ (where "better" is decided by the server, maybe based on the method and/or resource being requested) main character energy, honestly ๐
the Upgrade header field only applies to switching application-layer protocols on the existing transport-layer connection ๐ Upgrade can't be used to insist on a protocol change, since accepting and using it is optional for the server ๐ โโ๏ธ the capabilities and nature of the application-layer communication after the change depend entirely on the new protocol chosen, although the first action after changing protocols MUST be a response to the initial HTTP request containing the Upgrade header field ๐ซถ
the Upgrade header field only applies to the immediate connection. so the upgrade keyword MUST be supplied within a Connection header field (section 14.10) whenever Upgrade is present in an HTTP/1.1 message ๐
the Upgrade header field cannot be used to switch to a protocol on a different connection ๐ โโ๏ธ for that, it's more appropriate to use a 301, 302, 303, or 305 redirection response ๐ฆ
this spec only defines the protocol name "HTTP" for use by the family of Hypertext Transfer Protocols, as defined by the HTTP version rules of section 3.1 and future updates to this specification ๐ any token can be used as a protocol name, but it's only useful if both the client and server associate that name with the same protocol ๐ง
14.42 User-Agent ๐ธ
the User-Agent request-header field has info about the user agent that's sending the request ๐ it's for statistics, tracing protocol violations, and automatically recognizing user agents so responses can be tailored to avoid particular user agent limitations ๐ user agents SHOULD include this field with requests ๐ it can hold multiple product tokens (section 3.8) and comments identifying the agent and any subproducts that form a significant part of it. by convention, the product tokens are listed in order of significance for identifying the application ๐
User-Agent = "User-Agent" ":" 1*( product | comment )
Example:
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
14.43 Vary ๐ฆ
the Vary response-header field is how a server signals that the response entity was picked from the available representations using server-driven negotiation (section 12) ๐ง field-names listed in Vary headers are request-headers. the Vary value either says the listed header fields cover all the dimensions the representation might vary over, or that the dimensions are unspecified ("*"), which means they can vary over any aspect of future requests ๐
Vary = "Vary" ":" ( "*" | 1#field-name )
an HTTP/1.1 server MUST include an appropriate Vary header field with any cachable response that is subject to server-driven negotiation โจ doing so lets a cache correctly interpret future requests on that resource, and tells the user agent that negotiation is happening on it ๐ซถ a server SHOULD include an appropriate Vary header field with a non-cachable response that is subject to server-driven negotiation too, since it might give the user agent useful info about the dimensions the response could vary over ๐
the set of header fields named by the Vary value is known as the "selecting" request-headers ๐
when a cache gets a later request whose Request-URI matches one or more cache entries with a Vary header, the cache MUST NOT use that cache entry to build a response to the new request unless all of the headers named in the cached Vary header are present in the new request, and all the stored selecting request-headers from the previous request match the corresponding headers in the new request ๐ โโ๏ธ it's giving strict bouncer energy ๐ญ
the selecting request-headers from two requests match if and only if the ones in the first request can be turned into the ones in the second request by adding or removing linear whitespace (LWS) where the corresponding BNF allows it, and/or by combining multiple message-header fields with the same field name following the rules about message headers in section 4.2 ๐ธ
a Vary value of "*" means unspecified parameters play a role in picking the response representation, possibly other than the request-header contents (like the client's network address) ๐ later requests on that resource can only be properly interpreted by the origin server, so a cache MUST forward a (possibly conditional) request even when it has a fresh response cached for the resource ๐ง see section 13.6 for how caches use the Vary header ๐ฆ
a Vary value that's a list of field-names means the representation was chosen with a selection algorithm that considers ONLY the listed request-header field values ๐ a cache MAY assume the same selection will be made for future requests with the same values for those listed field names, for as long as the response is fresh โจ
the field-names given aren't limited to the standard request-header fields defined by this spec ๐ and field names are case-insensitive ๐
14.44 Via ๐ฆ
okay bestie, the Via general-header is how gateways and proxies MUST leave a trail of every middleman between the user agent and the server (on requests) and between the origin server and the client (on responses) ๐ต๏ธโโ๏ธ. It's basically the "Received" energy from RFC 822 โจ. The point is tracking where messages have been forwarded, avoiding request loops, and seeing what protocol capabilities every sender along the chain had ๐ .
Via = "Via" ":" 1#( received-protocol received-by [ comment ] )
received-protocol = [ protocol-name "/" ] protocol-version
protocol-name = token
protocol-version = token
received-by = ( host [ ":" port ] ) | pseudonym
pseudonym = token
The received-protocol tells you which protocol version the message arrived with at each hop ๐ธ. Every time a message gets forwarded, that version gets tacked onto the Via value, so the upstream capabilities stay visible to everyone downstream ๐.
The protocol-name is optional if and only if it would be "HTTP" ๐. The received-by field is usually the host (plus optional port) of the server or client that forwarded the message onward ๐. But if the real host is sensitive info, it MAY be swapped out for a pseudonym ๐ซถ. And if the port isn't given, it MAY be assumed to be the default port of the received-protocol ๐.
Multiple Via values represent each proxy or gateway that forwarded the message ๐ง. Each recipient MUST append its own info so the final list is in the exact order the messages were forwarded ๐.
Comments MAY be used in Via to identify the software of the recipient proxy or gateway, kind of like the User-Agent and Server headers ๐. BUT all comments in Via are optional and MAY be removed by any recipient before forwarding ๐.
Here's a cute example. A request goes from an HTTP/1.0 user agent to an internal proxy code-named "fred", which uses HTTP/1.1 to forward it to a public proxy at nowhere.com, which finishes the job by forwarding it to the origin server at www.ics.uci.edu. The request that www.ics.uci.edu receives would then have this Via header field:
Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
Proxies and gateways used as a portal through a network firewall SHOULD NOT, by default, forward the names and ports of hosts inside the firewall region ๐ฅ. That info SHOULD only get propagated if it's explicitly enabled ๐. If it's not enabled, the received-by host of any host behind the firewall SHOULD be replaced by an appropriate pseudonym for that host ๐.
For orgs with strong privacy needs about hiding their internal structure, a proxy MAY combine an ordered subsequence of Via entries that share identical received-protocol values into one entry โจ. For example, this:
Via: 1.0 ricky, 1.1 ethel, 1.1 fred, 1.0 lucy
could be collapsed to this:
Via: 1.0 ricky, 1.1 mertz, 1.0 lucy
Applications SHOULD NOT combine multiple entries unless they're all under the same organizational control AND the hosts have already been replaced by pseudonyms. Applications MUST NOT combine entries that have different received-protocol values. Don't get creative with this, bestie ๐ โโ๏ธ๐
14.45 Warning โ ๏ธ
The Warning response-header is extra info about a response's status that the status code doesn't show ๐. It's usually (not always) about a possible lack of semantic transparency from caching operations ๐ง.
Warning headers get sent with responses using this grammar:
Warning = "Warning" ":" 1#warning-value
warning-value = warn-code SP warn-agent SP warn-text
warn-code = 2DIGIT
warn-agent = ( host [ ":" port ] ) | pseudonym
; the name or pseudonym of the server adding
; the Warning header, for use in debugging
warn-text = quoted-string
A response may carry more than one Warning header ๐.
The warn-text should be in a natural language and character set that a human reading the response is most likely to understand ๐. You can base that on any info you have, like where the cache or user is, the Accept-Language field in a request, the Content-Language field in a response, etc. The default language is English and the default character set is ISO-8859-1 ๐ฌ๐ง.
If a character set other than ISO-8859-1 is used, it MUST be encoded in the warn-text using the method described in RFC 1522 [14] ๐ช.
Any server or cache can add Warning headers to a response. New ones should be added after any existing Warning headers ๐. A cache MUST NOT delete any Warning header it received with a response ๐ โโ๏ธ. BUT if a cache successfully validates a cache entry, it SHOULD remove any Warning headers previously attached to that entry, except as specified for specific Warning codes ๐งน. It MUST then add any Warning headers received in the validating response ๐ . In other words, Warning headers are the ones that would be attached to the most recent relevant response ๐.
When multiple Warning headers are attached to a response, the user agent SHOULD display as many as possible, in the order they appear in the response ๐ซง. If it's not possible to display all the warnings, the user agent should follow these heuristics:
- Warnings that appear early in the response take priority over those appearing later in the response.
- Warnings in the user's preferred character set take priority over warnings in other character sets, but only with identical warn-codes and warn-agents.
Systems that generate multiple Warning headers should order them with this user agent behavior in mind ๐ง .
This is the list of currently-defined warn-codes, each with a recommended warn-text in English and a description of what it means ๐:
- 10 Response is stale: MUST be included whenever the returned response is stale. A cache may add this warning to any response, but may never remove it until the response is known to be fresh. ๐ฅ
- 11 Revalidation failed: MUST be included if a cache returns a stale response because an attempt to revalidate the response failed, due to an inability to reach the server. A cache may add this warning to any response, but may never remove it until the response is successfully revalidated. ๐
- 12 Disconnected operation: SHOULD be included if the cache is intentionally disconnected from the rest of the network for a period of time. ๐ด
- 13 Heuristic expiration: MUST be included if the cache heuristically chose a freshness lifetime greater than 24 hours and the response's age is greater than 24 hours. โฐ
- 14 Transformation applied: MUST be added by an intermediate cache or proxy if it applies any transformation changing the content-coding (as specified in the Content-Encoding header) or media-type (as specified in the Content-Type header) of the response, unless this Warning code already appears in the response. MUST NOT be deleted from a response even after revalidation. ๐จ
- 99 Miscellaneous warning: The warning text may include arbitrary information to be presented to a human user, or logged. A system receiving this warning MUST NOT take any automated action. ๐คทโโ๏ธ
14.46 WWW-Authenticate ๐
The WWW-Authenticate response-header MUST be included in 401 (Unauthorized) response messages ๐ช. Its field value is at least one challenge that tells you which authentication scheme(s) and parameters apply to the Request-URI ๐๏ธ.
WWW-Authenticate = "WWW-Authenticate" ":" 1#challenge
The HTTP access authentication process is described in section 11 ๐. User agents MUST take special care when parsing the WWW-Authenticate field value if it has more than one challenge, or if more than one WWW-Authenticate header field is provided ๐ง. Why? Because a challenge can itself contain a comma-separated list of authentication parameters, so it gets messy fast ๐ญ.
15. Security Considerations ๐
this section is here to inform application developers, info providers, and users about the security limitations in HTTP/1.1 as described by this document ๐ก๏ธ. It does NOT have definitive solutions to the problems it reveals, though it does suggest some ways to reduce security risks ๐ซถ.
15.1 Authentication of Clients ๐ชช
ok bestie, real talk: the Basic authentication scheme is NOT a secure way to authenticate users ๐. It doesn't protect the entity either, which gets sent in clear text across whatever physical network is carrying it ๐ซ . HTTP doesn't stop you from adding extra authentication schemes and encryption to make things safer, or from adding enhancements (like one-time passwords) on top of Basic ๐ฅ.
The most serious flaw in Basic authentication is that it leads to the essentially clear text transmission of the user's password over the physical network ๐ฑ. That's the exact problem Digest Authentication is trying to fix ๐ฆ.
Because Basic authentication involves clear text transmission of passwords, it SHOULD never be used (without enhancements) to protect sensitive or valuable information ๐ซ.
Basic auth is also commonly used just for identification, like making users type a username and password so the server can gather accurate usage stats ๐. When it's used this way, it's super tempting to think there's no danger if illicit access to the protected docs isn't a big deal ๐. That's only correct if the server issues both the username and password to users, and in particular does NOT let users pick their own password ๐ โโ๏ธ. The danger is that naive users keep reusing one password to avoid juggling a bunch of them ๐.
If a server lets users choose their own passwords, the threat isn't just illicit access to documents on the server. It's illicit access to the accounts of every user who picked the same password for their account ๐ญ. If users get to choose their own password, the server also has to keep files containing the (presumably encrypted) passwords ๐๏ธ. Lots of these may be account passwords of users who are maybe at distant sites ๐. The owner or admin of a system like that could potentially be liable if that info isn't kept secure ๐ผโ๏ธ.
Basic Authentication is also vulnerable to spoofing by counterfeit servers ๐ป. If a user is led to believe they're connecting to a host with info protected by basic authentication, when they're actually connecting to a hostile server or gateway, the attacker can request a password, store it for later, and then fake an error ๐. This kind of attack is NOT possible with Digest Authentication [32] ๐ . Server implementers SHOULD guard against this sort of counterfeiting by gateways or CGI scripts ๐จ. In particular, it's very dangerous for a server to just hand a connection over to a gateway, because that gateway can then use the persistent connection mechanism to run multiple transactions with the client while impersonating the original server in a way the client can't detect ๐งโโ๏ธ๐
15.2 Offering a Choice of Authentication Schemes ๐
okay so a server is allowed to send multiple challenges with a 401 (Authenticate) response, and each challenge can use a different scheme ๐ the order they show up in is the order the server would prefer them to be picked. the server should put its "most secure" scheme first ๐ and the user agent should pick the first challenge it actually understands to show the user โจ
bestie, here's the twist ๐ when the server offers a bunch of schemes in the WWW-Authenticate header, the "security" of the whole thing is only as [...] a malicious user could capture the set of challenges and try to log in with the weakest scheme on the list ๐ so the ordering is really there to protect the user's credentials more than the server's info ๐ซถ
and then there's the sneaky MITM ๐ต๏ธโโ๏ธ attack where someone slips a weak scheme into the list, hoping the client picks one that exposes the user's credentials (ex. a password). so the client should always use the strongest scheme it understands from the choices it accepted ๐ช
it gets worse!! ๐ญ an even better MITM attack would be to remove every offered choice and insert a challenge asking for Basic authentication. user agents that care about this kind of attack could remember the strongest scheme a server ever requested, and show a warning that needs the user to confirm before they use a weaker one ๐ก๏ธ and the most iconic (in a terrible way) version of this attack is offering a "free" proxy caching service to gullible users ๐
15.3 Abuse of Server Log Information ๐
a server is literally in the position to save personal data about a user's requests, which can reveal their reading patterns or what they're interested in ๐ this info is super confidential, and the law in some countries might limit what can be done with it โ๏ธ people using HTTP to provide data are responsible for making sure that material isn't distributed without permission from anyone who can be identified in the published results ๐ซถ
15.4 Transfer of Sensitive Information ๐
HTTP is like any generic data transfer protocol, so it can't control what's inside the data it moves ๐
โโ๏ธ and there's no built-in way to tell how sensitive a piece of info is within a given request. so applications SHOULD give the info provider as much control over it as possible ๐ four header fields are worth special mention here: Server, Via, Referer and From ๐
first up, Server. revealing the exact software version can make the server machine more vulnerable to attacks on software with known security holes ๐ so implementers SHOULD make the Server header field a configurable option ๐
proxies that act as a portal through a network firewall SHOULD take special precautions with header info that identifies the hosts behind the firewall โจ in particular, they SHOULD remove, or replace with sanitized versions, any Via fields generated behind the firewall ๐ง
the Referer field lets people study reading patterns and draw reverse links ๐ it's super useful, but its power can be abused if user details aren't separated from the info in the Referer. even after personal info is removed, the Referer might still show a private document's URI, and publishing that would be inappropriate ๐ญ
the From field might clash with the user's privacy or their site's security policy, so it SHOULD NOT be sent unless the user can disable, enable, and modify its contents. the user MUST be able to set the contents of this field in a user preference or application defaults configuration ๐
we suggest (though we don't require it!) that a convenient toggle be provided so users can turn sending From and Referer info on or off ๐ธ
15.5 Attacks Based On File and Path Names ๐
implementations of HTTP origin servers SHOULD be careful to only return documents that the server administrators actually meant to be returned ๐ โโ๏ธ if an HTTP server translates HTTP URIs straight into file system calls, the server MUST take special care not to serve files that weren't meant for HTTP clients ๐ซ for example, UNIX, Microsoft Windows, and other OSes use ".." as a path component to mean one directory level up ๐ so on those systems, an HTTP server MUST disallow any such construct in the Request-URI if it would otherwise allow access to a resource outside what's meant to be reachable through the HTTP server ๐ค
files meant only for internal reference (like access control files, configuration files, and script code) MUST be protected from inappropriate retrieval, since they might have sensitive info ๐ and history backs this up: minor bugs in these server implementations have turned into real security risks ๐
15.6 Personal Information ๐ซฃ
HTTP clients are often holding huge amounts of personal info (ex. the user's name, location, mail address, passwords, encryption keys, etc.) ๐ณ so they SHOULD be very careful to stop this info from accidentally leaking over HTTP to other sources ๐ก๏ธ we very strongly recommend a convenient interface so the user can control where this info goes, and for designers and implementers to be extra careful here ๐ honestly, history shows that mistakes in this area are often serious security and/or privacy problems, and they tend to bring really bad press for the implementer's company ๐ฐ๐
15.7 Privacy Issues Connected to Accept Headers ๐
Accept request-headers can reveal info about the user to every server that gets accessed ๐ the Accept-Language header especially can reveal stuff the user would consider private, since knowing a language is often strongly linked to belonging to a particular ethnic group ๐ซถ user agents that let people configure what goes in Accept-Language on every request are strongly encouraged to include a message in that setup that makes the user aware of the privacy loss ๐จ
a way to limit the privacy loss is for the user agent to leave Accept-Language out by default, and only ask the user whether to start sending it to a server if it notices (by looking for Vary response-header fields the server generated) that sending it could improve the quality of service ๐ง
elaborate, user-customized accept header fields sent with every request, especially ones with quality values, can work as pretty reliable, long-lived user IDs ๐ those IDs let content providers do click-trail tracking, and let collaborating providers match click-trails or form submissions across servers ๐ฌ also, for lots of users not behind a proxy, the network address of the host running the user agent is also a long-lived user ID ๐ where proxies are used to boost privacy, user agents should be conservative about offering accept header config options to end users โจ as an extreme privacy move, proxies could filter the accept headers in relayed requests ๐ก๏ธ general purpose user agents with a high degree of header configurability should warn users about the privacy loss that can come with it โ ๏ธ
15.8 DNS Spoofing ๐ธ๏ธ
clients using HTTP rely heavily on the Domain Name Service, so they're generally open to security attacks based on deliberately messing up the mapping between IP addresses and DNS names ๐ต clients need to be cautious about assuming an IP number/DNS name association stays valid forever ๐
specifically, HTTP clients SHOULD rely on their name resolver to confirm an IP number/DNS name association, rather than caching the result of earlier host name lookups ๐ lots of platforms can already cache host name lookups locally when it makes sense, and they SHOULD be configured to do that ๐ these lookups should only be cached, though, when the TTL (Time To Live) info from the name server makes it likely the cached info will stay useful โณ
if HTTP clients cache host name lookup results to get a performance boost, they MUST observe the TTL info reported by DNS ๐ซถ
if clients don't follow this rule, they could get spoofed when a previously accessed server's IP address changes. network renumbering is expected to get more common, so this kind of attack will only grow ๐ following this requirement cuts down on that potential vulnerability ๐
this requirement also improves load-balancing for clients using replicated servers with the same DNS name, and makes it less likely that a user runs into failures accessing sites that use that strategy ๐ธ
15.9 Location Headers and Spoofing ๐
if one server supports multiple organizations that don't trust each other, it must check the values of Location and Content-Location headers in responses generated under the control of those organizations ๐ง that way, they can't try to invalidate resources they have no authority over ๐ซ๐
16. Acknowledgments ๐
Okay bestie, this spec leans SO hard on the augmented BNF and generic constructs David H. Crocker came up with for RFC 822 ๐ง And it also reuses a bunch of MIME definitions from Nathaniel Borenstein and Ned Freed. We're hoping that putting them here helps clear up the old confusion about how HTTP and Internet mail message formats relate ๐
HTTP has glowed up a LOT over the past four years ๐ Most of the credit goes to the huge, super active developer community, the many people who hung out on the www-talk mailing list. Honestly, that community is the reason HTTP and the World-Wide Web are such a massive success ๐ Marc Andreessen, Robert Cailliau, Daniel W. Connolly, Bob Denny, John Franks, Jean-Francois Groff, Phillip M. Hallam-Baker, Hakon W. Lie, Ari Luotonen, Rob McCool, Lou Montulli, Dave Raggett, Tony Sanders, and Marc VanHeyningen deserve a special shoutout for their work on the early parts of the protocol ๐ซถ
This document got SO much better thanks to everyone in the HTTP-WG who shared comments ๐ Besides the people already named, these folks also helped shape this specification:
Gary Adams Albert Lunde
Harald Tveit Alvestrand John C. Mallery
Keith Ball Jean-Philippe Martin-Flatin
Brian Behlendorf Larry Masinter
Paul Burchard Mitra
Maurizio Codogno David Morris
Mike Cowlishaw Gavin Nicol
Roman Czyborra Bill Perry
Michael A. Dolan Jeffrey Perry
David J. Fiander Scott Powers
Alan Freier Owen Rees
Marc Hedlund Luigi Rizzo
Greg Herlihy David Robinson
Koen Holtman Marc Salomon
Alex Hopmann Rich Salz
Bob Jernigan Allan M. Schiffman
Shel Kaphan Jim Seidman
Rohit Khare Chuck Shotton
John Klensin Eric W. Sink
Martijn Koster Simon E. Spero
Alexei Kosut Richard N. Taylor
David M. Kristol Robert S. Thau
Daniel LaLiberte Bill (BearHeart) Weinman
Ben Laurie Francois Yergeau
Paul J. Leach Mary Ellen Zurko
Daniel DuBois
The caching design owes a lot of its look and feel to ideas and feedback from Shel Kaphan, Paul Leach, Koen Holtman, David Morris, and Larry Masinter ๐
Most of the range specification is based on work Ari Luotonen and John Franks did originally, plus extra input from Steve Zilles โจ
Shoutout to the "cave men" of Palo Alto. You know who you are ๐ญ๐ฆ
Jim Gettys (the current editor of this document) especially wants to thank Roy Fielding, the previous editor, along with John Klensin, Jeff Mogul, Paul Leach, Dave Kristol, Koen Holtman, John Franks, Alex Hopmann, and Larry Masinter for their help ๐ธ
17. References ๐
[1] Alvestrand, H., "Tags for the identification of languages", RFC 1766, UNINETT, March 1995.
[2] Anklesaria, F., McCahill, M., Lindner, P., Johnson, D., Torrey, D., and B. Alberti. "The Internet Gopher Protocol: (a distributed document search and retrieval protocol)", RFC 1436, University of Minnesota, March 1993.
[3] Berners-Lee, T., "Universal Resource Identifiers in WWW", A Unifying Syntax for the Expression of Names and Addresses of Objects on the Network as used in the World-Wide Web", RFC 1630, CERN, June 1994.
[4] Berners-Lee, T., Masinter, L., and M. McCahill, "Uniform Resource Locators (URL)", RFC 1738, CERN, Xerox PARC, University of Minnesota, December 1994.
[5] Berners-Lee, T., and D. Connolly, "HyperText Markup Language Specification - 2.0", RFC 1866, MIT/LCS, November 1995.
[6] Berners-Lee, T., Fielding, R., and H. Frystyk, "Hypertext Transfer Protocol -- HTTP/1.0.", RFC 1945 MIT/LCS, UC Irvine, May 1996.
[7] Freed, N., and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC 2045, Innosoft, First Virtual, November 1996.
[8] Braden, R., "Requirements for Internet hosts - application and support", STD 3, RFC 1123, IETF, October 1989.
[9] Crocker, D., "Standard for the Format of ARPA Internet Text Messages", STD 11, RFC 822, UDEL, August 1982.
[10] Davis, F., Kahle, B., Morris, H., Salem, J., Shen, T., Wang, R., Sui, J., and M. Grinbaum. "WAIS Interface Protocol Prototype Functional Specification", (v1.5), Thinking Machines Corporation, April 1990.
[11] Fielding, R., "Relative Uniform Resource Locators", RFC 1808, UC Irvine, June 1995.
[12] Horton, M., and R. Adams. "Standard for interchange of USENET messages", RFC 1036, AT&T Bell Laboratories, Center for Seismic Studies, December 1987.
[13] Kantor, B., and P. Lapsley. "Network News Transfer Protocol." A Proposed Standard for the Stream-Based Transmission of News", RFC 977, UC San Diego, UC Berkeley, February 1986.
[14] Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text", RFC 2047, University of Tennessee, November 1996.
[15] Nebel, E., and L. Masinter. "Form-based File Upload in HTML", RFC 1867, Xerox Corporation, November 1995.
[16] Postel, J., "Simple Mail Transfer Protocol", STD 10, RFC 821, USC/ISI, August 1982.
[17] Postel, J., "Media Type Registration Procedure", RFC 2048, USC/ISI, November 1996.
[18] Postel, J., and J. Reynolds, "File Transfer Protocol (FTP)", STD 9, RFC 959, USC/ISI, October 1985.
[19] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2, RFC 1700, USC/ISI, October 1994.
[20] Sollins, K., and L. Masinter, "Functional Requirements for Uniform Resource Names", RFC 1737, MIT/LCS, Xerox Corporation, December 1994.
[21] US-ASCII. Coded Character Set - 7-Bit American Standard Code for Information Interchange. Standard ANSI X3.4-1986, ANSI, 1986.
[22] ISO-8859. International Standard -- Information Processing -- 8-bit Single-Byte Coded Graphic Character Sets --
Part 1: Latin alphabet No. 1, ISO 8859-1:1987.
Part 2: Latin alphabet No. 2, ISO 8859-2, 1987.
Part 3: Latin alphabet No. 3, ISO 8859-3, 1988.
Part 4: Latin alphabet No. 4, ISO 8859-4, 1988.
Part 5: Latin/Cyrillic alphabet, ISO 8859-5, 1988.
Part 6: Latin/Arabic alphabet, ISO 8859-6, 1987.
Part 7: Latin/Greek alphabet, ISO 8859-7, 1987.
Part 8: Latin/Hebrew alphabet, ISO 8859-8, 1988.
Part 9: Latin alphabet No. 5, ISO 8859-9, 1990.
[23] Meyers, J., and M. Rose "The Content-MD5 Header Field", RFC 1864, Carnegie Mellon, Dover Beach Consulting, October, 1995.
[24] Carpenter, B., and Y. Rekhter, "Renumbering Needs Work", RFC 1900, IAB, February 1996.
[25] Deutsch, P., "GZIP file format specification version 4.3." RFC 1952, Aladdin Enterprises, May 1996.
[26] Venkata N. Padmanabhan and Jeffrey C. Mogul. Improving HTTP Latency. Computer Networks and ISDN Systems, v. 28, pp. 25-35, Dec. 1995. Slightly revised version of paper in Proc. 2nd International WWW Conf. '94: Mosaic and the Web, Oct. 1994, which is available at http://www.ncsa.uiuc.edu/SDG/IT94/Proceedings/DDay/mogul/HTTPLatency.html.
[27] Joe Touch, John Heidemann, and Katia Obraczka, "Analysis of HTTP Performance", <URL: http://www.isi.edu/lsam/ib/http-perf/>, USC/Information Sciences Institute, June 1996
[28] Mills, D., "Network Time Protocol, Version 3, Specification, Implementation and Analysis", RFC 1305, University of Delaware, March 1992.
[29] Deutsch, P., "DEFLATE Compressed Data Format Specification version 1.3." RFC 1951, Aladdin Enterprises, May 1996.
[30] Spero, S., "Analysis of HTTP Performance Problems" <URL:http://sunsite.unc.edu/mdma-release/http-prob.html>.
[31] Deutsch, P., and J-L. Gailly, "ZLIB Compressed Data Format Specification version 3.3", RFC 1950, Aladdin Enterprises, Info-ZIP, May 1996.
[32] Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P., Luotonen, A., Sink, E., and L. Stewart, "An Extension to HTTP : Digest Access Authentication", RFC 2069, January 1997.
18. Authors' Addresses ๐
Roy T. Fielding
Department of Information and Computer Science
University of California
Irvine, CA 92717-3425, USA
Fax: +1 (714) 824-4056
EMail: fielding@ics.uci.edu
Jim Gettys
MIT Laboratory for Computer Science
545 Technology Square
Cambridge, MA 02139, USA
Fax: +1 (617) 258 8682
EMail: jg@w3.org
Jeffrey C. Mogul
Western Research Laboratory
Digital Equipment Corporation
250 University Avenue
Palo Alto, California, 94305, USA
EMail: mogul@wrl.dec.com
Henrik Frystyk Nielsen
W3 Consortium
MIT Laboratory for Computer Science
545 Technology Square
Cambridge, MA 02139, USA
Fax: +1 (617) 258 8682
EMail: frystyk@w3.org
Tim Berners-Lee
Director, W3 Consortium
MIT Laboratory for Computer Science
545 Technology Square
Cambridge, MA 02139, USA
Fax: +1 (617) 258 8682
EMail: timbl@w3.org
19. Appendices ๐
19.1. Internet Media Type message/http ๐
Besides defining HTTP/1.1, this document is also the spec for the Internet media type "message/http" ๐ฆ This is what gets registered with IANA:
Media Type name: message
Media subtype name: http
Required parameters: none
Optional parameters: version, msgtype
version: The HTTP-Version number of the enclosed message
(e.g., "1.1"). If not present, the version can be
determined from the first line of the body.
msgtype: The message type -- "request" or "response". If not
present, the type can be determined from the first
line of the body.
Encoding considerations: only "7bit", "8bit", or "binary" are
permitted
Security considerations: none
19.2. Internet Media Type multipart/byteranges ๐
When an HTTP message carries the content of several ranges (like a response to a request for multiple non-overlapping ranges), those ranges get sent as a multipart MIME message ๐ง The multipart media type for this is called "multipart/byteranges" โจ
The multipart/byteranges media type has two or more parts, and each one has its own Content-Type and Content-Range fields. The parts are split apart using a MIME boundary parameter ๐
Media Type name: multipart
Media subtype name: byteranges
Required parameters: boundary
Optional parameters: none
Encoding considerations: only "7bit", "8bit", or "binary" are
permitted
Security considerations: none
For example, it looks something like this ๐
HTTP/1.1 206 Partial content
Date: Wed, 15 Nov 1995 06:25:24 GMT
Last-modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-type: multipart/byteranges; boundary=THIS_STRING_SEPARATES
--THIS_STRING_SEPARATES
Content-type: application/pdf
Content-range: bytes 500-999/8000
...the first range...
--THIS_STRING_SEPARATES
Content-type: application/pdf
Content-range: bytes 7000-7999/8000
...the second range
--THIS_STRING_SEPARATES--
19.3 Tolerant Applications โจ
okay so, even though this doc spells out exactly what HTTP/1.1 messages have to look like when you make one, real-world apps aren't always perfect ๐ so the vibe is: be tolerant of little deviations, as long as the meaning is still totally clear ๐
Clients SHOULD be tolerant when parsing the Status-Line, and servers SHOULD be tolerant when parsing the Request-Line ๐ซถ Basically they SHOULD accept any amount of SP or HT characters between fields, even though only a single SP is really needed ๐
The line terminator for message-header fields is CRLF ๐ But applications parsing those headers are encouraged to treat a single LF as a line terminator too, and to ignore the leading CR ๐ธ
The character set of an entity-body should be labeled as the lowest common denominator of the character codes used inside that body ๐ฆ The one exception: no label is preferred over US-ASCII or ISO-8859-1 โจ
Now for dates, because dates are chaos ๐ญ Here are the extra rules for parsing and encoding them, plus a few other date gotchas:
- HTTP/1.1 clients and caches should assume that an
RFC-850date that looks more than 50 years in the future is actually in the past. This helps solve the "year 2000" problem ๐ - An HTTP/1.1 implementation may internally store a parsed
Expiresdate as earlier than the proper value, but it MUST NOT internally store a parsedExpiresdate as later than the proper value ๐ โโ๏ธ - All expiration-related calculations must be done in GMT. The local time zone MUST NOT influence the calculation or comparison of an age or expiration time ๐
- If an HTTP header carries a date with a time zone other than GMT, it must be converted into GMT using the most conservative possible conversion ๐ง
19.4 Differences Between HTTP Entities and MIME Entities ๐
okay bestie, so HTTP/1.1 borrows a bunch of stuff from Internet Mail (RFC 822) and MIME so entities can show up in a wide open variety of representations ๐ฆ But MIME is all about mail, and HTTP has some features that are different on purpose. Those differences were picked to make things faster over binary connections, give more freedom with new media types, make date comparisons easier, and also respect what early HTTP servers and clients were already doing ๐ MIME [7] is the original source for all this, btw โจ
This appendix lists the spots where HTTP and MIME don't match. Proxies and gateways that sit in front of strict MIME environments SHOULD know about these differences and do the right conversions ๐ง Proxies and gateways going the other direction, from MIME into HTTP, also need to know about them, since some conversions may be needed ๐ซถ
19.4.1 Conversion to Canonical Form ๐
MIME says an Internet mail entity has to be converted to canonical form before it gets sent ๐ฌ Section 3.7.1 of this document covers which forms are allowed for the subtypes of the "text" media type when they're sent over HTTP ๐ MIME wants "text" content to show line breaks as CRLF and doesn't allow CR or LF anywhere except in those line break sequences ๐ญ HTTP, on the other hand, lets CRLF, bare CR, and bare LF all mean a line break inside text content when a message travels over HTTP ๐ธ
Where it's possible, a proxy or gateway going from HTTP to a strict MIME environment SHOULD translate every line break inside the text media types from section 3.7.1 of this document into the MIME canonical form of CRLF ๐ฆ Heads up though, this can get messy when there's a Content-Encoding involved. It also gets messy because HTTP allows some character sets that don't use octets 13 and 10 to represent CR and LF, which is true for some multi-byte character sets ๐
19.4.2 Conversion of Date Formats ๐
HTTP/1.1 only uses a restricted set of date formats (section 3.3.1) so that comparing dates stays simple ๐ Proxies and gateways coming from other protocols SHOULD make sure any Date header field in a message matches one of the HTTP/1.1 formats, and rewrite the date if needed โจ
19.4.3 Introduction of Content-Encoding ๐ฅ
MIME doesn't have anything like HTTP/1.1's Content-Encoding header field ๐ณ Since it acts as a modifier on the media type, proxies and gateways going from HTTP to MIME-compliant protocols MUST either change the value of the Content-Type header field or decode the entity-body before forwarding the message. (Some experimental Internet mail apps used a media-type parameter of ;conversions=<content-coding> to do the same job as Content-Encoding, but that parameter isn't part of MIME ๐)
19.4.4 No Content-Transfer-Encoding ๐ซ
HTTP doesn't use the Content-Transfer-Encoding (CTE) field from MIME ๐
โโ๏ธ Proxies and gateways going from MIME-compliant protocols to HTTP MUST remove any non-identity CTE ("quoted-printable" or "base64") encoding before they hand the response message to an HTTP client ๐งผ
Proxies and gateways going from HTTP to MIME-compliant protocols are responsible for making sure the message is in the right format and encoding for "safe transport" on that protocol, where "safe transport" is defined by whatever limits the protocol has ๐ก๏ธ If labeling the data with an appropriate Content-Transfer-Encoding would make safe transport more likely over the destination protocol, that proxy or gateway SHOULD do it ๐ซถ
19.4.5 HTTP Header Fields in Multipart Body-Parts ๐
In MIME, most header fields in multipart body-parts get ignored unless the field name starts with "Content-" ๐ฅฑ In HTTP/1.1, multipart body-parts may contain any HTTP header fields that matter to the meaning of that part ๐
19.4.6 Introduction of Transfer-Encoding ๐
HTTP/1.1 brings in the Transfer-Encoding header field (section 14.40) ๐ Proxies/gateways MUST remove any transfer coding before forwarding a message through a MIME-compliant protocol ๐งน
Here's a pseudo-code way to think about decoding the "chunked" transfer coding (section 3.6), so you can picture the whole flow:
length := 0
read chunk-size, chunk-ext (if any) and CRLF
while (chunk-size > 0) {
read chunk-data and CRLF
append chunk-data to entity-body
length := length + chunk-size
read chunk-size and CRLF
}
read entity-header
while (entity-header not empty) {
append entity-header to existing header fields
read entity-header
}
Content-Length := length
Remove "chunked" from Transfer-Encoding
19.4.7 MIME-Version ๐งพ
HTTP isn't a MIME-compliant protocol (see appendix 19.4) ๐ But HTTP/1.1 messages may include a single MIME-Version general-header field to say which version of the MIME protocol was used to build the message ๐ Using the MIME-Version header field means the message is in full compliance with the MIME protocol. Proxies/gateways are responsible for making sure that compliance happens (where possible) when they export HTTP messages to strict MIME environments ๐ธ
MIME-Version = "MIME-Version" ":" 1*DIGIT "." 1*DIGIT
MIME version "1.0" is the default for use in HTTP/1.1 ๐ฆ That said, HTTP/1.1 message parsing and semantics are defined by this document, not by the MIME spec, so don't mix those up ๐ซถ
19.5 Changes from HTTP/1.0 ๐ฅ
okay so this section is the highlight reel of what changed between HTTP/1.0 and HTTP/1.1 ๐ It's a summary of the major differences, so you get the big picture before the details โจ
19.5.1 Changes to Simplify Multi-homed Web Servers and Conserve IP Addresses ๐
The requirements that clients and servers support the Host request-header, that an error gets reported if the Host request-header (section 14.23) is missing from an HTTP/1.1 request, and that absolute URIs (section 5.1.2) are accepted are among the most important changes in this spec ๐
Older HTTP/1.0 clients basically assumed one IP address per server ๐ There was no other established way to tell which server a request was meant for besides the IP address it was sent to ๐ญ These changes mean that, once older HTTP clients stop being common, the Internet can host multiple websites on a single IP address. That makes big operational Web servers way simpler, since giving one host a ton of IP addresses had caused serious problems ๐ง The Internet will also get back IP addresses that were only handed out so special-purpose domain names could show up in root-level HTTP URLs ๐ฆ With the Web growing so fast and so many servers already out there, it's super important that every HTTP implementation (including updates to existing HTTP/1.0 apps) gets these requirements right ๐
- Both clients and servers MUST support the
Hostrequest-header. Hostrequest-headers are required in HTTP/1.1 requests.- Servers MUST report a 400 (Bad Request) error if an HTTP/1.1 request does not include a
Hostrequest-header. - Servers MUST accept absolute URIs.
19.6 Additional Features โจ
this appendix documents protocol bits that some existing HTTP implementations use, but not consistently or correctly across most HTTP/1.1 apps ๐ Implementers should know about these features, but they can't count on them being there, or on working with other HTTP/1.1 apps ๐ฅฒ Some of them are proposed experimental features, and some are features that experimental deployments found lacking and that the base HTTP/1.1 spec now handles ๐
19.6.1 Additional Request Methods ๐
19.6.1.1 PATCH ๐ฉน
the PATCH method is kind of like PUT, except the entity holds a list of differences between the original version of the resource identified by the Request-URI and the version you want after the PATCH is applied ๐งฉ That list of differences is in a format defined by the media type of the entity (e.g., "application/diff"), and it MUST include enough information for the server to recreate the changes needed to turn the original version into the desired one ๐ ๏ธ
If the request goes through a cache and the Request-URI identifies an entity that's currently cached, that entity MUST be removed from the cache ๐งน Responses to this method are not cachable ๐ โโ๏ธ
What happens to the patched resource, and to its predecessor, is decided entirely by the origin server ๐ If the original version of the resource being patched had a Content-Version header field, the request entity MUST include a Derived-From header field matching the value of that original Content-Version header field ๐ Applications are encouraged to use these fields to build versioning relationships and to sort out version conflicts ๐
PATCH requests must obey the message transmission requirements set out in section 8.2 ๐ฌ
Caches that implement PATCH should invalidate cached responses as defined in section 13.10 for PUT ๐ซถ
19.6.1.2 LINK ๐
Okay bestie, LINK is the method that sets up one or more Link relationships between the existing resource named by the Request-URI and other existing resources. What makes it different from other methods that can create links is that LINK doesn't allow any message-body in the request, and it doesn't directly make brand new resources. It's all about connecting things that already exist ๐
If the request goes through a cache and the Request-URI points at a currently cached entity, that entity MUST be removed from the cache. Responses to this method are not cachable ๐
Caches that implement LINK should invalidate cached responses the way section 13.10 defines for PUT โจ
19.6.1.3 UNLINK ๐
UNLINK is the opposite energy: it removes one or more Link relationships from the existing resource named by the Request-URI. Those relationships might have been made with LINK, or with any other method that supports the Link header. Removing a link doesn't mean the resource is gone or can't be reached later on. The resource is still there, bestie, it just isn't linked up anymore ๐ฆ
If the request goes through a cache and the Request-URI points at a currently cached entity, that entity MUST be removed from the cache. Responses to this method are not cachable ๐
Caches that implement UNLINK should invalidate cached responses the way section 13.10 defines for PUT ๐ซถ
19.6.2 Additional Header Field Definitions ๐
19.6.2.1 Alternates ๐
Alternates is a response-header field that was proposed so the origin server can tell the client about other representations of the requested resource, along with what makes each one different. That gives the user agent a more reliable way to pick a different representation that fits what its user actually wants. This is the agent-driven negotiation that section 12 talks about, and it's giving very "I can choose for myself" ๐
Alternates is orthogonal to the Vary header field, which means both can show up in one message without messing with how the response or the available representations get read. Alternates is expected to be a big upgrade over the server-driven negotiation that Vary gives you for resources that vary along common dimensions like type and language โจ
The Alternates header field will be defined in a future specification ๐ฎ
19.6.2.2 Content-Version ๐ท๏ธ
Content-Version is an entity-header field that holds the version tag for one rendition of an evolving entity. Paired with Derived-From from section 19.6.2.3, it lets a group of people work on the same piece at the same time as an iterative process. This field should be used to let one work evolve down a single path, rather than making derived works or renditions in different representations ๐
Content-Version = "Content-Version" ":" quoted-string
Here are some examples of the Content-Version field:
Content-Version: "2.1.2"
Content-Version: "Fred 19950116-12:26:48"
Content-Version: "2.5a4-omega7"
19.6.2.3 Derived-From ๐งฌ
Derived-From is an entity-header field that can tell you which version tag the enclosed entity came from, before the sender modified it. It's there to help merge successive changes to a resource, especially when those changes are happening in parallel and from more than one source. Teamwork makes the dream work ๐ซถ
Derived-From = "Derived-From" ":" quoted-string
Here's an example of the field in action:
Derived-From: "2.1.1"
The Derived-From field is required for PUT and PATCH requests if the entity being sent was previously retrieved from the same URI and a Content-Version header was included with the entity when it was last retrieved ๐ฏ
19.6.2.4 Link ๐โจ
Link is an entity-header field that describes a relationship between two resources, usually between the requested resource and some other resource. An entity MAY include multiple Link values. Links at the metainformation level usually show things like hierarchy and navigation paths. Link is semantically equivalent to the <LINK> element in HTML.[5] Iconic crossover moment ๐ธ
Link = "Link" ":" #("<" URI ">" *( ";" link-param )
link-param = ( ( "rel" "=" relationship )
| ( "rev" "=" relationship )
| ( "title" "=" quoted-string )
| ( "anchor" "=" <"> URI <"> )
| ( link-extension ) )
link-extension = token [ "=" ( token | quoted-string ) ]
relationship = sgml-name
| ( <"> sgml-name *( SP sgml-name) <"> )
sgml-name = ALPHA *( ALPHA | DIGIT | "." | "-" )
Relationship values are case-insensitive and MAY be extended, as long as they stay within the constraints of the sgml-name syntax. The title parameter MAY be used to label the destination of a link so it can show up as identification in a human-readable menu. The anchor parameter MAY be used to point at a source anchor other than the entire current resource, like a fragment of this resource or a third resource ๐ฆ
Here are some examples of how it gets used:
Link: <http://www.cern.ch/TheBook/chapter2>; rel="Previous"
Link: <mailto:timbl@w3.org>; rev="Made"; title="Tim Berners-Lee"
The first example says that chapter2 comes before this resource in a logical navigation path. The second says that the person responsible for making the resource available is the one with the given e-mail address. Very organised, very cute ๐ง
19.6.2.5 URI ๐
The URI header field was used in earlier versions of this specification as a mashup of the existing Location, Content-Location, and Vary header fields, plus the future Alternates field (see above). Its main job was to carry a list of extra URIs for the resource, like names and mirror locations. But it became clear that cramming so many different jobs into one field made it really hard to implement any of them consistently and correctly ๐ Also, we think identifying names and mirror locations would be better handled by the Link header field. So the URI header field is deprecated in favor of those other fields. Bye bye, URI ๐
URI-header = "URI" ":" 1#( "<" URI ">" )
19.7 Compatibility with Previous Versions ๐ฐ๏ธ
Protocol specs can't really force anyone to stay compatible with older versions. That's beyond their scope. HTTP/1.1 was deliberately designed to make supporting previous versions easy though, and it's worth noting that when this specification was written, we'd expect commercial HTTP/1.1 servers to:
- recognize the format of the Request-Line for HTTP/0.9, 1.0, and 1.1 requests;
- understand any valid request in the format of HTTP/0.9, 1.0, or 1.1;
- respond appropriately with a message in the same major version used by the client.
And we'd expect HTTP/1.1 clients to:
- recognize the format of the Status-Line for HTTP/1.0 and 1.1 responses;
- understand any valid response in the format of HTTP/0.9, 1.0, or 1.1.
For most HTTP/1.0 implementations, the client establishes each connection before the request, and the server closes it after sending the response. A few implementations use the Keep-Alive version of persistent connections described in section 19.7.1.1 ๐
19.7.1 Compatibility with HTTP/1.0 Persistent Connections ๐
Some clients and servers may want to be compatible with certain older implementations of persistent connections in HTTP/1.0 clients and servers. Persistent connections in HTTP/1.0 must be explicitly negotiated, since they aren't the default behavior. The experimental HTTP/1.0 implementations of persistent connections were faulty, and HTTP/1.1's new facilities were designed to fix those problems ๐ง The trouble was that some existing 1.0 clients might send Keep-Alive to a proxy server that doesn't understand Connection. That proxy would then wrongly forward it to the next inbound server, which would set up the Keep-Alive connection, and the result would be an HTTP/1.0 proxy hung up waiting for the close on the response ๐ฑ So HTTP/1.0 clients must be prevented from using Keep-Alive when talking to proxies.
But talking to proxies is the most important use of persistent connections, so that prohibition is clearly unacceptable ๐ โโ๏ธ We need another mechanism for signaling that a persistent connection is wanted, and it has to be safe even when talking to an old proxy that ignores Connection. Persistent connections are the default for HTTP/1.1 messages, and we introduce a new keyword (Connection: close) for declaring non-persistence ๐
The following describes the original HTTP/1.0 form of persistent connections.
When it connects to an origin server, an HTTP client MAY send the Keep-Alive connection-token in addition to the Persist connection-token:
Connection: Keep-Alive
An HTTP/1.0 server would then respond with the Keep-Alive connection token, and the client may go ahead with an HTTP/1.0 (or Keep-Alive) persistent connection ๐
An HTTP/1.1 server may also set up persistent connections with HTTP/1.0 clients once it receives a Keep-Alive connection token. However, a persistent connection with an HTTP/1.0 client cannot use the chunked transfer-coding, so it MUST use a Content-Length to mark the ending boundary of each message ๐
A client MUST NOT send the Keep-Alive connection token to a proxy server, because HTTP/1.0 proxy servers don't follow the HTTP/1.1 rules for parsing the Connection header field ๐ซ
19.7.1.1 The Keep-Alive Header ๐ซง
When the Keep-Alive connection-token has been sent with a request or a response, a Keep-Alive header field MAY also be included. The Keep-Alive header field looks like this:
Keep-Alive-header = "Keep-Alive" ":" 0# keepalive-param
keepalive-param = param-name "=" value
The Keep-Alive header is optional, and it only gets used if a parameter is being sent. HTTP/1.1 doesn't define any parameters ๐ท
If the Keep-Alive header is sent, the corresponding connection token MUST be transmitted. The Keep-Alive header MUST be ignored if it's received without the connection token ๐ฅฐ
๐ฆ where this page comes from
- ietf: rfc2068 1997-01
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms