RFC 2616
Hypertext Transfer Protocol -- HTTP/1.1
Hypertext Transfer Protocol -- HTTP/1.1 ๐ฆ
okay bestie, this one is the big one ๐ RFC 2616 from June 1999, and it's a Standards Track doc, so it's the real deal, not a vibe-check draft ๐. It obsoletes RFC 2068 and it's basically the glow-up of that earlier version, aka an update to RFC 2068 [33] ๐ธ
The authors are a whole squad ๐ซถ: R. Fielding (UC Irvine), J. Gettys (Compaq/W3C), J. Mogul (Compaq), H. Frystyk (W3C/MIT), L. Masinter (Xerox), P. Leach (Microsoft), and T. Berners-Lee (W3C/MIT). Iconic lineup, no notes ๐ญโจ
Status of this Memo ๐
ok so this part is the paperwork, but it matters ๐. This document is an Internet standards track protocol for the Internet community, and it's basically asking everyone to talk about it and send ideas for making it better ๐ง. If you want to know where this protocol stands in the official standardization state, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐. And the memo is distributed with unlimited distribution, so anyone can read it ๐
Copyright Notice ยฉ๏ธ
Copyright (C) The Internet Society (1999). All Rights Reserved. Legally boring but very much real ๐
Abstract โจ
okay the main idea: the Hypertext Transfer Protocol (HTTP) is an application-level protocol for distributed, collaborative, hypermedia information systems ๐ It's a generic, stateless protocol, so it's giving flexible energy. It isn't only for hypertext either. You can stretch it to name servers and distributed object management systems by extending its request methods, error codes and headers [47] ๐ฅ
One of the iconic features is the typing and negotiation of data representation. That means systems can be built independently of the data being transferred, which is so smart and honestly kind of main-character ๐
HTTP has been used by the World-Wide Web global information initiative since 1990 ๐ This specification defines the protocol called "HTTP/1.1", and it's the update to RFC 2068 [33] ๐
Table of Contents ๐ง
more of the table of contents is coming up in the next part, so stay tuned, bestie ๐ฆ๐
๐ bestie, this part only has the section headings, because the body text for these sections wasn't in the original I was given. I've kept every heading, number, and name exactly as the table of contents lists them, so the text can slot in once you send the body.
1. Introduction โจ
1.1. Purpose
1.2. Requirements
1.3. Terminology
1.4. Overall Operation
2. Notational Conventions and Generic Grammar ๐
2.1. Augmented BNF
2.2. Basic Rules
3. Protocol Parameters ๐
3.1. HTTP Version
3.2. Uniform Resource Identifiers
3.2.1. General Syntax
3.2.2. http URL
3.2.3. URI Comparison
3.3. Date/Time Formats
3.3.1. Full Date
3.3.2. Delta Seconds
3.4. Character Sets
3.4.1. Missing Charset
3.5. Content Codings
3.6. Transfer Codings
3.6.1. Chunked Transfer Coding
3.7. Media Types
3.7.1. Canonicalization and Text Defaults
3.7.2. Multipart Types
3.8. Product Tokens
3.9. Quality Values
3.10. Language Tags
3.11. Entity Tags
3.12. Range Units
4. HTTP Message ๐
4.1. Message Types
4.2. Message Headers
4.3. Message Body
4.4. Message Length
4.5. General Header Fields
5. Request ๐ฆ
5.1. Request-Line
5.1.1. Method
5.1.2. Request-URI
5.2. The Resource Identified by a Request
5.3. Request Header Fields
6. Response ๐ธ
6.1. Status-Line
6.1.1. Status Code and Reason Phrase
6.2. Response Header Fields
7. Entity ๐ง
7.1. Entity Header Fields
7.2. Entity Body
7.2.1. Type
7.2.2. Entity Length
8. Connections ๐
8.1. Persistent Connections
8.1.1. Purpose
8.1.2. Overall Operation
8.1.3. Proxy Servers
8.1.4. Practical Considerations
8.2. Message Transmission Requirements
8.2.1. Persistent Connections and Flow Control
8.2.2. Monitoring Connections for Error Status Messages
8.2.3. Use of the 100 (Continue) Status
8.2.4. Client Behavior if Server Prematurely Closes Connection
9. Method Definitions ๐ ๏ธ
9.1. Safe and Idempotent Methods
9.1.1. Safe Methods
9.1.2. Idempotent Methods
9.2. OPTIONS
9.3. GET
9.4. HEAD
9.5. POST
9.6. PUT
9.7. DELETE
9.8. TRACE
9.9. CONNECT
10. Status Code Definitions ๐ฆ
10.1. Informational 1xx
10.1.1. 100 Continue
10.1.2. 101 Switching Protocols
10.2. Successful 2xx
10.2.1. 200 OK
10.2.2. 201 Created
10.2.3. 202 Accepted
10.2.4. 203 Non-Authoritative Information
10.2.5. 204 No Content
10.2.6. 205 Reset Content
10.2.7. 206 Partial Content
10.3. Redirection 3xx
10.3.1. 300 Multiple Choices
10.3.2. 301 Moved Permanently
10.3.3. 302 Found
10.3.4. 303 See Other
10.3.5. 304 Not Modified
10.3.6. 305 Use Proxy
10.3.7. 306 (Unused)
10.3.8. 307 Temporary Redirect
10.4. Client Error 4xx
10.4.1. 400 Bad Request
10.4.2. 401 Unauthorized
10.4.3. 402 Payment Required
10.4.4. 403 Forbidden
10.4.5. 404 Not Found
10.4.6. 405 Method Not Allowed
10.4.7. 406 Not Acceptable
10.4.8. 407 Proxy Authentication Required
10.4.9. 408 Request Timeout
10.4.10. 409 Conflict
10.4.11. 410 Gone
10.4.12. 411 Length Required
10.4.13. 412 Precondition Failed
10.4.14. 413 Request Entity Too Large
10.4.15. 414 Request-URI Too Long
10.4.16. 415 Unsupported Media Type
10.4.17. 416 Requested Range Not Satisfiable
10.4.18. 417 Expectation Failed
10.5. Server Error 5xx
10.5.1. 500 Internal Server Error
10.5.2. 501 Not Implemented
10.5.3. 502 Bad Gateway
10.5.4. 503 Service Unavailable
10.5.5. 504 Gateway Timeout
10.5.6. 505 HTTP Version Not Supported
11. Access Authentication ๐
12. Content Negotiation ๐
12.1. Server-driven Negotiation
12.2. Agent-driven Negotiation
12.3. Transparent Negotiation
13. Caching in HTTP ๐๏ธ
13.1.1. Cache Correctness
13.1.2. Warnings
13.1.3. Cache-control Mechanisms
13.1.4. Explicit User Agent Warnings
13.1.5. Exceptions to the Rules and Warnings
13.1.6. Client-controlled Behavior
13.2. Expiration Model
13.2.1. Server-Specified Expiration
13.2.2. Heuristic Expiration
13.2.3. Age Calculations
13.2.4. Expiration Calculations
13.2.5. Disambiguating Expiration Values
13.2.6. Disambiguating Multiple Responses
13.3. Validation Model
13.3.1. Last-Modified Dates
13.3.2. Entity Tag Cache Validators
13.3.3. Weak and Strong Validators
13.3.4. Rules for When to Use Entity Tags and Last-Modified Dates
13.3.5. Non-validating Conditionals
13.4. Response Cacheability
13.5. Constructing Responses From Caches
13.5.1. End-to-end and Hop-by-hop Headers
13.5.2. Non-modifiable Headers
13.5.3. Combining Headers
13.5.4. Combining Byte Ranges
13.6. Caching Negotiated Responses
13.7. Shared and Non-Shared Caches
13.8. Errors or Incomplete Response Cache Behavior
13.9. Side Effects of GET and HEAD
13.10. Invalidation After Updates or Deletions
13.11. Write-Through Mandatory
13.12. Cache Replacement
13.13. History Lists
14. Header Field Definitions ๐ฌ
14.1. Accept
14.2. Accept-Charset
14.3. Accept-Encoding
14.4 Accept-Language ............................................104
14.5 Accept-Ranges ..............................................105
14.6 Age ........................................................106
14.7 Allow ......................................................106
14.8 Authorization ..............................................107
14.9 Cache-Control ..............................................108
14.9.1 What is Cacheable .......................................109
14.9.2 What May be Stored by Caches ............................110
14.9.3 Modifications of the Basic Expiration Mechanism .........111
14.9.4 Cache Revalidation and Reload Controls ..................113
14.9.5 No-Transform Directive ..................................115
14.9.6 Cache Control Extensions ................................116
14.10 Connection ...............................................117
14.11 Content-Encoding .........................................118
14.12 Content-Language .........................................118
14.13 Content-Length ...........................................119
14.14 Content-Location .........................................120
14.15 Content-MD5 ..............................................121
14.16 Content-Range ............................................122
14.17 Content-Type .............................................124
14.18 Date .....................................................124
14.18.1 Clockless Origin Server Operation ......................125
14.19 ETag .....................................................126
14.20 Expect ...................................................126
14.21 Expires ..................................................127
14.22 From .....................................................128
14.23 Host .....................................................128
14.24 If-Match .................................................129
14.25 If-Modified-Since ........................................130
14.26 If-None-Match ............................................132
14.27 If-Range .................................................133
14.28 If-Unmodified-Since ......................................134
14.29 Last-Modified ............................................134
14.30 Location .................................................135
14.31 Max-Forwards .............................................136
14.32 Pragma ...................................................136
14.33 Proxy-Authenticate .......................................137
14.34 Proxy-Authorization ......................................137
14.35 Range ....................................................138
14.35.1 Byte Ranges ...........................................138
14.35.2 Range Retrieval Requests ..............................139
14.36 Referer ..................................................140
14.37 Retry-After ..............................................141
14.38 Server ...................................................141
14.39 TE .......................................................142
14.40 Trailer ..................................................143
14.41 Transfer-Encoding..........................................143
14.42 Upgrade ..................................................144
14.43 User-Agent ...............................................145
14.44 Vary .....................................................145
14.45 Via ......................................................146
14.46 Warning ..................................................148
14.47 WWW-Authenticate .........................................150
15 Security Considerations .......................................150
15.1 Personal Information....................................151
15.1.1 Abuse of Server Log Information .........................151
15.1.2 Transfer of Sensitive Information .......................151
15.1.3 Encoding Sensitive Information in URI's .................152
15.1.4 Privacy Issues Connected to Accept Headers ..............152
15.2 Attacks Based On File and Path Names .......................153
15.3 DNS Spoofing ...............................................154
15.4 Location Headers and Spoofing ..............................154
15.5 Content-Disposition Issues .................................154
15.6 Authentication Credentials and Idle Clients ................155
15.7 Proxies and Caching ........................................155
15.7.1 Denial of Service Attacks on Proxies....................156
16 Acknowledgments .............................................156
17 References ..................................................158
18 Authors' Addresses ..........................................162
19 Appendices ..................................................164
19.1 Internet Media Type message/http and application/http ......164
19.2 Internet Media Type multipart/byteranges ...................165
19.3 Tolerant Applications ......................................166
19.4 Differences Between HTTP Entities and RFC 2045 Entities ....167
19.4.1 MIME-Version ............................................167
19.4.2 Conversion to Canonical Form ............................167
19.4.3 Conversion of Date Formats ..............................168
19.4.4 Introduction of Content-Encoding ........................168
19.4.5 No Content-Transfer-Encoding ............................168
19.4.6 Introduction of Transfer-Encoding .......................169
19.4.7 MHTML and Line Length Limitations .......................169
19.5 Additional Features ........................................169
19.5.1 Content-Disposition .....................................170
19.6 Compatibility with Previous Versions .......................170
19.6.1 Changes from HTTP/1.0 ...................................171
19.6.2 Compatibility with HTTP/1.0 Persistent Connections ......172
19.6.3 Changes from RFC 2068 ...................................172
20 Index .......................................................175
21 Full Copyright Statement ....................................176
1. Introduction โจ
1.1. Purpose
okay so HTTP (the Hypertext Transfer Protocol) is an application-level protocol ๐ built for distributed, collaborative, hypermedia information systems. It's been in use by the World-Wide Web global information initiative since 1990, so it's literally been the backbone of the web for ages ๐๐ฆ. The very first version, called HTTP/0.9, was a simple protocol for raw data transfer across the Internet. Super basic, but it started the whole thing ๐ธ.
Then came HTTP/1.0, defined in RFC 1945 [6] ๐. It leveled up by letting messages look like MIME-like messages, which means they could carry metainformation about the data being transferred plus modifiers on the request/response semantics. Iconic glow-up โจ. BUT ngl, HTTP/1.0 didn't fully think about hierarchical proxies, caching, the need for persistent connections, or virtual hosts ๐. On top of that, a bunch of half-finished apps were calling themselves "HTTP/1.0" ๐, which meant a protocol version change was needed so two apps could figure out each other's true capabilities. Bestie, the drama is real ๐ญ.
So this specification defines the protocol known as "HTTP/1.1" ๐. It comes with more stringent requirements than HTTP/1.0 so that its features actually get implemented reliably. No more vibes-based implementations, we want receipts ๐ .
Real-world information systems need way more than simple retrieval. Think search, front-end update, and annotation ๐ฅ. HTTP lets you use an open-ended set of methods and headers that show the purpose of a request [47] ๐ง. It leans on the discipline of reference from the Uniform Resource Identifier (URI) [3], which can act as a location (URL) [4] or a name (URN) [20] to say which resource a method should be applied to ๐. Messages are passed in a format that's similar to Internet mail [9], as defined by the Multipurpose Internet Mail Extensions (MIME) [7] ๐.
HTTP is also used as a generic protocol for talking between user agents and proxies/gateways to other Internet systems ๐. That includes the SMTP [16], NNTP [13], FTP [18], Gopher [2], and WAIS [10] protocols. So HTTP gives you basic hypermedia access to resources from all kinds of diverse applications, which is so main character energy ๐ฆโจ.
1.2. Requirements
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [34] ๐. These are the official capitalised vibes, so pay attention to them ๐.
An implementation is not compliant if it fails to satisfy one or more of the MUST or REQUIRED level requirements for the protocols it implements ๐ซ. An implementation that satisfies all the MUST or REQUIRED level and all the SHOULD level requirements for its protocols is said to be "unconditionally compliant" ๐โจ. One that satisfies all the MUST level requirements but not all the SHOULD level requirements for its protocols is said to be "conditionally compliant." ๐ซถ Still valid, just not the full glam.
1.3 Terminology โจ
okay bestie, this part is basically the glossary ๐ the spec uses a bunch of terms for the roles everyone plays in HTTP communication, plus the stuff they're passing around. let's go ๐
connection ๐ A transport layer virtual circuit established between two programs for the purpose of communication.
message ๐ The basic unit of HTTP communication, consisting of 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, and resolutions) or vary in other ways. the main character of the whole spec, honestly ๐
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). even the error responses get a say, iykyk ๐
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 varriant'. 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 being performed by the program 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. so a program isn't stuck as one thing forever, it just depends on which connection we're talking about โจ
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. A "transparent proxy" is a proxy that does not modify the request or response beyond what is required for proxy authentication and identification. A "non-transparent proxy" is a proxy that modifies the request or response in order to provide some added service to the user agent, such as group annotation services, media type transformation, protocol reduction, or anonymity filtering. Except where either transparent or non-transparent behavior is explicitly stated, the HTTP proxy requirements apply to both types of proxies.
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 be aware that it is communicating with a gateway. sneaky, but make it make sense ๐ต๏ธโโ๏ธ
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 cacheable responses in order to reduce the 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.
cacheable ๐พ A response is cacheable if a cache is allowed to store a copy of the response message for use in answering subsequent requests. The rules for determining the cacheability of HTTP responses are defined in section 13. Even if a resource is cacheable, there may be additional constraints on whether a cache can use the cached copy for a particular request. "allowed to" is doing a lot of work here ๐ญ
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. still good, no cap โจ
stale ๐ฅ A response is stale if its age has passed its freshness lifetime. rip ๐
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. the cache is basically a ghost, but a fast one ๐ป
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.
upstream/downstream โฌ๏ธ Upstream and downstream describe the flow of a message: all messages flow from upstream to downstream.
inbound/outbound โฉ๏ธ Inbound and outbound refer to the request and response paths for messages: "inbound" means "traveling toward the origin server", and "outbound" means "traveling toward the user agent"
1.4 Overall Operation โจ
okay so HTTP is a request/response protocol ๐ A client sends a request to the server. The request has a request method, a URI, and a protocol version, then a MIME-like message with request modifiers, client info, and maybe a body ๐ The server answers with a status line that has its protocol version and a success or error code, then its own MIME-like message with server info, entity metainformation, and maybe entity-body content ๐ฆ The relationship between HTTP and MIME is described in appendix 19.4 ๐ธ
Most HTTP communication starts with a user agent asking for something to be applied to a resource on some origin server ๐ In the simplest case it's one single connection (v) between the user agent (UA) and the origin server (O) โจ
request chain ------------------------>
UA -------------------v------------------- O
<----------------------- response chain
it gets more interesting when there are one or more intermediaries in the chain ๐ There are three common kinds. A proxy is a forwarding agent ๐ง It gets requests for a URI in its absolute form, rewrites all or part of the message, then forwards the reformatted request toward the server the URI names. A gateway is a receiving agent that acts as a layer above some other server(s) and, if needed, 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 has to pass through an intermediary, like a firewall, even when that intermediary can't understand what's inside the messages ๐
request chain -------------------------------------->
UA -----v----- A -----v----- B -----v----- C -----v----- O
<------------------------------------- response chain
this diagram has three intermediaries (A, B, and C) between the user agent and origin server ๐ A request or response that travels the whole chain goes through four separate connections, and that distinction is a big deal ๐ญ Some HTTP options might only apply to the connection with the nearest, non-tunnel neighbor, some only to the end-points of the chain, and some to every connection along the chain ๐ฅ The diagram is linear, but everybody 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 same time it's handling A's request ๐
Any party in the communication that isn't acting as a tunnel may use an internal cache to handle requests โจ The cache effect is that the request/response chain gets shorter if one of the participants has a cached response that applies to that request ๐ฆ This shows the resulting chain if B has a cached copy of an earlier response from O (via C) for a request that UA or A hasn't cached ๐ซถ
request chain ---------->
UA -----v----- A -----v----- B - - - - - - C - - - - - O
<--------- response chain
not every response is worth caching, and some requests come with modifiers that put special demands on cache behavior ๐ HTTP requirements for cache behavior and cacheable responses are defined in section 13 ๐
there's a huge variety of cache and proxy setups being experimented with or deployed across the World Wide Web right now ๐ That includes national hierarchies of proxy caches to save transoceanic bandwidth, systems that broadcast or multicast cache entries, organizations that hand out subsets of cached data on CD-ROM, and so on ๐ฟ HTTP systems run in corporate intranets over high-bandwidth links, and also for access from PDAs with low-power radio links and on-and-off connectivity ๐ฑ The goal of HTTP/1.1 is to support all that existing diversity while adding protocol constructs for people building web applications who need high reliability and, when that isn't possible, at least reliable indications of failure ๐
HTTP usually runs over TCP/IP connections ๐ The default port is TCP 80 [19], but other ports can be used ๐ฆ That doesn't stop HTTP from being implemented on top of any other protocol on the Internet, or on other networks ๐ธ HTTP only assumes a reliable transport, so any protocol that gives 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 โจ
in HTTP/1.0, most implementations opened a new connection for each request/response exchange ๐ญ In HTTP/1.1, a connection can be used for one or more request/response exchanges, although connections may get closed for a variety of reasons (see section 8.1) ๐ฅ
2 Notational Conventions and Generic Grammar โจ
2.1 Augmented BNF โจ
okay this part is the notation, so you'll need to know it to read the rest ๐ค 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] ๐ The augmented BNF has these constructs ๐ง
name = definitionThe name of a rule is just the name itself (no enclosing "<" and ">"), and it's separated from its definition by the equal "=" character. White space only matters because indenting a continuation line shows that a rule definition spans more than one line. Certain basic rules are in uppercase, like SP, LWS, HT, CRLF, DIGIT, ALPHA, etc. Angle brackets are used inside definitions whenever their presence helps you tell which rule names are being used ๐"literal"Quotation marks surround literal text. Unless stated otherwise, the text is case-insensitive ๐ธrule1 | rule2Elements separated by a bar ("|") are alternatives, e.g.,"yes | no"will accept yes or no ๐ฆ(rule1 rule2)Elements enclosed in parentheses are treated as a single element. So"(elem (foo | bar) elem)"allows the token sequences"elem foo elem"and"elem bar elem"๐*ruleThe 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 element. The defaults 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 ruleSpecific repetition:"<n>(element)"is equivalent to"<n>*<n>(element)", which means exactly <n> occurrences of (element) ๐ So 2DIGIT is a 2-digit number, and 3ALPHA is a string of three alphabetic characters ๐ฅ#ruleA construct "#" is defined, similar to "*", for 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 white space (LWS) ๐ This makes the usual form of lists super easy. A rule like
( *LWS element *( *LWS "," *LWS element ))
can be written 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 it 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 defaults are 0 and infinity, so "#element" allows any number, including zero; "1#element" requires at least one; and "1#2element" allows one or two ๐
; commentA semi-colon, set off some distance to the right of rule text, starts a comment that runs to the end of the line ๐ง It's a simple way to put useful notes right next to the specs โจimplied *LWSThe grammar in this specification is word-based ๐ Except where noted otherwise, linear white space (LWS) can go between any two adjacent words (token or quoted-string), and between adjacent words and separators, without changing how a field is interpreted ๐ธ At least one delimiter (LWS and/or separators) MUST exist between any two tokens (for the definition of "token" below), because otherwise they'd be read as one single token ๐
2.2. Basic Rules โจ
Okay bestie, this is the vocab list everything else in the spec is built on ๐ค These are the basic parsing building blocks, and the US-ASCII character set they use 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)>
HTTP/1.1 defines CR LF as the end-of-line marker for all protocol elements except the entity-body (see appendix 19.3 for tolerant applications). The end-of-line marker within an entity-body is defined by its associated media type, as described in section 3.7. ๐ธ
CRLF = CR LF
HTTP/1.1 header field values can be folded onto multiple lines if the continuation line begins with a space or horizontal tab. All linear white space, including folding, has the same semantics as SP. A recipient MAY replace any linear white space with a single SP before interpreting the field value or forwarding the message downstream. ๐ฆ
LWS = [CRLF] 1*( SP | HT )
The TEXT rule is only used for descriptive field contents and values that are not intended to be interpreted by the message parser. Words of *TEXT MAY contain characters from character sets other than ISO-8859-1 [22] only when encoded according to the rules of RFC 2047 [14]. ๐ง
TEXT = <any OCTET except CTLs,
but including LWS>
A CRLF is allowed in the definition of TEXT only as part of a header field continuation. It is expected that the folding LWS will be replaced with a single SP before interpretation of the TEXT value.
Hexadecimal numeric characters are used in several protocol elements. ๐
HEX = "A" | "B" | "C" | "D" | "E" | "F"
| "a" | "b" | "c" | "d" | "e" | "f" | DIGIT
Many HTTP/1.1 header field values consist of words separated by LWS or special characters. These special characters MUST be in a quoted string to be used within a parameter value (as defined in section 3.6). ๐
token = 1*<any CHAR except CTLs or separators>
separators = "(" | ")" | "<" | ">" | "@"
| "," | ";" | ":" | "\" | <">
| "/" | "[" | "]" | "?" | "="
| "{" | "}" | SP | HT
Comments can be included in some HTTP header fields by surrounding the comment text with parentheses. Comments are only allowed in fields containing "comment" as part of their field value definition. In all other fields, parentheses are considered part of the field value. ๐
comment = "(" *( ctext | quoted-pair | comment ) ")"
ctext = <any TEXT excluding "(" and ")">
A string of text is parsed as a single word if it is quoted using double-quote marks. ๐ซถ
quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
qdtext = <any TEXT except <">>
The backslash character "\" MAY be used as a single-character quoting mechanism only within quoted-string and comment constructs. ๐ฅ
quoted-pair = "\" CHAR
3. Protocol Parameters โจ
3.1. HTTP Version ๐
HTTP uses a "<major>.<minor>" numbering scheme to indicate versions of the protocol. The versioning policy is there so the sender can show the format of a message and how much it can understand of further HTTP communication, rather than the features it gets from that communication. No change is made to the version number for the addition of message components which do not affect communication behavior or which only add to extensible field values. ๐ฆ
The <minor> number goes up when the protocol changes add features that don't change the general message parsing algorithm, but that may add to the message semantics and imply additional capabilities of the sender. The <major> number goes up when the format of a message within the protocol changes. See RFC 2145 [36] for a fuller explanation. ๐ธ
The version of an HTTP message is indicated by an HTTP-Version field in the first line of the message.
HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
Note that the major and minor numbers MUST be treated as separate integers and that each MAY be incremented higher than a single digit. Thus, HTTP/2.4 is a lower version than HTTP/2.13, which in turn is lower than HTTP/12.3. Leading zeros MUST be ignored by recipients and MUST NOT be sent. ๐
An application that sends a request or response message that includes HTTP-Version of "HTTP/1.1" MUST be at least conditionally compliant with this specification. Applications that are at least conditionally compliant with this specification SHOULD use an HTTP-Version of "HTTP/1.1" in their messages, and MUST do so for any message that is not compatible with HTTP/1.0. For more details on when to send specific HTTP-Version values, see RFC 2145 [36]. ๐
The HTTP version of an application is the highest HTTP version for which the application is at least conditionally compliant. โญ
Proxy and gateway applications need to be careful when forwarding messages in protocol versions different from that of the application. Since the protocol version indicates the protocol capability of the sender, a proxy/gateway MUST NOT send a message with a version indicator which is greater than its actual version. If a higher version request is received, the proxy/gateway MUST either downgrade the request version, or respond with an error, or switch to tunnel behavior. ๐
Due to interoperability problems with HTTP/1.0 proxies discovered since the publication of RFC 2068[33], caching proxies MUST, gateways MAY, and tunnels MUST NOT upgrade the request to the highest version they support. The proxy/gateway's response to that request MUST be in the same major version as the request. ๐
Note: Converting between versions of HTTP may involve modification of header fields required or forbidden by the versions involved.
3.2. Uniform Resource Identifiers ๐ฆ
URIs have been known by many names: WWW addresses, Universal Document Identifiers, Universal Resource Identifiers [3], and finally the combination of Uniform Resource Locators (URL) [4] and Names (URN) [20]. As far as HTTP is concerned, Uniform Resource Identifiers are simply formatted strings which identify (via name, location, or any other characteristic) a resource. ๐ง
3.2.1. General Syntax ๐
URIs in HTTP can be represented in absolute form or relative to some known base URI [11], depending upon the context of their use. The two forms are differentiated by the fact that absolute URIs always begin with a scheme name followed by a colon. For definitive information on URL syntax and semantics, see "Uniform Resource Identifiers (URI): Generic Syntax and Semantics," RFC 2396 [42] (which replaces RFCs 1738 [4] and RFC 1808 [11]). This specification adopts the definitions of "URI-reference", "absoluteURI", "relativeURI", "port", "host", "abs_path", "rel_path", and "authority" from that specification. ๐
The HTTP protocol does not place any a priori limit on the length of a URI. 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 ought to be cautious about depending on URI lengths above 255 bytes, because some older client or proxy implementations might not properly support these lengths.
3.2.2. http URL ๐ธ
The "http" scheme is used to locate network resources via the HTTP protocol. This section defines the scheme-specific syntax and semantics for http URLs. ๐
http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
If the port is empty or not given, port 80 is assumed. The semantics are that the identified resource is located at the server listening for TCP connections on that port of that host, and the Request-URI for the resource is abs_path (section 5.1.2). The use of IP addresses in URLs SHOULD be avoided whenever possible (see RFC 1900 [24]). If the abs_path is not present in the URL, it MUST be given as "/" when used as a Request-URI for a resource (section 5.1.2). If a proxy receives a host name which is not a fully qualified domain name, it MAY add its domain to the host name it received. If a proxy receives a fully qualified domain name, the proxy MUST NOT change the host name. ๐
3.2.3. URI Comparison ๐ฅ
When comparing two URIs to decide if they match or not, a client SHOULD use a case-sensitive octet-by-octet comparison of the entire URIs, with these exceptions:
- A port that is empty or not given is equivalent to the default port for that URI-reference;
- 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 other than those in the "reserved" and "unsafe" sets (see RFC 2396 [42]) are equivalent to their ""%" HEX HEX" encoding. ๐
For example, the following 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 so HTTP apps have historically let people write date/time stamps in three different formats ๐ฐ๏ธ ๐ญ
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 one is the fave โจ It's the preferred Internet standard, and it's a fixed-length subset of what RFC 1123 [8] defines (RFC 1123 is an update to RFC 822 [9]). The second one is super common in the wild, but it's built on the outdated RFC 850 [12] date format and it doesn't 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. See section 19.3 for further information. ๐
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. ๐ For the purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal Time). This is indicated in the first two formats by the inclusion of "GMT" as the three-letter abbreviation for time zone, and MUST be assumed when reading the asctime format. HTTP-date is case sensitive and MUST NOT include additional LWS beyond that specifically included as SP in the grammar. no extra spaces, we are being precise bestie ๐
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. so your logs can look however you want ๐ฆ
3.3.2. Delta Seconds
some HTTP header fields let you give a time value as a whole number of seconds (written in decimal) counted from the moment the message was received โฑ๏ธ โจ
delta-seconds = 1*DIGIT
3.4. Character Sets
HTTP uses the exact same definition of "character set" that MIME uses ๐ง Here's how the spec puts it:
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 encoding, 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
Although HTTP allows an arbitrary token to be used as a charset value, any token that has a predefined value within the IANA Character Set registry [19] MUST represent the character set defined by that registry. Applications SHOULD limit their use of character sets to those defined by the IANA registry. keep it in the lane, babe ๐ฃ๏ธ
Implementors should be aware of IETF character set requirements [38] [41]. ๐ซถ
3.4.1. Missing Charset
some HTTP/1.0 software read a Content-Type header with no charset parameter as "recipient should guess" ๐ Senders who want to defeat that behavior MAY include a charset parameter even when the charset is ISO-8859-1, and SHOULD do so when it is known that it will not confuse the recipient.
ngl, some older HTTP/1.0 clients didn't handle an explicit charset parameter properly either ๐ So HTTP/1.1 recipients MUST respect the charset label provided by the sender. And any user agents that have a provision to "guess" a charset MUST use the charset from the content-type field if they support that charset, rather than the recipient's preference, when initially displaying a document. See section 3.7.1. ๐
3.5. Content Codings
content coding values name an encoding transformation that has been applied (or could be applied) to an entity ๐ The whole point is to let a document get compressed or otherwise 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.11) header fields. Even though the value describes the content coding, 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. Initially, 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).deflate: The "zlib" format defined in RFC 1950 [31] in combination with the "deflate" compression mechanism described in RFC 1951 [29].identity: The default (identity) encoding; the use of no transformation whatsoever. This content-coding is used only in theAccept-Encodingheader, and SHOULD NOT be used in theContent-Encodingheader.
Quick heads-up on compress: using program names to identify encoding formats is not desirable, and it's 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.
New content-coding value tokens SHOULD be registered. To allow interoperability between clients and servers, the specifications of the content coding algorithms needed to implement a new value SHOULD be publicly available and adequate for independent implementation, and conform to the purpose of content coding defined in this section. the interop goals are literally everything ๐โจ
3.6. Transfer Codings
transfer-coding values are used to indicate an encoding transformation that has been, can be, or may need to be applied to an entity-body in order to ensure "safe transport" through the network ๐ This is different from a content coding, because the transfer-coding is a property of the message, not of the original entity. main character energy for the message ๐
transfer-coding = "chunked" | transfer-extension
transfer-extension = token *( ";" parameter )
Parameters are in the form of attribute/value pairs.
parameter = attribute "=" value
attribute = token
value = token | quoted-string
All transfer-coding values are case-insensitive. HTTP/1.1 uses transfer-coding values in the TE header field (section 14.39) and in the Transfer-Encoding header field (section 14.41).
Whenever a transfer-coding is applied to a message-body, the set of transfer-codings MUST include "chunked", unless the message is terminated by closing the connection. When the "chunked" transfer-coding is used, it MUST be the last transfer-coding applied to the message-body. The "chunked" transfer-coding MUST NOT be applied more than once to a message-body. These rules let the recipient figure out the transfer-length of the message (section 4.4). ๐งฉ
Transfer-codings are analogous to the Content-Transfer-Encoding values of MIME [7], which were designed to enable safe transport of binary data over a 7-bit transport service. However, "safe transport" means something different for an 8bit-clean transfer protocol. In HTTP, the only unsafe characteristic of message-bodies is the difficulty in determining the exact body length (section 7.2.2), or the desire to encrypt data over a shared transport. ๐
The Internet Assigned Numbers Authority (IANA) acts as a registry for transfer-coding value tokens. Initially, the registry contains the following tokens: "chunked" (section 3.6.1), "identity" (section 3.6.2), "gzip" (section 3.5), "compress" (section 3.5), and "deflate" (section 3.5).
New transfer-coding value tokens SHOULD be registered in the same way as new content-coding value tokens (section 3.5). ๐
A server which receives an entity-body with a transfer-coding it does not understand SHOULD return 501 (Unimplemented), and close the connection. A server MUST NOT send transfer-codings to an HTTP/1.0 client. ๐ซ๐
3.6.1 Chunked Transfer Coding
okay so chunked encoding is literally the best way to send a body in pieces ๐ each chunk gets its own size label, and you can add an OPTIONAL trailer full of entity-header fields at the end. It's perfect for stuff that gets made on the fly, because the receiver can still check that the whole message showed up โจ
Chunked-Body = *chunk
last-chunk
trailer
CRLF
chunk = chunk-size [ chunk-extension ] CRLF
chunk-data CRLF
chunk-size = 1*HEX
last-chunk = 1*("0") [ chunk-extension ] CRLF
chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)
trailer = *(entity-header CRLF)
So chunk-size is a string of hex digits that tells you how big the chunk is ๐ฆ The whole thing ends when you hit a chunk with size zero, then the trailer, and then an empty line to close it out ๐
The trailer lets the sender tack extra HTTP header fields onto the very end of the message ๐ธ The Trailer header field is how you say which header fields are sitting in the trailer (see section 14.40), so people know what to expect.
Now here's the rule that matters ๐ A server using chunked transfer-coding in a response MUST NOT put any header fields in the trailer unless at least one of these is true:
- a) the request had a TE header field that says "trailers" is acceptable in the transfer-coding of the response, as described in section 14.39; or,
- b) the server is the origin server for the response, the trailer fields are entirely optional metadata, and the recipient could still use the message (in a way the origin server is fine with) without getting that metadata. Basically, the origin server is cool with the trailer fields maybe getting silently dropped on the way to the client.
Why does this rule exist? ๐ฅบ It stops an interop disaster when an HTTP/1.1 (or later) proxy gets a message and forwards it to an HTTP/1.0 recipient. Without it, following the protocol could force the proxy to keep a possibly infinite buffer, and nobody wants that bestie ๐ญ
An example process for decoding a Chunked-Body is in appendix 19.4.6, so go peek at that if you want to see it in action ๐ง
Okay, the big one: all HTTP/1.1 applications MUST be able to receive and decode the "chunked" transfer-coding, and they MUST ignore any chunk-extension extensions they don't understand ๐ซถ no drama, just skip what you don't know, periodt ๐
3.7 Media Types
HTTP uses Internet Media Types [17] in the Content-Type (section 14.17) and Accept (section 14.1) header fields, and that's how it gets open, extensible data typing and type negotiation ๐
media-type = type "/" subtype *( ";" parameter )
type = token
subtype = token
Parameters MAY follow the type/subtype as attribute/value pairs (as defined in section 3.6) โจ
The type, subtype, and parameter attribute names are case-insensitive ๐ Parameter values might or might not be case-sensitive, depending on what the parameter name means. Linear white space (LWS) MUST NOT show up between the type and subtype, or between an attribute and its value ๐ โโ๏ธ Whether a parameter is there or not might matter for how a media-type gets processed, depending on how it's defined in the media type registry.
Heads up though: some older HTTP apps don't even recognize media type parameters ๐ So when you're sending data to those older apps, implementations SHOULD only use media type parameters when that type/subtype definition actually requires them.
Media-type values are registered with the Internet Assigned Number Authority (IANA [19]) ๐ The registration process is outlined in RFC 1590 [17]. Using non-registered media types is discouraged, so maybe don't ๐
3.7.1 Canonicalization and Text Defaults
Internet media types get registered with a canonical form ๐ An entity-body sent over HTTP MUST be in the right canonical form before it's transmitted, except for "text" types (more on that in the next paragraph).
When it's in canonical form, media subtypes of the "text" type use CRLF as the text line break ๐ HTTP relaxes this a bit and lets text media use plain CR or plain LF as a line break, but only if 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 where octets 13 and 10 don't mean CR and LF (which happens with some multi-byte character sets), HTTP lets you use whatever octet sequences that character set defines as the equivalent of CR and LF for line breaks โจ This flexibility only covers 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 is encoded with a content-coding, the underlying data MUST be in one of the forms above before it gets encoded ๐ธ
The "charset" parameter is used with some media types to say what character set the data is in ๐ When the sender doesn't give an explicit charset parameter, media subtypes of the "text" type default to a charset value of "ISO-8859-1" when they come in over HTTP. Data in character sets other than "ISO-8859-1" or its subsets MUST be labeled with an appropriate charset value ๐ท๏ธ Check section 3.4.1 for compatibility problems, because there are some.
3.7.2 Multipart Types
MIME has a bunch of "multipart" types ๐ง they're encapsulations of one or more entities packed into a single message-body. All multipart types share the same syntax, defined in section 5.1.1 of RFC 2046 [40], and they MUST include a boundary parameter as part of the media type value ๐ The message body is a protocol element itself, so it MUST use only CRLF for line breaks between body-parts ๐
Here's the twist: unlike in RFC 2046, the epilogue of any multipart message MUST be empty, and HTTP applications MUST NOT transmit the epilogue, even if the original multipart had one ๐ These rules keep the multipart message-body self-delimiting, which means the "end" of the body is marked by the ending multipart boundary โจ
Generally, HTTP treats a multipart message-body like any other media type, which is to say purely as payload ๐ The one exception is the "multipart/byteranges" type (appendix 19.2) when it shows up in a 206 (Partial Content) response. Some HTTP caching mechanisms will interpret that one, as described in sections 13.5.4 and 14.16 ๐ In every other case, an HTTP user agent SHOULD act the same as, or very similar to, a MIME user agent would when it gets a multipart type. The MIME header fields inside each body-part don't mean anything to HTTP beyond what their MIME semantics already say ๐
Again, an HTTP user agent SHOULD follow the same or similar behavior as a MIME user agent would upon receiving a multipart type ๐ฆ And if an application gets a multipart subtype it doesn't recognize, it MUST treat it as equivalent to "multipart/mixed" ๐ซถ
Note: The "multipart/form-data" type was specifically defined for carrying form data meant for processing via the POST request method, as described in RFC 1867 [15]. ๐
3.8 Product Tokens
Product tokens let apps say who they are by software name and version ๐ธ Most fields that use product tokens also let you list sub-products that make up a big part of the app, separated by white space. By convention, the products get listed in order of how much they matter for identifying the application ๐
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 ๐ They MUST NOT be used for advertising or other non-essential info, so no ads in your User-Agent, bestie ๐ โโ๏ธ Any token character MAY appear in a product-version, but this token SHOULD only be used for a version identifier. Basically, 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 various negotiable parameters are, aka their "weight" ๐ A weight gets normalized to a real number from 0 through 1, where 0 is the minimum and 1 is the maximum. If a parameter has a quality value of 0, then content with that parameter is `not acceptable' for the client ๐ โโ๏ธ HTTP/1.1 applications MUST NOT generate more than three digits after the decimal point ๐ฅ User configuration of these values SHOULD also be limited in that same way ๐ง
qvalue = ( "0" [ "." 0*3DIGIT ] )
| ( "1" [ "." 0*3("0") ] )
"Quality values" is kind of a misnomer, tbh ๐ These values really just represent 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 other humans ๐ธ Computer languages are explicitly excluded, sorry coders ๐ 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 one or more parts: a primary language tag, then a possibly empty series of subtags ๐ฆ
language-tag = primary-tag *( "-" subtag )
primary-tag = 1*8ALPHA
subtag = 1*8ALPHA
White space 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
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 are examples of tags that could be registered in the future ๐ )
3.11 Entity Tags ๐ท๏ธ
Okay bestie, entity tags are how we compare two or more entities that come from the same requested resource ๐
HTTP/1.1 uses them in the ETag (section 14.19), If-Match (section 14.24), If-None-Match (section 14.26), and If-Range (section 14.27) header fields. How they get used and compared as cache validators is covered in section 13.3.3. An entity tag is an opaque quoted string, and it can have a weakness indicator stuck on the front โจ
entity-tag = [ weak ] opaque-tag
weak = "W/"
opaque-tag = quoted-string
A "strong entity tag" MAY be shared by two entities of a resource, but only if they are equivalent by octet equality. Strong and exact, no cap ๐ฅ
A "weak entity tag," marked with the "W/" prefix, MAY be shared by two entities of a resource, but 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, so it's giving "close enough, not identical" ๐
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. Still, using the same entity tag value with entities from different URIs does not imply that those entities are equivalent. Don't assume a match just because the tags look the same ๐
3.12 Range Units ๐ธ
So this is the part where a client can ask for just a slice (a range) of the response entity instead of the whole thing ๐ HTTP/1.1 uses range units in the Range (section 14.35) and Content-Range (section 14.16) header fields. An entity can be split 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 that are specified using other units, so they don't have to care about those ๐ง
HTTP/1.1 was designed so that applications which don't depend on knowing about ranges can still be built and work just fine ๐ซถ
4 HTTP Message ๐
4.1 Message Types ๐ฌ
HTTP messages are made of requests going from client to server, and responses going from server to client. Simple ๐
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] to carry entities (the payload of the message) ๐ฆ Both kinds of message have a start-line, zero or more header fields (also called "headers"), an empty line (meaning a line with nothing before the CRLF) that marks the end of the header fields, and possibly a message-body.
generic-message = start-line
*(message-header CRLF)
CRLF
[ message-body ]
start-line = Request-Line | Status-Line
For robustness, servers SHOULD ignore any empty line(s) they get where a Request-Line is expected ๐ฅน In other words, if a server is reading the protocol stream at the start of a message and gets a CRLF first, it should just ignore that CRLF.
Some buggy HTTP/1.0 client implementations send extra CRLFs after a POST request ๐ญ To restate what the BNF already explicitly forbids: an HTTP/1.1 client MUST NOT preface or follow a request with an extra CRLF. No extra CRLFs, periodt ๐
4.2 Message Headers ๐
HTTP header fields are the general-header (section 4.5), request-header (section 5.3), response-header (section 6.2), and entity-header (section 7.1) fields ๐ง They all follow the same generic format as the one in Section 3.1 of RFC 822 [9]. Each header field is a name, then a colon (":"), then the field value. Field names are case-insensitive ๐ The field value MAY be preceded by any amount of LWS, although a single SP is preferred. Header fields can be extended over multiple lines by starting each extra line with at least one SP or HT. When you're generating HTTP constructs, applications ought to follow "common form" where one is known or indicated, because some implementations might fail to accept anything beyond the common forms ๐ซ
message-header = field-name ":" [ field-value ]
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, separators, and quoted-string>
The field-content doesn't include any leading or trailing LWS ๐ That's linear white space before the first non-whitespace character of the field-value, or after the last non-whitespace character of it. Such leading or trailing LWS MAY be removed without changing the semantics of the field value โจ Any LWS that appears between field-content MAY be replaced with a single SP before the field value is interpreted or the message is forwarded downstream.
The order of header fields with different field names doesn't matter ๐ However, it's "good practice" to send general-header fields first, then request-header or response-header fields, and to end with the entity-header fields ๐
Multiple message-header fields with the same field-name MAY be present in a message if and only if the entire field-value for that header field is defined as a comma-separated list (that is, #(values)) ๐งฉ It MUST be possible to combine the multiple header fields into one "field-name: field-value" pair, without changing the semantics of the message, by appending each later field-value to the first one, each separated by a comma. The order of header fields with the same field-name is therefore significant to how the combined field value is interpreted, so a proxy MUST NOT change the order of these field values when it forwards a message ๐ซ Order matters, bestie ๐
4.3 Message Body ๐ฐ
The message-body (if there is one) of an HTTP message carries the entity-body associated with the request or response ๐ The message-body only differs from the entity-body when a transfer-coding has been applied, as shown by the Transfer-Encoding header field (section 14.41).
message-body = entity-body
| <entity-body encoded as per Transfer-Encoding>
Transfer-Encoding MUST be used to indicate any transfer-codings an application has applied to make sure the message gets transferred safely and properly ๐ก๏ธ Transfer-Encoding is a property of the message, not of the entity, so ANY application along the request/response chain MAY add or remove it. (Section 3.6 does place restrictions on when certain transfer-codings may be used, so check that too ๐ค)
The rules for when a message-body is allowed in a message are different for requests and responses ๐
The presence of a message-body in a request is signaled by including a Content-Length or Transfer-Encoding header field in the request's message-headers ๐ฎ A message-body MUST NOT be included in a request if the specification of the request method (section 5.1.1) doesn't allow sending an entity-body in requests ๐ท A server SHOULD read and forward a message-body on any request. If the request method has no defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request.
For response messages, whether or not a message-body is included depends on both the request method and the response status code (section 6.1.1) ๐ญ All responses to the HEAD request method MUST NOT include a message-body, even though the presence of entity-header fields might make you think they should ๐ All 1xx (informational), 204 (no content), and 304 (not modified) responses MUST NOT include a message-body. Every other response does include a message-body, although it MAY be of zero length ๐ซง
4.4 Message Length ๐
The transfer-length of a message is the length of the message-body as it appears in the message, meaning after any transfer-codings have been applied ๐งฎ When a message-body is included with a message, the transfer-length of that body is determined by one of the following, listed in order of precedence:
- 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 terminated by the first empty line after the header fields, regardless of which entity-header fields are present in the message ๐
- If a Transfer-Encoding header field (section 14.41) is present and has any value other than "identity", then the transfer-length is defined by use of the "chunked" transfer-coding (section 3.6), unless the message is terminated by closing the connection ๐งธ
- If a Content-Length header field (section 14.13) is present, its decimal value in OCTETs represents both the entity-length and the transfer-length ๐ข The Content-Length header field MUST NOT be sent if these two lengths are different (that is, if a Transfer-Encoding header field is present). If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter MUST be ignored ๐ โโ๏ธ
- If the message uses the media type "multipart/byteranges", and the transfer-length is not otherwise specified, then this self-delimiting media type defines the transfer-length ๐งต This media type MUST NOT be used unless the sender knows that the recipient can parse it. The presence of a Range header with multiple byte-range specifiers in a request from a 1.1 client implies that the client can parse multipart/byteranges responses ๐ง
A Range header might be forwarded by a 1.0 proxy that doesn't understand multipart/byteranges. In that case, the server MUST delimit the message using the methods defined in items 1, 3, or 5 of this section ๐ฆ
- By the server closing the connection. (Closing the connection can't be used to mark the end of a request body, since that would leave no way for the server to send back a response ๐)
For compatibility with HTTP/1.0 applications, HTTP/1.1 requests containing 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 contains a message-body and no Content-Length is given, the server SHOULD respond with 400 (bad request) if it can't determine the length of the message, or with 411 (length required) if it wants to insist on receiving a valid Content-Length ๐ซ
All HTTP/1.1 applications that receive entities MUST accept the "chunked" transfer-coding (section 3.6), which lets this mechanism be used for messages whose length can't be determined in advance ๐ญ
Messages MUST NOT include both a Content-Length header field and a non-identity transfer-coding. If the message does include a non-identity transfer-coding, the Content-Length MUST be ignored ๐
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 ๐ฏ HTTP/1.1 user agents MUST notify the user when an invalid length is received and detected. So if the length is wrong, the user finds out, no cap ๐
4.5 General Header Fields ๐
okay so there are a few header fields that are relevant for BOTH requests and responses ๐ซถ but they don't describe the entity being transferred at all. they only apply to the message being sent right now โจ no cap, it's giving separate lane energy ๐ฆ
general-header = Cache-Control ; Section 14.9
| Connection ; Section 14.10
| Date ; Section 14.18
| Pragma ; Section 14.32
| Trailer ; Section 14.40
| Transfer-Encoding ; Section 14.41
| Upgrade ; Section 14.42
| Via ; Section 14.45
| Warning ; Section 14.46
general-header field names can only be extended reliably together with a change in the protocol version ๐ but, bestie, new or experimental header fields may be given the semantics of general header fields if every party in the conversation recognizes them as general header fields ๐ง and anything nobody recognizes gets treated as an entity-header field ๐
5 Request ๐ฎ
okay the request is the message a client sends to a server ๐ซถ and in its very first line it has to spill three things: the method to apply, the identifier of the resource, and the protocol version it's using ๐
Request = Request-Line ; Section 5.1
*(( general-header ; Section 4.5
| request-header ; Section 5.3
| entity-header ) CRLF) ; Section 7.1
CRLF
[ message-body ] ; Section 4.3
5.1 Request-Line ๐
the Request-Line starts with a method token, then the Request-URI, then the protocol version, and it ends with CRLF โจ everything is split up by SP characters, and no CR or LF is allowed anywhere except in that final CRLF sequence ๐
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
5.1.1 Method ๐ธ
the Method token tells the server what to do to the resource named in the Request-URI, and it is case-sensitive, so capitalisation matters, periodt ๐
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
| "CONNECT" ; Section 9.9
| extension-method
extension-method = token
the list of methods a resource allows can be spelled out in an Allow header field (section 14.7) ๐ and the status code in the response always tells the client whether a method is allowed on that resource right now, since the allowed set can change on the fly ๐ฆ an origin server SHOULD send back 405 (Method Not Allowed) when it knows the method but the requested resource doesn't allow it, and 501 (Not Implemented) when the method is unrecognized or the origin server just doesn't implement it ๐ญ GET and HEAD MUST be supported by every general-purpose server ๐ all the other methods are OPTIONAL ๐ but if the methods above are implemented, they MUST be implemented with the same semantics as the ones in section 9 ๐ฅ
5.1.2 Request-URI ๐ฆ
the Request-URI is a Uniform Resource Identifier (section 3.2) and it names the resource the request should be applied to ๐
Request-URI = "*" | absoluteURI | abs_path | authority
there are four options for the Request-URI and which one you get depends on what kind of request it is ๐ง the asterisk "*" means the request isn't about a particular resource, it's about the server itself, and it's only allowed when the method doesn't have to apply to a resource ๐ one example is
OPTIONS * HTTP/1.1
the absoluteURI form is REQUIRED when the request is going to a proxy ๐ซถ the proxy is asked to forward the request, or to serve it from a valid cache, and then return the response โจ the proxy MAY forward the request on to another proxy, or straight to the server named in the absoluteURI ๐ and 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 looks like this:
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 authority form is only used by the CONNECT method (section 9.9) ๐
now the most common form, which identifies a resource on an origin server or gateway ๐ here the absolute path of the URI MUST be sent (see section 3.2.1, abs_path) as the Request-URI, and the network location of the URI (the authority) MUST be sent in a Host header field โจ say a client wants that resource straight from the origin server, it opens a TCP connection to port 80 of the host "www.w3.org" and sends these lines:
GET /pub/WWW/TheProject.html HTTP/1.1
Host: www.w3.org
and then the rest of the request follows ๐ง the absolute path can't be empty, so if the original URI doesn't have one, it MUST be given as "/" (the server root) ๐
the Request-URI gets transmitted in the format from section 3.2.1 ๐ if it's encoded with the "% HEX HEX" encoding [42], the origin server MUST decode the Request-URI to properly interpret the request ๐ฅ servers SHOULD respond to invalid Request-URIs with a suitable status code ๐ญ
a transparent proxy MUST NOT rewrite the "abs_path" part of the Request-URI it receives when it forwards it to the next inbound server, except for the one exception above, where a null abs_path gets replaced 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 URI character for a reserved purpose. Implementors 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 ๐
the exact resource an Internet request identifies is worked out by looking at BOTH the Request-URI and the Host header field ๐ซถ
an origin server that doesn't let resources differ by the requested host MAY ignore the Host header field value when it works out which resource an HTTP/1.1 request is for ๐ธ (but check out section 19.6.1.1 for the other Host support requirements in HTTP/1.1 ๐)
an origin server that DOES tell resources apart by the host requested (you might hear these called virtual hosts or vanity host names โจ) MUST use the following rules to work out the requested resource on an HTTP/1.1 request ๐
- 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 attempt to use heuristics (for example, looking at the URI path for something unique to a particular host) to figure out exactly which resource is being requested ๐ง detective era ๐ต๏ธโโ๏ธ
5.3 Request Header Fields ๐
the request-header fields let the client pass along extra info about the request, and about the client itself, to the server ๐ they act as request modifiers, kinda like the parameters you'd 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
| Expect ; Section 14.20
| From ; Section 14.22
| Host ; Section 14.23
| If-Match ; Section 14.24
| If-Modified-Since ; 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.35
| Referer ; Section 14.36
| TE ; Section 14.39
| User-Agent ; Section 14.43
request-header field names can only be extended reliably together with a change in the protocol version ๐ however, new or experimental header fields MAY be given the semantics of request-header fields if every party in the communication recognizes them as request-header fields ๐ฆ and anything unrecognized gets treated as an entity-header field ๐
6 Response ๐
once a server has received and understood a request message, it replies with an HTTP response message ๐
Response = Status-Line ; Section 6.1
*(( general-header ; Section 4.5
| response-header ; Section 6.2
| entity-header ) CRLF) ; Section 7.1
CRLF
[ message-body ] ; Section 7.2
6.1 Status-Line ๐
the first line of a Response message is the Status-Line ๐ซถ it's made of the protocol version, then a numeric status code, then its textual phrase, with each part separated by SP characters โจ and again, 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 โจ
okay so 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 a short textual description of the Status-Code ๐ธ. the Status-Code is for automata (aka machines) and the Reason-Phrase is for the human user ๐ง, and the client is not required to examine or display the Reason-Phrase ๐ซถ.
the first digit of the Status-Code tells you the class of the response, and the last two digits don't do any categorizing at all ๐. there are 5 possible 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 ๐ญ
the individual values of the numeric status codes defined for HTTP/1.1 are listed below, along with an example set of matching Reason-Phrases ๐. the reason phrases are only recommendations, so they MAY be replaced by local equivalents without affecting the protocol ๐.
Status-Code =
"100" ; Section 10.1.1: Continue
| "101" ; Section 10.1.2: Switching Protocols
| "200" ; Section 10.2.1: OK
| "201" ; Section 10.2.2: Created
| "202" ; Section 10.2.3: Accepted
| "203" ; Section 10.2.4: Non-Authoritative Information
| "204" ; Section 10.2.5: No Content
| "205" ; Section 10.2.6: Reset Content
| "206" ; Section 10.2.7: Partial Content
| "300" ; Section 10.3.1: Multiple Choices
| "301" ; Section 10.3.2: Moved Permanently
| "302" ; Section 10.3.3: Found
| "303" ; Section 10.3.4: See Other
| "304" ; Section 10.3.5: Not Modified
| "305" ; Section 10.3.6: Use Proxy
| "307" ; Section 10.3.8: Temporary Redirect
| "400" ; Section 10.4.1: Bad Request
| "401" ; Section 10.4.2: Unauthorized
| "402" ; Section 10.4.3: Payment Required
| "403" ; Section 10.4.4: Forbidden
| "404" ; Section 10.4.5: Not Found
| "405" ; Section 10.4.6: Method Not Allowed
| "406" ; Section 10.4.7: Not Acceptable
| "407" ; Section 10.4.8: Proxy Authentication Required
| "408" ; Section 10.4.9: Request Time-out
| "409" ; Section 10.4.10: Conflict
| "410" ; Section 10.4.11: Gone
| "411" ; Section 10.4.12: Length Required
| "412" ; Section 10.4.13: Precondition Failed
| "413" ; Section 10.4.14: Request Entity Too Large
| "414" ; Section 10.4.15: Request-URI Too Large
| "415" ; Section 10.4.16: Unsupported Media Type
| "416" ; Section 10.4.17: Requested range not satisfiable
| "417" ; Section 10.4.18: Expectation Failed
| "500" ; Section 10.5.1: Internal Server Error
| "501" ; Section 10.5.2: Not Implemented
| "502" ; Section 10.5.3: Bad Gateway
| "503" ; Section 10.5.4: Service Unavailable
| "504" ; Section 10.5.5: Gateway Time-out
| "505" ; Section 10.5.6: HTTP Version not supported
| extension-code
extension-code = 3DIGIT
Reason-Phrase = *<TEXT, excluding CR, LF>
HTTP status codes are extensible ๐งฉ. HTTP applications are not required to understand the meaning of all registered status codes, though such understanding is obviously desirable ๐ค. however, applications MUST understand the class of any status code, as indicated by the first digit, and treat any unrecognized response as being equivalent to the x00 status code of that class ๐ฅ, with the exception that an unrecognized response MUST NOT be cached ๐. for example, if an unrecognized status code of 431 is received by the client, it can safely assume that there was something wrong with its request and treat the response as if it had received a 400 status code ๐
. in such cases, user agents SHOULD present to the user the entity returned with the response, since that entity is likely to include human-readable information which will explain the unusual status ๐ซถ.
6.2. Response Header Fields โจ
the response-header fields let the server pass along extra information about the response that can't fit in the Status-Line ๐. these header fields give information about the server and about further access to the resource identified by the Request-URI ๐ง.
response-header = Accept-Ranges ; Section 14.5
| Age ; Section 14.6
| ETag ; Section 14.19
| Location ; Section 14.30
| Proxy-Authenticate ; Section 14.33
| Retry-After ; Section 14.37
| Server ; Section 14.38
| Vary ; Section 14.44
| WWW-Authenticate ; Section 14.47
response-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 response-header fields if all parties in the communication recognize them to be response-header fields ๐. unrecognized header fields are treated as entity-header fields ๐ฆ.
7. Entity ๐ธ
Request and Response messages MAY transfer an entity if not otherwise restricted by the request method or response status code ๐ซถ. an entity is made up of entity-header fields and an entity-body, although some responses will only include the entity-headers ๐.
in this section, both sender and recipient refer to either the client or the server, depending on who sends and who receives the entity ๐ง.
7.1. Entity Header Fields ๐
entity-header fields define metainformation about the entity-body or, if no body is present, about the resource identified by the request ๐. some of this metainformation is OPTIONAL, and some might be REQUIRED by portions of this specification ๐.
entity-header = Allow ; Section 14.7
| Content-Encoding ; Section 14.11
| Content-Language ; Section 14.12
| Content-Length ; Section 14.13
| Content-Location ; Section 14.14
| Content-MD5 ; Section 14.15
| Content-Range ; Section 14.16
| Content-Type ; Section 14.17
| Expires ; Section 14.21
| Last-Modified ; Section 14.29
| extension-header
extension-header = message-header
the extension-header mechanism lets you define extra entity-header fields without changing the protocol, but those fields can't be assumed to be recognizable by the recipient ๐ฆ. unrecognized header fields SHOULD be ignored by the recipient and MUST be forwarded by transparent proxies ๐ฅ.
7.2. Entity Body ๐
the entity-body (if there is one) sent with an HTTP request or response is in a format and encoding defined by the entity-header fields โจ.
entity-body = *OCTET
an entity-body only shows up in a message when a message-body is present, as described in section 4.3 ๐งฉ. the entity-body is obtained from the message-body by decoding any Transfer-Encoding that might have been applied to keep the transfer safe and proper ๐ซถ.
7.2.1. Type ๐
when an entity-body comes along with a message, its data type is determined by the header fields Content-Type and Content-Encoding ๐. together they make a two-layer, ordered encoding model ๐ฅ:
entity-body := Content-Encoding( Content-Type( data ) )
Content-Type specifies the media type of the underlying data ๐. Content-Encoding can be used to indicate any additional content codings applied to the data, usually for compression, that are a property of the requested resource ๐ง. there is no default encoding ๐.
any HTTP/1.1 message containing an entity-body SHOULD include a Content-Type header field defining the media type of that body ๐
. if and only if the media type is not given by a Content-Type field, the recipient MAY attempt to guess the media type by inspecting its content and/or the name extension(s) of the URI used to identify the resource ๐. if the media type stays unknown, the recipient SHOULD treat it as type "application/octet-stream" ๐ธ.
7.2.2. Entity Length ๐ฆ
the entity-length of a message is the length of the message-body before any transfer-codings have been applied ๐ซถ. section 4.4 explains how the transfer-length of a message-body is determined ๐.
8. Connections ๐
8.1. Persistent Connections โจ
8.1.1. Purpose ๐ง
prior to persistent connections, a separate TCP connection was established to fetch each URL ๐ญ, which increased the load on HTTP servers and caused congestion on the Internet ๐. inline images and other associated data often mean a client has to make multiple requests to the same server in a short amount of time ๐. analysis of these performance problems and results from a prototype implementation are available [26] [30] ๐. implementation experience and measurements of actual HTTP/1.1 (RFC 2068) implementations show good results [39] ๐. alternatives have also been explored, for example, T/TCP [27] ๐ธ.
persistent HTTP connections have a number of advantages ๐ฅ:
- by opening and closing fewer TCP connections, CPU time is saved in routers and hosts (clients, servers, proxies, gateways, tunnels, or caches), and memory used for TCP protocol control blocks can be saved in hosts ๐ .
- 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 much more efficiently, with much lower elapsed time ๐ฆ.
- network congestion goes down by reducing the number of packets caused by TCP opens, and by giving TCP enough time to figure out the congestion state of the network ๐.
- latency on subsequent requests is reduced, since there's no time spent in TCP's connection opening handshake โญ.
- 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, but if they're talking to an older server, they retry with old semantics after an error is reported ๐งฉ.
HTTP implementations SHOULD implement persistent connections ๐.
8.1.2. Overall Operation ๐
a big difference between HTTP/1.1 and earlier versions of HTTP is that persistent connections are the default behavior of any HTTP connection ๐. that means, unless otherwise indicated, the client SHOULD assume that the server will maintain a persistent connection, even after error responses from the server ๐.
persistent connections give a client and a server a way to signal the close of a TCP connection ๐. this signaling happens using the Connection header field (section 14.10) ๐. once a close has been signaled, the client MUST NOT send any more requests on that connection ๐ .
8.1.2.1 Negotiation โจ
okay so an HTTP/1.1 server MAY assume that an HTTP/1.1 client wants to keep the connection persistent ๐ฆ, unless the request had a Connection header with the connection-token "close" in it ๐. 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 the connection to stay open ๐, but it decides whether to keep it open by checking if the server's response has a Connection header with the connection-token "close" in it. If the client doesn't want the connection to go on past 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.6.2 for more on backward compatibility with HTTP/1.0 clients ๐.
to stay persistent, all messages on the connection MUST have a self-defined message length (one not defined by closure of the connection) ๐, as described in section 4.4 ๐.
8.1.2.2 Pipelining ๐
a client that supports persistent connections MAY "pipeline" its requests, meaning it sends several 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 that first pipelined attempt fails ๐ญ. If a client does retry, it MUST NOT pipeline before 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 matching responses ๐.
clients SHOULD NOT pipeline requests using non-idempotent methods, or non-idempotent sequences of methods (see section 9.1.2) ๐ โโ๏ธ. Otherwise, a premature termination of the transport connection could lead to indeterminate results ๐ต. A client wishing to send a non-idempotent request SHOULD wait to send that request until it has received the response status for the previous request โณ.
8.1.3 Proxy Servers ๐
it is especially important that proxies correctly implement the properties of the Connection header field as specified in section 14.10 ๐
.
the proxy server MUST signal persistent connections separately with its clients and with the origin servers (or other proxy servers) that it connects to ๐ง. Each persistent connection applies to only one transport link ๐.
a proxy server MUST NOT establish an HTTP/1.1 persistent connection with an HTTP/1.0 client (but see RFC 2068 [33] for information and discussion of the problems with the Keep-Alive header implemented by many HTTP/1.0 clients) ๐.
8.1.4 Practical Considerations โฐ
servers will usually have some time-out value beyond which they stop maintaining an inactive connection ๐ฐ๏ธ. Proxy servers might make this a higher value, since the client is likely to be making more connections through the same server ๐ธ. Using persistent connections places no requirements on the length (or existence) of this time-out, for either the client or the server โจ.
when a client or server wishes to time out, it SHOULD issue a graceful close on the transport connection ๐ซถ. Clients and servers SHOULD both constantly watch for the other side of the transport close, and respond to it as appropriate ๐. If a client or server does not detect 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 might have started to send a new request at the same time that the server has decided to close the "idle" connection. From the server's point of view, the connection is being closed while it was idle, but from the client's point of view, a request is in progress ๐ณ.
this means clients, servers, and proxies MUST be able to recover from asynchronous close events ๐ช. Client software SHOULD reopen the transport connection and retransmit the aborted sequence of requests without user interaction, so long as the request sequence is idempotent (see section 9.1.2) ๐. Non-idempotent methods or sequences MUST NOT be automatically retried, although user agents MAY offer a human operator the choice of retrying the request(s) ๐โโ๏ธ. Confirmation by user-agent software with semantic understanding of the application MAY substitute for user confirmation ๐ค. The automatic retry SHOULD NOT be repeated if the second sequence of requests 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 the number of simultaneous connections that they maintain to a given server ๐. A single-user client SHOULD NOT maintain more than 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 are intended to improve HTTP response times and avoid congestion ๐ธ.
8.2 Message Transmission Requirements ๐
8.2.1 Persistent Connections and Flow Control ๐
HTTP/1.1 servers SHOULD maintain persistent connections and use TCP's flow control mechanisms to resolve temporary overloads, rather than terminating connections with the expectation that clients will retry ๐. The latter technique can make network congestion even worse ๐.
8.2.2 Monitoring Connections for Error Status Messages ๐
an HTTP/1.1 (or later) client sending a message-body SHOULD monitor the network connection for an error status while it is transmitting the request ๐ต๏ธโโ๏ธ. If the client sees an error status, it SHOULD immediately cease transmitting the body ๐. If the body is being sent using a "chunked" encoding (section 3.6), a zero length chunk and empty trailer 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 ๐.
8.2.3 Use of the 100 (Continue) Status ๐
the whole purpose of the 100 (Continue) status (see section 10.1.1) is to let a client that's sending a request message with a request body figure out whether the origin server is willing to accept the request (based on the request headers) before the client sends the request body ๐ซง. In some cases, it might be either inappropriate or highly inefficient for the client to send the body if the server will reject the message without looking at the body ๐.
Requirements for HTTP/1.1 clients:
- If a client will wait for a 100 (Continue) response before sending the request body, it MUST send an
Expectrequest-header field (section 14.20) with the "100-continue" expectation ๐. - A client MUST NOT send an
Expectrequest-header field (section 14.20) with the "100-continue" expectation if it does not intend to send a request body ๐ โโ๏ธ.
because of older implementations, the protocol allows ambiguous situations in which a client may send Expect: 100-continue without receiving either a 417 (Expectation Failed) status or a 100 (Continue) status ๐คทโโ๏ธ. Therefore, when a client sends this header field to an origin server (possibly via a proxy) from which it has never seen a 100 (Continue) status, the client SHOULD NOT wait for an indefinite period before sending the request body โณ.
Requirements for HTTP/1.1 origin servers:
- Upon receiving a request which includes an
Expectrequest-header field with the "100-continue" expectation, an origin server MUST either respond with 100 (Continue) status and continue to read from the input stream, or respond with a final status code. The origin server MUST NOT wait for the request body before sending the 100 (Continue) response. If it responds with a final status code, it MAY close the transport connection or it MAY continue to read and discard the rest of the request. It MUST NOT perform the requested method if it returns a final status code ๐. - An origin server SHOULD NOT send a 100 (Continue) response if the request message does not include an
Expectrequest-header field with the "100-continue" expectation, and MUST NOT send a 100 (Continue) response if such a request comes from an HTTP/1.0 (or earlier) client. There is an exception to this rule: for compatibility with RFC 2068, a server MAY send a 100 (Continue) status in response to an HTTP/1.1 PUT or POST request that does not include anExpectrequest-header field with the "100-continue" expectation. This exception, the purpose of which is to minimize any client processing delays associated with an undeclared wait for 100 (Continue) status, applies only to HTTP/1.1 requests, and not to requests with any other HTTP-version value ๐ง. - An origin server MAY omit a 100 (Continue) response if it has already received some or all of the request body for the corresponding request ๐.
- An origin server that sends a 100 (Continue) response MUST ultimately send a final status code, once the request body is received and processed, unless it terminates the transport connection prematurely ๐.
- If an origin server receives a request that does not include an
Expectrequest-header field with the "100-continue" expectation, the request includes a request body, and the server responds with a final status code before reading the entire request body from the transport connection, then the server SHOULD NOT close the transport connection until it has read the entire request, or until the client closes the connection. Otherwise, the client might not reliably receive the response message. However, this requirement is not be construed as preventing a server from defending itself against denial-of-service attacks, or from badly broken client implementations ๐ก๏ธ.
Requirements for HTTP/1.1 proxies:
- If a proxy receives a request that includes an
Expectrequest-header field with the "100-continue" expectation, and the proxy either knows that the next-hop server complies with HTTP/1.1 or higher, or does not know the HTTP version of the next-hop server, it MUST forward the request, including theExpectheader field ๐. - If the proxy knows that the version of the next-hop server is HTTP/1.0 or lower, it MUST NOT forward the request, and it MUST respond with a 417 (Expectation Failed) status ๐ โโ๏ธ.
- Proxies SHOULD maintain a cache recording the HTTP version numbers received from recently-referenced next-hop servers ๐๏ธ.
- A proxy MUST NOT forward a 100 (Continue) response if the request message was received from an HTTP/1.0 (or earlier) client and did not include an
Expectrequest-header field with the "100-continue" expectation. This requirement overrides the general rule for forwarding of 1xx responses (see section 10.1) ๐.
8.2.4. Client Behavior if Server Prematurely Closes Connection ๐๐
okay bestie, picture this: an HTTP/1.1 client sends a request with a body ๐ฆ, but it doesn't include an Expect header with the "100-continue" expectation ๐. The client also isn't directly connected to an HTTP/1.1 origin server. Then the connection gets slammed shut before the client hears a single status from the server ๐ญ. In that situation the client SHOULD retry the request. ๐
If the client does retry, it MAY use this "binary exponential backoff" algorithm to make sure it gets a reliable response โจ:
- Open a new connection to the server ๐
- Send the request-headers
- Set a variable R to the estimated round-trip time to the server (e.g., based on how long it took to establish the connection), or to a constant value of 5 seconds if the round-trip time isn't available โฑ๏ธ
- Compute
T = R * (2**N), where N is the number of previous retries of this request ๐งฎ - Wait for either an error response from the server or for T seconds, whichever comes first ๐
- If no error response arrives, send the body of the request once T seconds have passed ๐ค
- If the client sees the connection closed prematurely again, repeat from step 1 until the request is accepted, an error response is received, or the user gets impatient and ends the retry process ๐ค
If at any point an error status is received, the client: - SHOULD NOT continue, and - SHOULD close the connection if it has not completed sending the request message.
9. Method Definitions ๐
Here's the squad of common methods for HTTP/1.1 ๐. The set can be expanded, but you can't assume that additional methods share the same semantics across 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 ๐ก๏ธ
Implementors need to remember that the software is representing the user when they interact over the Internet ๐งโโ๏ธ. So be careful to let the user know about any action that might have an unexpected significance to them or to others ๐.
The convention is that GET and HEAD SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe" ๐ซง. That way user agents can show other methods, like POST, PUT and DELETE, in a special way, so the user knows a possibly unsafe action is being requested ๐ฉ.
Obviously, nobody can guarantee the server won't generate side-effects while handling a GET request. Some dynamic resources actually consider that a feature โจ. The important distinction is that the user didn't ask for those side-effects, so the user can't be held accountable for them ๐.
9.1.2. Idempotent Methods ๐
Methods can also be "idempotent" ๐ . Aside from error or expiration issues, the side-effects of N > 0 identical requests are the same as for a single request. GET, HEAD, PUT and DELETE all share this property. The methods OPTIONS and TRACE SHOULD NOT have side effects, so they're inherently idempotent ๐ธ.
Here's the twist ๐: a sequence of several requests can still be non-idempotent, even if every method in that sequence is idempotent. (A sequence is idempotent if a single execution of the entire sequence always yields a result that isn't changed by re-executing all, or part, of that sequence.) For example, a sequence is non-idempotent if its result depends on a value that gets modified later in the same sequence ๐ญ.
A sequence that never has side effects is idempotent by definition, provided that no concurrent operations are running on the same set of resources ๐ง.
9.2. OPTIONS ๐
The OPTIONS method is a request for information about the communication options available on the request/response chain identified by the Request-URI. It lets the client figure out the options and/or requirements for a resource, or a server's capabilities, without implying a resource action or starting a resource retrieval ๐ต๏ธโโ๏ธ.
Responses to this method are not cacheable. ๐ซ
If the OPTIONS request includes an entity-body (shown by the presence of Content-Length or Transfer-Encoding), the media type MUST be indicated by a Content-Type field ๐ฆ. This specification doesn't define any use for such a body, but future extensions to HTTP might use it to make more detailed queries on the server ๐ฎ. A server that doesn't support such an extension MAY discard the request body ๐๏ธ.
If the Request-URI is an asterisk (""), the OPTIONS request is meant for the server in general, not one specific resource ๐. Since a server's communication options usually depend on the resource, the "" request is only useful as a "ping" or "no-op" type of method ๐. It does nothing beyond letting the client test the server's capabilities. For example, it can test a proxy for HTTP/1.1 compliance (or lack thereof) ๐งช.
If the Request-URI is not an asterisk, the OPTIONS request applies only to the options available when communicating with that resource ๐ฏ.
A 200 response SHOULD include any header fields that indicate optional features the server implements and that apply to that resource (e.g., Allow), possibly including extensions this specification doesn't define ๐. The response body, if there is one, SHOULD also include information about the communication options ๐. This specification doesn't define the format for such a body, but future extensions to HTTP might ๐. Content negotiation MAY be used to pick the right response format ๐. If no response body is included, the response MUST include a Content-Length field with a field-value of "0" 0๏ธโฃ.
The Max-Forwards request-header field MAY be used to target a specific proxy in the request chain ๐ฏ. When a proxy receives an OPTIONS request on an absoluteURI for which request forwarding is permitted, the proxy MUST check for a Max-Forwards field ๐. If the Max-Forwards field-value is zero ("0"), the proxy MUST NOT forward the message. Instead, the proxy SHOULD respond with its own communication options ๐โโ๏ธ. If the Max-Forwards field-value is an integer greater than zero, the proxy MUST decrement the field-value when it forwards the request โ. If no Max-Forwards field is present in the request, then the forwarded request MUST NOT include a Max-Forwards field ๐ซ.
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, the produced data is what gets returned as the entity in the response, not the source text of the process ๐ญ, unless that text happens to be the output of the process ๐คทโโ๏ธ.
GET changes into 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 asks for the entity to be transferred only under the circumstances described by the conditional header field(s) ๐ง. The point is to cut down on unnecessary network usage by letting cached entities get refreshed without multiple requests or re-transferring data the client already has ๐พ.
GET also changes into a "partial GET" if the request message includes a Range header field โ๏ธ. A partial GET asks that only part of the entity be transferred, as described in section 14.35 ๐งฉ. Again, the goal is to reduce unnecessary network usage by letting partially-retrieved entities be completed without transferring data the client already holds ๐ซถ.
The response to a GET request is cacheable if and only if it meets the requirements for HTTP caching described in section 13 ๐พ.
See section 15.1.3 for security considerations when this is used for forms ๐.
9.4. HEAD ๐ง
HEAD is identical to GET, except that the server MUST NOT return a message-body in the response ๐ โโ๏ธ. The metainformation in the HTTP headers of a HEAD response SHOULD be identical to the information sent for a GET request ๐ฏ. This method is great for getting metainformation about the entity implied by the request without transferring the entity-body itself ๐. It's often used for testing hypertext links for validity, accessibility, and recent modification ๐.
The response to a HEAD request MAY be cacheable, in the sense that its information MAY be used to update a previously cached entity from that resource ๐. If the new field values show that the cached entity differs from the current entity (as a change in Content-Length, Content-MD5, ETag or Last-Modified would indicate), then the cache MUST treat the cache entry as stale ๐ฅ.
9.5. POST ๐ฎ
POST is used to ask the origin server to accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line โ๏ธ. It's designed to be a uniform method covering these functions:
- Annotating existing resources ๐;
- Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles ๐ฐ;
- Providing a block of data, such as the result of submitting a form, to a data-handling process ๐;
- Extending a database through an append operation ๐๏ธ.
The server decides what POST actually does, and that usually depends on the Request-URI ๐งญ. The posted entity is subordinate to that URI the same way a file is subordinate to the directory containing it, a news article is subordinate to the newsgroup it's posted to, or a record is subordinate to a database ๐๏ธ.
POST might not result in a resource that can be identified by a URI. In that case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity describing 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) ๐.
Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields ๐ . However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource ๐.
POST requests MUST obey the message transmission requirements set out in section 8.2 ๐ซก.
See section 15.1.3 for security considerations ๐.
9.6. PUT โจ
okay so PUT is the method that says "hey, please store this enclosed entity under the Request-URI I'm giving you" ๐ If the Request-URI already points at a resource, the enclosed entity SHOULD be considered as a modified version of the one living on the origin server ๐ฆ If nothing lives there yet and the user agent is able to define that URI as a brand-new resource, the origin server can create it ๐ธ If a new resource really does get created, the origin server MUST inform the user agent with a 201 (Created) response ๐ If an existing resource gets modified instead, a 200 (OK) or 204 (No Content) response code SHOULD be sent to show the request went through โจ And if the resource couldn't be created or modified at that Request-URI, an appropriate error response SHOULD be given that reflects what went wrong ๐ญ The recipient of the entity MUST NOT ignore any Content-* headers (like Content-Range) that it doesn't understand or implement, and it MUST return a 501 (Not Implemented) response in those cases ๐
If the request goes through a cache and the Request-URI identifies one or more entries that are currently cached, those entries SHOULD be treated as stale ๐ง Responses to this method are not cacheable, so don't even try ๐
Now the big POST vs PUT difference, bestie ๐ It's all about what the Request-URI means. In a POST, the URI identifies the resource that will handle the enclosed entity, and that could 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 that's enclosed with the request. The user agent already knows which URI it means, so the server MUST NOT attempt 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, and then the user agent MAY make its own decision about whether or not to redirect the request ๐ฅ
A single resource MAY be identified by many different URIs, and that's so iconic ๐ For example, an article might have one URI for "the current version" that's separate from the URI for each particular version. In that setup, a PUT on a general URI might result in several other URIs being defined by the origin server ๐ฆ
HTTP/1.1 does not 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 ๐
Unless a particular entity-header says otherwise, the entity-headers in the PUT request SHOULD be applied to the resource created or modified by the PUT โจ
9.7. DELETE ๐๏ธ
okay the DELETE method 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, so it's not always the final word ๐ซถ The client can't be guaranteed that the operation was actually carried out, even if the status code returned by the origin server says it was completed successfully ๐ญ That's why the server SHOULD NOT indicate success unless, at the time it gives the response, it intends to delete the resource or move it to an inaccessible location ๐ โโ๏ธ
A successful response SHOULD be 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action hasn't been enacted yet, or 204 (No Content) if the action has been enacted but the response doesn't include an 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 cacheable ๐
9.8. TRACE ๐
The TRACE method is used to invoke a remote, application-layer loop-back of the request message ๐ช The final recipient of the request 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 being received at the other end of the request chain, and then use that data for testing or diagnostics ๐ง The value of the Via header field (section 14.45) is of particular interest, since it acts as a trace of the request chain ๐ฆ Using the Max-Forwards header field lets the client limit how long the request chain gets, which is super useful for testing a chain of proxies that's forwarding messages in an infinite loop ๐๐ญ
If the request is valid, 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 ๐
9.9. CONNECT ๐
This specification reserves the method name CONNECT for use with a proxy that can dynamically switch to being a tunnel (e.g. SSL tunneling [44]) ๐ That's a whole main character moment for the proxy ๐
10. Status Code Definitions โจ
Each Status-Code is described below, including a description of which method(s) it can follow and any metainformation required in the response ๐ So for every code, you get the full tea ๐ซ
10.1. Informational 1xx ๐ฌ
This class of status code indicates a provisional response, consisting only of the Status-Line and optional headers, and it's terminated by an empty line ๐ธ There are no required headers for this class of status code ๐ 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 ๐งช Not allowed, bestie ๐ โโ๏ธ
A client MUST be prepared to accept one or more 1xx status responses before a regular response, even if the client doesn't expect a 100 (Continue) status message ๐ซถ Unexpected 1xx status responses MAY be ignored by a user agent ๐
Proxies MUST forward 1xx responses, unless the connection between the proxy and its client has been closed, or unless the proxy itself requested the generation of the 1xx response ๐ (For example, if a proxy adds an Expect: 100-continue field when it forwards a request, then it doesn't need to forward the corresponding 100 (Continue) response(s) ๐ง )
10.1.1. 100 Continue ๐ข
The client SHOULD 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 remainder of the request or, if the request has already been completed, ignore this response ๐ The server MUST send a final response after the request has been completed ๐ See section 8.2.3 for the detailed discussion of how this status code gets used and handled ๐
10.1.2. 101 Switching Protocols ๐
The server understands and is willing to comply with the client's request, via the Upgrade message header field (section 14.42), for a change in the application protocol being used on this connection ๐ค The server will switch protocols to the ones defined by the response's Upgrade header field immediately after the empty line that terminates the 101 response ๐ฆ
The protocol SHOULD be switched only when it's advantageous to do so ๐ง For example, switching to a newer version of HTTP is advantageous over older versions, and switching to a real-time, synchronous protocol might be advantageous when delivering resources that use such features โก
10.2. Successful 2xx ๐
This class of status code indicates that the client's request was successfully received, understood, and accepted ๐ฅณ We love a request that gets the green light ๐
10.2.1. 200 OK โ
The request has succeeded ๐ The information returned with the response 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 resulted in a new resource being created ๐ฑ The newly created resource can be referenced by the URI(s) returned in the entity of the response, with the most specific URI for the resource given by a Location header field ๐ The response SHOULD include an entity containing a list of resource characteristics and location(s) so the user or user agent can choose the one that's most appropriate ๐ The entity format is specified by the media type given in the Content-Type header field ๐ The origin server MUST create the resource before returning the 201 status code ๐ If the action can't be carried out immediately, the server SHOULD respond with a 202 (Accepted) response instead โณ
A 201 response MAY contain an ETag response header field indicating the current value of the entity tag for the requested variant that was just created, see section 14.19 ๐ท๏ธ
10.2.3. 202 Accepted ๐ฌ
The request has been accepted for processing, but the processing hasn't been completed yet ๐ฐ๏ธ The request might or might not eventually be acted upon, since it might be disallowed when processing actually takes place ๐ค There's no facility for re-sending 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 (perhaps a batch-oriented process that only runs once per day) without requiring the user agent's connection to the server to stick around until the process is completed ๐ The entity returned with this response SHOULD include an indication of the request's current status and either a pointer to a status monitor or some estimate of when the user can expect the request to be fulfilled ๐
10.2.4. 203 Non-Authoritative Information ๐ชช
The returned metainformation in the entity-header is not the definitive set available from the origin server, but was gathered from a local or third-party copy ๐ The set presented MAY be a subset or a superset of the original version ๐งฉ For example, including local annotation information about the resource might 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 be 200 (OK) ๐
10.2.5. 204 No Content ๐ซ
The server has fulfilled the request but doesn't need to return an entity-body, and might want to return updated metainformation ๐ง The response MAY include new or updated metainformation in the form of entity-headers, and if they're present, they SHOULD be associated with the requested variant ๐
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 ๐ช Any new or updated metainformation SHOULD still be applied to the document currently in the user agent's active view โจ
The 204 response MUST NOT include a message-body, so it's always terminated by the first empty line after the header fields ๐
10.2.6. 205 Reset Content ๐งผ
The server has fulfilled the request, and the user agent SHOULD reset the document view that caused the request to be sent ๐ซ This response is mainly meant to let input for actions take place via user input, followed by clearing the form the input was given in, so the user can easily start another input action ๐ The response MUST NOT include an entity ๐ โโ๏ธ
10.2.7 206 Partial Content โจ
okay bestie, 206 is the server being like "I got you, here's just the slice you asked for" ๐๐. The server has fulfilled the partial GET request for the resource. The request MUST have included a Range header field (section 14.35) indicating the desired range, and MAY have included an If-Range header field (section 14.27) to make the request conditional.
The response MUST include the following header fields:
- Either a
Content-Rangeheader field (section 14.16) indicating the range included with this response, or amultipart/byterangesContent-TypeincludingContent-Rangefields for each part. If aContent-Lengthheader field is present in the response, its value MUST match the actual number of OCTETs transmitted in the message-body. ๐ Date๐๏ธETagand/orContent-Location, if the header would have been sent in a 200 response to the same request ๐ธExpires,Cache-Control, and/orVary, if the field-value might differ from that sent in any previous response for the same variant ๐ฆ
If the 206 response is the result of an If-Range request that used a strong cache validator (see section 13.3.3), the response SHOULD NOT include other entity-headers. If the response is the result of an If-Range request that used a weak validator, the response MUST NOT include other entity-headers, because this keeps cached entity-bodies and updated headers from getting into a mess with each other ๐
โโ๏ธ. Otherwise, the response MUST include all of the entity-headers that would have been returned with a 200 (OK) response to the same request. ๐
A cache MUST NOT combine a 206 response with other previously cached content if the ETag or Last-Modified headers do not match exactly, see 13.5.4. ๐ซ
A cache that does not support the Range and Content-Range headers MUST NOT cache 206 (Partial) responses. ๐
10.3 Redirection 3xx ๐งญ
this class of status code means the user agent still has some work to do before the request is fulfilled ๐โโ๏ธ. 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 client SHOULD detect infinite redirection loops, since such loops generate network traffic for each redirection. ๐
Note: previous versions of this specification recommended a maximum of five redirections. Content developers should be aware that there might be clients that implement such a fixed limitation.
10.3.1 300 Multiple Choices ๐
the requested resource corresponds to any one of a set of representations. Each one has its own specific location, and agent-driven negotiation information (section 12) is being provided so that the user (or user agent) can pick a preferred representation and redirect its request to that location ๐๏ธ.
Unless it was a HEAD request, the response SHOULD include an entity containing a list of resource characteristics and location(s) the user or user agent can choose from, the one most appropriate being the goal. The entity format is specified by the media type given in the Content-Type header field. Depending upon the format and the capabilities of the user agent, selection of the most appropriate choice MAY be performed automatically. However, this specification does not define any standard for such automatic selection. ๐ค
If the server has a preferred choice of representation, it SHOULD include the specific URI for that representation in the Location field; user agents MAY use the Location field value for automatic redirection. This response is cacheable unless indicated otherwise. ๐
10.3.2 301 Moved Permanently ๐ก
The requested resource has been assigned a new permanent URI, and any future references to this resource SHOULD use one of the returned URIs. Clients with link editing capabilities ought to automatically re-link references to the Request-URI to one or more of the new references returned by the server, where possible. This response is cacheable unless indicated otherwise. โ๏ธ
The new permanent URI 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 the 301 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. ๐
Note: when automatically redirecting aPOSTrequest after receiving a 301 status code, some existing HTTP/1.0 user agents will erroneously change it into aGETrequest. ๐ฌ
10.3.3 302 Found ๐
The requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field. โณ
The temporary URI 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 the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. ๐
โโ๏ธ
Note: RFC 1945 and RFC 2068 specify that the client is not allowed to change the method on the redirected request. However, most existing user agent implementations treat 302 as if it were a 303 response, performing aGETon theLocationfield-value regardless of the original request method. The status codes 303 and 307 have been added for servers that wish to make unambiguously clear which kind of reaction is expected of the client. ๐ซ
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 method exists primarily to allow the output of a POST-activated script to redirect the user agent to a selected resource. The new URI is not a substitute reference for the originally requested resource. The 303 response MUST NOT be cached, but the response to the second (redirected) request might be cacheable. ๐
The different URI 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). ๐
Note: many pre-HTTP/1.1 user agents do not understand the 303 status. When interoperability with such clients is a concern, the 302 status code may be used instead, since most user agents react to a 302 response as described here for 303. ๐งธ
10.3.5 304 Not Modified ๐ค
If the client has performed a conditional GET request and access is allowed, but the document has not been modified, the server SHOULD respond with this status code. The 304 response MUST NOT contain a message-body, and thus is always terminated by the first empty line after the header fields. ๐ซ
The response MUST include the following header fields:
Date, unless its omission is required by section 14.18.1 ๐๏ธ
If a clockless origin server obeys these rules, and proxies and clients add their own Date to any response received without one (as already specified by [RFC 2068], section 14.19), caches will operate correctly. โฐ
ETagand/orContent-Location, if the header would have been sent in a 200 response to the same request ๐ธExpires,Cache-Control, and/orVary, 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 (i.e., the conditional GET used a weak validator), the response MUST NOT include other entity-headers, because this keeps cached entity-bodies and updated headers from getting into a mess with each other ๐
โโ๏ธ.
If a 304 response indicates an entity not currently cached, then 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. โจ
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 URI of the proxy. The recipient is expected to repeat this single request via the proxy. 305 responses MUST only be generated by origin servers. ๐ก๏ธ
Note: RFC 2068 was not clear that 305 was intended to redirect a single request, and to be generated by origin servers only. Not observing these limitations has significant security consequences. ๐จ๐
10.3.7 306 (Unused) ๐ซฅ
The 306 status code was used in a previous version of the specification, is no longer used, and the code is reserved. ๐ฐ๏ธ
10.3.8 307 Temporary Redirect ๐ฆ
The requested resource resides temporarily under a different URI. Since the redirection MAY be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field. ๐ท
The temporary URI 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), since many pre-HTTP/1.1 user agents do not understand the 307 status. Therefore, the note SHOULD contain the information necessary for a user to repeat the original request on the new URI. ๐บ๏ธ
If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. ๐
10.4 Client Error 4xx ๐โโ๏ธ
the 4xx class of status code is for when the client seems to have messed up somewhere ๐
. Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. These status codes are applicable to any request method. User agents SHOULD display any included entity to the user. ๐ฃ
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 request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications. ๐ง
10.4.2 401 Unauthorized ๐
okay so 401 is the server going "hold up, who are you?" ๐ The request needs user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) with 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 had Authorization credentials, then the 401 is basically saying those credentials got refused ๐. If the 401 has the same challenge as the previous response, and the user agent already tried authenticating at least once, then the user SHOULD be shown the entity from the response, since it might have useful diagnostic info โจ. HTTP access authentication is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43] ๐.
10.4.3 402 Payment Required ๐ธ
this one is reserved for future use ๐ซ so nothing to see here yet, bestie.
10.4.4 403 Forbidden ๐ซ
the server understood the request, but it's refusing to fulfill it ๐
โโ๏ธ. Authorization will not help, so 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. If the server doesn't want to share that info with the client, the status code 404 (Not Found) can be used instead ๐๐
.
10.4.5 404 Not Found ๐งญ
the server hasn't found anything matching the Request-URI ๐. There's no indication of whether the condition is temporary or permanent. 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 ๐ชฆ. This code is commonly used when the server doesn't want to reveal exactly why the request was refused, or when no other response is applicable ๐คทโโ๏ธ.
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 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 with a list of available entity characteristics and location(s) the user or user agent can pick the most appropriate one from ๐. 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, picking the best choice 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 might even be preferable to sending a 406 response. User agents are encouraged to inspect the headers of an incoming response to decide if it's acceptable ๐.
If the response could be unacceptable, a user agent SHOULD temporarily stop receiving more data and ask the user what to do next ๐.
10.4.8 407 Proxy Authentication Required ๐งฑ
this is basically the 401 cousin, but it means the client has to authenticate itself with the proxy first ๐ต๏ธโโ๏ธ. The proxy MUST return a Proxy-Authenticate header field (section 14.33) with a challenge that applies to the proxy for the requested resource. The client MAY repeat the request with a suitable Proxy-Authorization header field (section 14.34). HTTP access authentication is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43] ๐.
10.4.9 408 Request Timeout โฐ
the client didn't send a request in the time the server was ready to wait ๐ญ. 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 current state of the resource ๐ฌ. This code is only allowed when the user will probably be able to resolve 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 entity would have enough info for the user or user agent to fix the problem, but that might not be possible and is not required ๐ธ.
Conflicts happen most often in response to a PUT request ๐
. For example, if versioning were being used and the entity being PUT had changes that conflict with changes made by an earlier (third-party) request, the server might use the 409 response to say it can't complete the request. In that case, the response entity would probably 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 requested resource isn't available on the server anymore, and no forwarding address is known ๐ข. This condition is expected to 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, the status code 404 (Not Found) SHOULD be used instead ๐. This response is cacheable unless indicated otherwise ๐พ.
The 410 response is mostly meant to help with web maintenance ๐ ๏ธ. It tells the recipient the resource is intentionally unavailable and that the server owners want remote links to it removed. This is common for limited-time promo stuff, and for resources belonging to people who no longer work at the server's site ๐ฅ. You don't have to mark every permanently gone resource as "gone", and you don't have to keep the mark for any particular length of time. 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 ๐ง
a precondition in one or more of the request-header fields evaluated to false when the server tested it ๐. This response code lets the client set preconditions on the current resource metainformation (header field data), so the requested method can't be applied to 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 process ๐. The server MAY close the connection to stop the client from continuing the request ๐.
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 MAY 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's only likely when a client has improperly turned a POST request into a GET request with long query info ๐ฎ, when the client has fallen into a URI "black hole" of redirection (for example, a redirected URI prefix that points to a suffix of itself) ๐ณ๏ธ, or when a client is attacking the server by trying to exploit security holes in servers that use fixed-length buffers for reading or manipulating the Request-URI ๐จ๐ญ.
10.4.16 415 Unsupported Media Type ๐๏ธ
the server won't service the request because the entity of the request is in a format the requested resource doesn't support for that method ๐ โโ๏ธ.
10.4.17 416 Requested Range Not Satisfiable ๐
A server SHOULD return a response with this status code if a request included a Range request-header field (section 14.35), none of the range-specifier values in that field overlap the current extent of the selected resource, and the request did not include an If-Range request-header field. (For byte-ranges, this means that the first-byte-pos of all of the byte-range-spec values were greater than the current length of the selected resource.) ๐งฎ๐
When this status code is returned for a byte-range request, the response SHOULD include a Content-Range entity-header field saying the current length of the selected resource (see section 14.16) ๐โจ. This response MUST NOT use the multipart/byteranges content-type ๐ซ๐.
10.4.18 417 Expectation Failed ๐ โโ๏ธ
the expectation given in an Expect request-header field (see section 14.20) couldn't be met by this server. Or, if the server is a proxy, it has unambiguous evidence that the request couldn't be met by the next-hop server ๐ง.
10.5 Server Error 5xx ๐ฅ
status codes starting with the digit "5" mean the server knows it messed up, or it can't do the request ๐ญ๐งฏ. 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 needed to fulfill the request ๐. 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 ๐
the server, while acting as a gateway or proxy, got an invalid response from the upstream server it reached out to 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 ๐งนโจ. The implication is that this is temporary and will get better after some delay. If it's known, the length of the delay 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 might just prefer to refuse the connection ๐ โโ๏ธ๐.
10.5.5 504 Gateway Timeout โ
the server, while acting as a gateway or proxy, didn't get a timely response from the upstream server specified by the URI (for example, HTTP, FTP, LDAP) or from some other auxiliary server (for example, DNS) it needed to reach in order to complete the request ๐๐ฉ.
Note: Note to implementors: some deployed proxies are known to return 400 or 500 when DNS lookups time out. ๐ซถ๐ง
10.5.6 505 HTTP Version Not Supported ๐
okay so the server is looking at the HTTP version the client sent and going "nah, not today" ๐ โโ๏ธ it either doesn't support that version or refuses to. it's basically saying it can't or won't finish the request using the same major version as the client (see section 3.1), so this error message is all you get ๐ญ. the response SHOULD contain an entity explaining why that version isn't supported and which other protocols that server does speak ๐ซถ
11 Access Authentication โจ
okay bestie, HTTP has a few OPTIONAL challenge-response auth mechanisms ๐. the server can challenge a client request, and the client can answer with its auth info. the whole general framework, plus the "basic" and "digest" schemes, lives in "HTTP Authentication: Basic and Digest Access Authentication" [43] ๐. this spec just borrows the definitions of "challenge" and "credentials" from that doc, no need to reinvent the wheel ๐๐
12 Content Negotiation ๐
so most HTTP responses carry an entity meant for a human to read ๐งโ๐ป. naturally you want to hand them the "best available" version, but here's the drama: not everyone agrees on what "best" means, and not every user agent can render every entity type ๐. that's why HTTP has a bunch of "content negotiation" mechanisms, which is basically the process of picking the best representation for a response when there are several options ๐
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 with an entity-body MAY be subject to negotiation, and yes, that includes error responses ๐ญ
there are two flavours of negotiation: server-driven and agent-driven ๐. they're orthogonal, which means you can use them separately or stack them together ๐ง. one combo is called transparent negotiation, and it happens when a cache takes the agent-driven info the origin server gave it and uses that to do server-driven negotiation for later requests ๐
12.1 Server-driven Negotiation
if the server's own algorithm picks the best representation for a response, that's server-driven negotiation ๐ฅ๏ธ. the pick is based on the representations available (the dimensions they can vary over, like language, content-coding, etc.) and on the contents of certain request header fields, or on other stuff about the request, like the client's network address ๐
server-driven negotiation is great when the selection algorithm would be hard to explain to the user agent, or when the server wants to send its "best guess" with the very first response, hoping the client is happy with it and no extra round trip is needed โจ. to help the server guess better, the user agent MAY include request header fields like Accept, Accept-Language, Accept-Encoding, and so on, describing what it prefers ๐
but server-driven negotiation has some downsides, bestie ๐ฌ:
- the server can never really know what's "best" for a given user, since that would need full info about the user agent's capabilities and what the response is for (like, does the user want to read it on screen or print it on paper? ๐จ๏ธ).
- making the user agent describe its capabilities in every request can be super inefficient (since only a small percentage of responses have multiple representations) and can also be a privacy concern ๐.
- it makes the origin server harder to build, along with the algorithms that generate responses ๐ ๏ธ.
- it may limit a public cache's ability to reuse the same response for different users' requests ๐ซ .
HTTP/1.1 has these request header fields for server-driven negotiation, which describe user agent capabilities and 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.43). but an origin server isn't stuck with those dimensions ๐
. it MAY vary the response based on any aspect of the request, including stuff outside the request-header fields or inside extension header fields not defined by this spec ๐ฆ
the Vary header field is how you express which parameters the server used to pick a representation that's subject to server-driven negotiation ๐งฉ. see section 13.6 for how caches use Vary, and section 14.44 for how servers use it ๐
12.2 Agent-driven Negotiation
with agent-driven negotiation, the user agent does the picking ๐. it gets an initial response from the origin server first, then chooses the best representation from a list of available ones. that list is included in the header fields or entity-body of the initial response, and each representation has its own URI ๐. the user agent can choose automatically (if it's capable) or the user can pick manually from a generated (possibly hypertext) menu ๐ฝ๏ธ
agent-driven negotiation shines when the response varies over common dimensions (like type, language, or encoding), when the origin server can't figure out the user agent's capabilities from the request, and generally when public caches are used to spread out server load and cut down network usage ๐ธ
the downside? it needs a second request to get the best alternate representation ๐ฉ. that second request is only efficient when caching is in play โจ. also, this spec doesn't define any mechanism for automatic selection, though it doesn't stop anyone from building one as an extension and using it within HTTP/1.1 ๐ง
HTTP/1.1 defines the 300 (Multiple Choices) and 406 (Not Acceptable) status codes to enable agent-driven negotiation when the server can't or won't provide a varying response using server-driven negotiation ๐
12.3 Transparent Negotiation
transparent negotiation is the combo of server-driven and agent-driven negotiation ๐ซถ. when a cache gets some form of the list of available representations (like in agent-driven negotiation) and the cache fully understands the dimensions of variance, the cache can do server-driven negotiation on the origin server's behalf for later requests on that resource ๐ง
the perks: it spreads out the negotiation work that would otherwise land on the origin server, and it gets rid of the second-request delay of agent-driven negotiation when the cache guesses the right response right ๐ฏ
this spec doesn't define any mechanism for transparent negotiation, but it doesn't block anyone from building one as an extension that could be used within HTTP/1.1 ๐ฆ
13 Caching in HTTP ๐๏ธ
HTTP is usually used for distributed information systems, where performance can get a huge boost from response caches ๐. HTTP/1.1 has a bunch of elements designed to make caching work as well as possible ๐. they're totally intertwined with the rest of the protocol and they interact with each other, so it helps to describe the basic caching design separately from the detailed bits about methods, headers, response codes, and so on ๐
caching is pointless if it doesn't actually improve performance, obviously ๐. 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 round trips for many operations, and that's handled by an "expiration" mechanism (see section 13.2) โฐ. the second one saves bandwidth, and that's handled by a "validation" mechanism (see section 13.3) ๐ซง
now here's the tea โ: performance, availability, and disconnected operation requirements mean we have to be able to relax the goal of semantic transparency ๐ค. HTTP/1.1 lets origin servers, caches, and clients explicitly reduce transparency when needed. but non-transparent operation can confuse non-expert users, and it might not work with certain server applications (like ones for ordering merchandise ๐). so the protocol says transparency can only 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 you these important elements ๐ :
- protocol features that give full semantic transparency when everyone needs 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 keep the requested level of semantic transparency โ ๏ธ.
a basic principle here is that clients have to be able to detect any potential relaxation of semantic transparency ๐ต๏ธโโ๏ธ
Note: The server, cache, or client implementor might face design decisions not explicitly discussed in this specification. If a decision might affect semantic transparency, the implementor ought to err on the side of maintaining transparency unless a careful and complete analysis shows significant benefits in breaking transparency. ๐
13.1.1. Cache Correctness โจ
Okay so bestie, a correct cache MUST respond to a request with the most up-to-date response it's holding that's actually appropriate for that request (see sections 13.2.5, 13.2.6, and 13.12) ๐ . It only gets to do that if the response meets one of these 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) ๐ธ. By default, that means it meets the least restrictive freshness requirement of the client, origin server, and cache (see section 14.9). If the origin server says so, it only has to meet the origin server's own freshness requirement ๐.
If a stored response isn't "fresh enough" by the most restrictive freshness requirement of both the client and the origin server, the cache MAY still return it in carefully considered circumstances, with the appropriate Warning header (see sections 13.1.5 and 14.46) ๐ง. The exception is when the response is prohibited, like by a "no-store" cache-directive or a "no-cache" cache-request-directive (see section 14.9) ๐ โโ๏ธ.
- It is an appropriate 304 (Not Modified), 305 (Proxy Redirect), or error (4xx or 5xx) response message ๐.
If the cache can not communicate with the origin server, a correct cache SHOULD respond as above if the response can be correctly served from the cache ๐ซถ. If it can't do that, it MUST return an error or warning saying there was a communication failure ๐ญ.
If a cache receives 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 to the requesting client anyway. It shouldn't add a new Warning, but it also shouldn't remove any existing Warning headers ๐ฆ. A cache SHOULD NOT try to revalidate a response just because it went stale in transit, since that could lead to an infinite loop ๐. A user agent that gets a stale response with no Warning MAY display 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 general-header ๐จ. The Warning header and the currently defined warnings are described in section 14.46. The warning lets clients take appropriate action ๐.
Warnings MAY 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 get three digit warn-codes. The first digit tells you whether the Warning MUST or MUST NOT be deleted from a stored cache entry after a successful revalidation ๐:
1xxWarnings describe the freshness or revalidation status of the response, so they MUST be deleted after a successful revalidation. 1XX warn-codes MAY be generated by a cache only when validating a cached entry. It MUST NOT be generated by clients ๐.2xxWarnings describe some aspect of the entity body or entity headers that revalidation doesn't fix (for example, a lossy compression of the entity bodies). These MUST NOT be deleted after a successful revalidation ๐.
See section 14.46 for the definitions of the codes themselves ๐.
HTTP/1.0 caches will cache all Warnings in responses, and they won't delete the ones in the first category ๐ฐ๏ธ. Warnings in responses passed to HTTP/1.0 caches carry an extra warning-date field. That field stops a future HTTP/1.1 recipient from believing a Warning that was cached in error ๐ก๏ธ.
Warnings also carry a warning text. The text MAY be in any appropriate natural language (maybe based on the client's Accept headers), and it can include an OPTIONAL indication of which character set is used ๐.
Multiple warnings MAY be attached to a response, either by the origin server or by a cache. That includes multiple warnings with the same code number. For example, a server might send the same warning with texts in both English and Basque ๐ฌ๐ง๐ช๐ธ.
When a response has multiple warnings attached, showing all of them to the user might not be practical or reasonable ๐. This version of HTTP doesn't specify strict priority rules for deciding which warnings to display and in what order, but it does suggest some heuristics ๐ .
13.1.3. Cache-control Mechanisms
The basic cache mechanisms in HTTP/1.1 (server-specified expiration times and validators) are 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 usually override the default caching algorithms. As a general rule, if there's any apparent conflict between header values, the most restrictive interpretation is applied (the one most likely to preserve semantic transparency) ๐. But some cache-control directives are explicitly specified as weakening that approximation of semantic transparency, like 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, the user agent might let the user say that cached entities (even explicitly stale ones) are never validated. Or the user agent might habitually add Cache-Control: max-stale=3600 to every request ๐. The user agent SHOULD NOT default to either non-transparent behavior, or behavior that results in abnormally ineffective caching. It MAY be explicitly configured to do so by an explicit action of the user ๐
โโ๏ธ.
If the user has overridden the basic caching mechanisms, the user agent SHOULD explicitly indicate it whenever that results in displaying information that might not meet the server's transparency requirements. This is especially true 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 show up 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 indicator ๐คข.
If the user has overridden the caching mechanisms in a way that would abnormally reduce the effectiveness of caches, the user agent SHOULD continually indicate this state to the user ๐ฅ. For example, it could show a picture of currency in flames, so the user doesn't accidentally burn through excess resources or suffer from excessive latency ๐ธ.
13.1.5. Exceptions to the Rules and Warnings
Sometimes the operator of a cache MAY choose to configure it to return stale responses even when clients didn't ask for them ๐งโ๐ป. This decision ought not be made 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), so the client software can 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 that 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 main source of expiration information, with intermediate caches playing a smaller role through their contribution to the age of a response ๐ . But sometimes the client needs a say in whether a cache returns a cached response without validating it. Clients do this with several directives of the Cache-Control header ๐๏ธ.
A client's request MAY 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 0๏ธโฃ. A client MAY 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 MAY also say it will accept stale responses, up to some maximum amount of staleness. This loosens the constraints on caches, so it might break the origin server's specified constraints on semantic transparency. It might still be necessary for disconnected operation, or for high availability when connectivity is poor ๐ด.
13.2. Expiration Model
13.2.1. Server-Specified Expiration
HTTP caching works best when caches can completely avoid sending requests to the origin server ๐. The main way to avoid requests is for an origin server to give an explicit expiration time in the future, saying that a response MAY be used to satisfy later requests. In other words, a cache can return a fresh response without asking the server first ๐งโโ๏ธ.
The idea is that servers will give future explicit expiration times to responses because they believe the entity won't change in a semantically significant way before that time ๐ฎ. This normally preserves semantic transparency, as long as the server picks its expiration times carefully ๐ง.
The expiration mechanism only applies to responses taken from a cache. It doesn't apply to first-hand responses forwarded right away to the requesting client ๐โโ๏ธ.
If an origin server wants to force a semantically transparent cache to validate every request, it MAY assign 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. See section 14.9.4 for a more restrictive way to force revalidation ๐.
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) ๐ช.
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 force a user agent to refresh its display or reload a resource. Its semantics only apply to caching mechanisms, and those mechanisms only need to check a resource's expiration status when a new request for that resource starts. See section 13.13 for the difference between caches and history mechanisms ๐.
13.2.2. Heuristic Expiration
Origin servers don't always give explicit expiration times, so HTTP caches usually assign heuristic expiration times ๐ฒ. They use algorithms that look at other header values (like the Last-Modified time) to guess a plausible expiration time ๐. The HTTP/1.1 specification doesn't give specific algorithms, but it does put worst-case constraints on their results ๐ง. Heuristic expiration times might compromise semantic transparency, so they ought to be used cautiously. We really encourage origin servers to give explicit expiration times as much as they can ๐โจ.
13.2.3 Age Calculations โจ
okay so, a cache needs to know if its age is bigger than its freshness lifetime to decide if an entry is still fresh ๐ซถ we'll do the freshness lifetime math in section 13.2.4 ๐ฆ. this section is all about working out the age of a response or cache entry ๐
when we say "now" we just mean "whatever the clock on this host says right this second" โฐ hosts using HTTP, and especially origin servers and caches, SHOULD use NTP [28] or something similar to sync their clocks to a globally accurate time standard. clock vibes matter, bestie ๐ฐ๏ธ
HTTP/1.1 requires origin servers to send a Date header, if they can, with every response. it tells you when the response was generated (see section 14.18) ๐
we'll call the value of that header "date_value," in a form that works for math ๐ข
HTTP/1.1 uses the Age response-header to say how old a response is when it comes from a cache ๐ต the Age value is the cache's guess for how long it's been since the origin server generated or revalidated the response โ
basically, the Age value is all the time the response has chilled inside each cache along the way from the origin server, plus all the time it spent traveling over the network ๐๐ธ we'll call the value of that header "age_value," also in math-friendly form ๐งฎ
there are two totally independent ways to figure out a response's age ๐
- now minus date_value, if your local clock is reasonably in sync with the origin server's clock. if that comes out negative, you just use zero instead ๐
- age_value, but only if every cache on the response path is running HTTP/1.1 ๐
since we have two separate ways to get the age, we can combine them like this ๐
corrected_received_age = max(now - date_value, age_value)
and as long as we've got either nearly synced clocks or an all-HTTP/1.1 path, you get a reliable (conservative) result ๐ฅ
here's the tea ๐ต some real time can pass between the server generating a response and the next cache or client actually receiving it, because of network delays ๐ข if we don't correct for that, the age comes out too low, and that's not it ๐ญ
the fix is to record the time the request was started. the request that got back that Age value had to be sent before the value was created, so when an Age value shows up, it MUST be interpreted relative to the time the request was initiated, not the time the response arrived ๐ฏ this keeps things conservative no matter how much delay happened, which is so iconic ๐ so we compute:
corrected_initial_age = corrected_received_age
- (now - request_time)
where "request_time" is the time (by the local clock) when the request that got this response was sent โฑ๏ธ
here's the full age calculation summary for 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;
the current_age of a cache entry is the corrected initial age plus how many seconds have passed since the origin server last validated the entry ๐ง when a cache builds a response from one of its entries, it MUST include a single Age header field in that response, and its value MUST be the entry's current_age ๐ (okay, it's MUST, not vibes, sorry ๐
)
having an Age header in a response means the response is not first-hand ๐
โโ๏ธ the reverse isn't guaranteed though. no Age header doesn't automatically mean it's first-hand, unless every cache on the request path is HTTP/1.1 compliant, because older caches never learned how to do Age ๐ด
13.2.4 Expiration Calculations ๐ธ
so to figure out if a response is fresh or stale, we compare its freshness lifetime to its age ๐ต๏ธโโ๏ธ the age part is in section 13.2.3, and this section is where we figure out the freshness lifetime and decide whether the response has expired ๐ in the math below, the values can be stored however is easiest for arithmetic ๐งฎ
we'll call the value of the Expires header "expires_value," and "max_age_value" is the number of seconds in the "max-age" directive of a Cache-Control header in a response (see section 14.9.3) ๐ซง
max-age takes priority over Expires, so if max-age is in the response, the math is just:
freshness_lifetime = max_age_value
otherwise, if Expires is in the response, it's:
freshness_lifetime = expires_value - date_value
and fun fact, neither of these is affected by clock skew, since all the info comes straight from the origin server ๐ง โจ
if none of Expires, Cache-Control: max-age, or Cache-Control: s-maxage (see section 14.9.3) show up in the response, and the response doesn't have any other caching restrictions, the cache MAY work out a freshness lifetime using a heuristic ๐ค the cache MUST attach Warning 113 to any response whose age is more than 24 hours, if that 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 fraction might be 10% ๐
figuring out whether a response has expired is honestly super simple ๐
response_is_fresh = (freshness_lifetime > current_age)
13.2.5 Disambiguating Expiration Values ๐
expiration values get assigned optimistically, so two caches can each have fresh copies of the same resource that are totally different ๐ฌ that's a whole mess, bestie ๐ซ
if a client doing a retrieval gets a response that isn't first-hand, for a request its own cache already had fresh, and the Date header in its existing entry is newer than the Date on the new response, then the client MAY ignore the new response ๐ if it does, 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 but 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 revalidation of an entry that looked fresh ๐
13.2.6 Disambiguating Multiple Responses ๐ฆ
clients can get responses through multiple paths, so some responses might come through one set of caches and others through a different set ๐ฃ๏ธ that means a client could receive responses in a different order than the origin server sent them ๐ต we really want the client to use the most recently generated response, even if older ones still look fresh ๐
neither the entity tag nor the expiration value can set an order for responses, because a later response can totally intentionally have an earlier expiration time ๐ Date values are ordered to a granularity of one second โณ
when a client tries to revalidate a cache entry and the response has a Date that looks older than the one on the existing entry, the client SHOULD repeat the request unconditionally, and include
Cache-Control: max-age=0
to make any intermediate caches check their copies directly with the origin server, or
Cache-Control: no-cache
to make any intermediate caches 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 fresh response too ๐ง and servers MUST NOT depend on clients being able to pick deterministically between responses generated during the same second, if their expiration times overlap ๐ซ that's a no-no, bestie ๐ค
13.3 Validation Model ๐
when a cache has a stale entry it wants to use as a response to a client's request, it first has to check with the origin server (or maybe an intermediate cache with a fresh response) to see if the entry is still usable ๐ we call this "validating" the entry โ we don't want to pay the cost of resending the whole response if the cached entry is still good, and we don't want to pay for an extra round trip if the entry is invalid, so HTTP/1.1 supports conditional methods ๐
the key features for conditional methods are the "cache validators" ๐๏ธ when an origin server generates a full response, it attaches some kind of validator to it, which 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, and if they match (see section 13.3.3), it responds with a special status code (usually 304 (Not Modified)) and no entity-body ๐ otherwise, it returns a full response, including the entity-body ๐จ so we skip resending the full response when the validator matches, and we skip an extra round trip when it doesn't ๐ซถ
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 one ๐ช
the protocol has both positive and negative cache-validating conditions ๐ that means you can ask for a method to run only if a validator matches, or only if no validators match ๐
Note: a response without a validator can still be cached and served from cache until it expires, unless a cache-control directive explicitly forbids it ๐ but a cache can't do a conditional retrieval without a validator for the entity, so it can't be refreshed once 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 counts as valid if the entity hasn't been modified since the Last-Modified value ๐ no drama, just vibes ๐ธ
13.3.2. Entity Tag Cache Validators โจ
okay so the ETag response-header field value, an entity tag ๐ท๏ธ, gives you an "opaque" cache validator ๐. this can be super helpful when storing modification dates is a hassle ๐ , when the one-second resolution of HTTP date values just isn't precise enough โฑ๏ธ, or when the origin server wants to dodge certain paradoxes that can pop up with modification dates ๐. it's giving "no tangles" energy ๐
Entity Tags are described in section 3.11. The headers used with entity tags are described in sections 14.19, 14.24, 14.26 and 14.44.
13.3.3. Weak and Strong Validators ๐
okay this one's a big deal ๐ง. origin servers AND caches both compare two validators to figure out if they're the same or different entities, so you'd normally expect that if the entity (the entity-body or any entity-headers) changes in any way, the validator changes too. if that's true, we call it a "strong validator" ๐ช.
BUT sometimes a server would rather only change the validator on semantically significant changes, and not when insignificant aspects of the entity shift around ๐ซง. 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 ๐ง . or another way to see it: a strong validator is part of an identifier for one specific entity, and 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.
Note: An entity's modification time, if represented with one-second resolution, could be a weak validator, since it is possible that the resource might be modified twice during a single second.
Note: 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 is 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 do not depend on exact equality of an entity ๐. for example, either kind is usable for a conditional GET of a full entity. however, only a strong validator is usable for a sub-range retrieval, since otherwise the client might end up with an internally inconsistent entity ๐.
Clients MAY issue simple (non-subrange) GET requests with either weak validators or strong validators. Clients MUST NOT use weak validators in other forms of request. ๐ซ
the only function that the HTTP/1.1 protocol defines on validators is comparison ๐. there are two validator comparison functions, depending on whether the comparison context allows the use of weak validators or not:
- The strong comparison function: in order to be considered equal, both validators MUST be identical in every way, and both MUST NOT 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.
an entity tag is strong unless it is 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 is possible to deduce that it is 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 are generated from different clocks, or at somewhat different times during the preparation of the response โฐ. an implementation MAY use a value larger than 60 seconds, if it is believed that 60 seconds is too short ๐ธ.
if a client wishes to perform a sub-range retrieval on a value for which it has only 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 conditional request, other than a full-body GET request, MUST use the strong comparison function to evaluate the condition. ๐ซถ
these rules allow HTTP/1.1 caches and clients to safely perform sub-range retrievals on values that have been obtained from HTTP/1.0 servers ๐ง.
13.3.4. Rules for When to Use Entity Tags and Last-Modified Dates ๐
we adopt a set of rules and recommendations for origin servers, clients, and caches regarding when various validator types ought to be used, and for what purposes ๐.
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 might persist for arbitrarily long periods, regardless of expiration times, so it might 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-Match or If-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 origin server, upon receiving a conditional request that includes both a Last-Modified date (e.g., in an If-Modified-Since or If-Unmodified-Since header field) and one or more entity tags (e.g., in an If-Match, If-None-Match, or If-Range header field) as cache validators, MUST NOT return a response status of 304 (Not Modified) unless doing so is consistent with all of the conditional header fields in the request. ๐ โโ๏ธ
An HTTP/1.1 caching proxy, upon receiving a conditional request that includes both a Last-Modified date and one or more entity tags as cache validators, MUST NOT return a locally cached response to the client unless that cached response is consistent with all of the conditional header fields in the request. ๐
Note: 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 principle behind entity tags is that only the service author knows the semantics of a resource well enough to select 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 Cacheability โจ
Okay bestie, so the default is that a caching system MAY always store a successful response (see section 13.8) as a cache entry ๐ฆ. Unless a cache-control directive (section 14.9) says otherwise, it MAY hand that entry back without validating it if it's still fresh, and it MAY hand it back after a successful validation too ๐
. If a response has neither a cache validator nor an explicit expiration time, we don't expect it to get cached ๐
โโ๏ธ. But certain caches MAY break that expectation anyway (for example, when there's little or no network connectivity) ๐ถ. A client can usually tell that a response came from a cache by comparing the Date header to the current time โฐ.
๐ Note: some HTTP/1.0 caches are known to break that expectation without providing any Warning. Hmm, sus ๐
Sometimes though, it's just not giving for a cache to keep an entity or return it to someone later ๐ โโ๏ธ. Maybe the service author needs absolute semantic transparency, or there are security or privacy concerns ๐. That's why there are cache-control directives, so the server can say that certain resource entities, or parts of them, are not to be cached no matter what else is going on ๐.
Also, section 14.8 usually stops a shared cache from saving and returning a response to a previous request if that request had an Authorization header in it ๐. Main character energy for privacy, no cap ๐.
A response with a status code of 200, 203, 206, 300, 301 or 410 MAY be stored by a cache and reused for a later request, as long as it follows the expiration mechanism and no cache-control directive says no ๐. But a cache that doesn't support the Range and Content-Range headers MUST NOT cache 206 (Partial Content) responses ๐ซ.
Any other status code (like 302 and 307) MUST NOT be returned in reply to a later request unless a cache-control directive or some other header explicitly allows it ๐. Examples of that permission include an Expires header (section 14.21), or a max-age, s-maxage, 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 what comes back from requests so it can answer future requests ๐ง . Most of the time, it just passes the right parts of a response along to whoever asked ๐จ. But if the cache already has an entry from an earlier response, it might need to mix bits of the new response with what's already stored ๐งฉ.
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 buckets ๐ชฃ:
- End-to-end headers, which get sent all the way to the final recipient of a request or response ๐ฏ. End-to-end headers in responses MUST be stored as part of a cache entry, and they MUST be sent along in any response built from a cache entry ๐.
- Hop-by-hop headers, which only matter for one single transport-level connection ๐. Caches don't store them and proxies don't forward them ๐ โโ๏ธ.
These HTTP/1.1 headers are hop-by-hop headers ๐ซถ:
ConnectionKeep-AliveProxy-AuthenticateProxy-AuthorizationTETrailersTransfer-EncodingUpgrade
Every other header defined by HTTP/1.1 is an end-to-end header ๐.
Any other hop-by-hop header MUST be listed in a Connection header (section 14.10) to be introduced into HTTP/1.1 (or later) ๐. Iykyk ๐ญ.
13.5.2 Non-modifiable Headers ๐
Some HTTP/1.1 features, like Digest Authentication, depend on the exact value of certain end-to-end headers ๐. So a transparent proxy SHOULD NOT modify an end-to-end header unless that header's definition requires or specifically allows it ๐ โโ๏ธ.
A transparent proxy MUST NOT modify any of these fields in a request or response, and it MUST NOT add any of them if they're not already there ๐ซ:
Content-LocationContent-MD5ETagLast-Modified
A transparent proxy MUST NOT modify this field in a response ๐:
Expires
...but it MAY add any of these fields if they're not already present ๐. If an Expires header gets added, it MUST be given a field-value identical to the Date header in that same response ๐
.
A proxy MUST NOT modify or add any of these fields in a message that contains the no-transform cache-control directive, or in any request ๐
โโ๏ธ:
Content-EncodingContent-RangeContent-Type
A non-transparent proxy MAY modify or add these fields to a message that doesn't include no-transform. But if it does, it MUST add a Warning 214 (Transformation applied) if one isn't already in the message (see section 14.46) ๐ท๏ธ.
โ ๏ธ Warning: unnecessary modification of end-to-end headers might cause authentication failures if stronger authentication mechanisms are introduced in later versions of HTTP. Those authentication mechanisms MAY rely on the values of header fields that aren't listed here ๐ฌ.
The Content-Length field of a request or response gets added or deleted according to the rules in section 4.4 ๐. A transparent proxy MUST preserve the entity-length (section 7.2.2) of the entity-body, though it MAY change the transfer-length (section 4.4) ๐ง.
13.5.3 Combining Headers ๐
When a cache sends a validating request to a server, and the server answers with a 304 (Not Modified) response or a 206 (Partial Content) response, the cache then builds the response it sends back to the client ๐.
If the status code is 304 (Not Modified), the cache uses the entity-body stored in the cache entry as the entity-body of this outgoing response ๐ฆ. If the status code is 206 (Partial Content) and the ETag or Last-Modified headers match exactly, the cache MAY combine what's stored in the cache entry with the new contents from the response, and use the result as the entity-body of this outgoing response (see 13.5.4) ๐งฉ.
The end-to-end headers stored in the cache entry get used for the built response, with a few exceptions ๐:
- Any stored Warning headers with warn-code 1xx (see section 14.46) MUST be deleted from the cache entry and from the forwarded response ๐๏ธ.
- Any stored Warning headers with warn-code 2xx MUST be kept in the cache entry and in the forwarded response ๐พ.
- Any end-to-end headers provided in the
304or206response MUST replace the matching 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 the matching headers from the incoming response, except for the Warning headers we just talked about ๐. If a header field-name in the incoming response matches more than one header in the cache entry, all of those old headers MUST be replaced ๐ฏ.
So basically, the end-to-end headers from the incoming response override all the matching end-to-end headers stored with the cache entry. The exception is stored Warning headers with warn-code 1xx, which get deleted even if nothing overrides them ๐.
๐ Note: this rule lets an origin server use a304(Not Modified) or a206(Partial Content) response to update any header that went with an earlier response for the same entity or its sub-ranges. It might not always make sense or be correct to do that, though ๐ค. This rule does NOT let an origin server use a304or206response to fully delete a header it sent with an earlier response ๐ โโ๏ธ.
13.5.4 Combining Byte Ranges ๐งฉ
A response might only transfer a subrange of the bytes of an entity-body, either because the request had one or more Range specifications, or because a connection broke early ๐. After a few of these transfers, a cache might have several ranges of the same entity-body ๐ง.
If a cache already 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, but only if both of these are true ๐ซถ:
- Both the incoming response and the cache entry have a cache validator.
- The two cache validators match using the strong comparison function (see section 13.3.3).
If either requirement isn't met, the cache MUST use only the most recent partial response (based on the Date values sent with every response, and using the incoming response if those values are equal or missing) โณ. It MUST also discard the other partial information ๐๏ธ. Periodt ๐
โจ
13.6. Caching Negotiated Responses โจ
Okay bestie, so when a server uses server-driven content negotiation (section 12.1), which you can spot by the Vary header field in the response, that changes the rules for when a cache can reuse that response for later requests ๐. Servers use Vary in a specific way, so peep section 14.44 for those details ๐
.
A server SHOULD use the Vary header field to tell a cache which request-header fields were used to pick between multiple representations of a cacheable response that's subject to server-driven negotiation ๐ฆ. The header fields named in the Vary value are called the "selecting" request-headers, and they're the main characters here ๐.
When a cache gets a new request whose Request-URI points at one or more cache entries that have a Vary header field, the cache MUST NOT use that entry to build a response unless every selecting request-header in the new request matches the stored request-headers from the original request ๐. No skipping the check, periodt ๐.
Two requests have matching selecting request-headers if and only if you can turn the selecting request-headers from the first request into the ones in the second request. You can do that by adding or removing linear white space (LWS) in the spots the corresponding BNF allows, and/or by combining multiple message-header fields that share a field name, following the rules about message headers in section 4.2 ๐ธ.
A Vary field-value of * always fails to match, so later requests on that resource can only be properly interpreted by the origin server ๐ญ.
If the selecting request header fields for a cached entry don't match the selecting request header fields of the new request, the cache MUST NOT use the cached entry to satisfy the request. It has to first relay the new request to the origin server as a conditional request, and the server has to respond with 304 (Not Modified), including an entity tag or Content-Location that shows which entity should be used ๐ซถ.
If an entity tag was given to a cached representation, the forwarded request SHOULD be conditional and include the entity tags from all of the cache's entries for the resource in an If-None-Match header field โจ. This tells the server which entities the cache is currently holding, so if one of them matches the requested entity, the server can use the ETag header field in its 304 (Not Modified) response to tell the cache 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 ๐.
If any existing cache entry only has partial content for its entity, its entity-tag SHOULD NOT be included in the If-None-Match header field, unless the request is for a range that the entry would fully satisfy ๐.
If a cache receives a successful response whose Content-Location field matches an existing cache entry for the same Request-URI, whose entity-tag is different from the existing entry's, and whose Date is more recent than the existing entry's, the existing entry SHOULD NOT be returned in response to 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 "shared" and "non-shared" ones, and this part is seriously important ๐ซถ. A non-shared cache can only be accessed by a single user. That access SHOULD be enforced by appropriate security mechanisms ๐. Every other cache counts as "shared" ๐. Other sections of this spec limit what shared caches can do, so they don't leak private stuff or break access controls ๐ญ.
13.8. Errors or Incomplete Response Cache Behavior ๐
A cache that gets an incomplete response (for example, one with fewer bytes of data than the Content-Length header says) MAY store it ๐. BUT the cache MUST treat it as a partial response ๐. Partial responses MAY be combined as described in section 13.5.4, and the result could be a full response or could still be partial ๐งฉ. A cache MUST NOT hand a partial response to a client without clearly marking it as partial, using the 206 (Partial Content) status code โจ. A cache MUST NOT return a partial response with a status code of 200 (OK) ๐ซ.
If a cache gets a 5xx response while it's trying to revalidate an entry, it MAY either forward that response to the requesting client, or act as if the server never responded ๐ธ. 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 bans caching of these responses, using GET and HEAD on any resources SHOULD NOT cause side effects that would lead to messed-up behavior if the responses come from a cache ๐ โโ๏ธ. The requests MAY still have side effects, but a cache isn't required to think about those side effects when it makes caching decisions ๐ง . Caches are always expected to respect an origin server's explicit caching restrictions, no exceptions ๐ซถ.
There's one exception to this rule ๐. Some apps have traditionally used GETs and HEADs with query URLs (the ones with a ? in the rel_path part) to do operations with big side effects ๐ญ. So caches MUST NOT treat responses to those URIs as fresh unless the server gives an explicit expiration time โฐ. This specifically means that responses from HTTP/1.0 servers for those URIs SHOULD NOT be taken from a cache ๐ซ. See section 9.1.1 for related info ๐ฆ.
13.10. Invalidation After Updates or Deletions ๐ฅ
Certain methods used on a resource at the origin server can make one or more existing cache entries non-transparently invalid ๐ต. Even if those entries still count as "fresh," they don't accurately show what the origin server would return for a new request on that resource ๐.
HTTP can't guarantee that every one of those cache entries gets marked invalid ๐ฌ. For example, the request that made the change at the origin server might never have gone through the proxy where a cache entry lives ๐โโ๏ธ. Still, a few rules help cut down on messed-up behavior ๐.
In this section, "invalidate an entity" means the cache will either remove every instance of that entity from its storage, or mark them as "invalid" and in need of a mandatory revalidation before they can be returned for a later request ๐งน.
Some HTTP methods MUST make a cache invalidate an entity ๐
. That's either the entity referred to by the Request-URI, or the one from the Location or Content-Location headers (if they're there) ๐. 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 happen if its host part matches the one in the Request-URI ๐ก๏ธ. This one's so important, bestie ๐ค.
A cache that passes through requests for methods it doesn't understand SHOULD invalidate any entities referred to by the Request-URI ๐ซถ.
13.11. Write-Through Mandatory ๐
Every method that might change the origin server's resources MUST be written through to the origin server ๐. Right now, that's 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 ๐
โโ๏ธ. This doesn't stop a proxy cache from sending a 100 (Continue) response before the inbound server has sent its final reply ๐ธ.
The alternative, known as "write-back" or "copy-back" caching, is not allowed in HTTP/1.1 ๐ซ. That's because it's hard to keep updates consistent, and a server, cache, or network failure before the write-back causes a lot of problems ๐ญ.
13.12. Cache Replacement ๐
If a new cacheable response comes in from a resource while existing responses for that same resource are cached (see sections 14.9.2, 13.2.5, 13.2.6 and 13.8), the cache SHOULD use the new response to reply to the current request โจ. The cache MAY store it, and MAY, if it meets all the other requirements, use it to respond to any future requests that would've gotten the old response before ๐ฆ. If the new response does go into cache storage, the rules in section 13.5.3 apply ๐ง .
Note: a new response that has an older Date header value than existing cached responses is not cacheable. ๐
13.13. History Lists ๐
User agents often have history features, like "Back" buttons and history lists, that can bring back an entity they fetched earlier in a session ๐.
History mechanisms and caches are NOT the same thing ๐ โโ๏ธ. 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 when the resource was retrieved ๐ธ.
By default, expiration times don't apply to history mechanisms โณ. If the entity is still in storage, a history mechanism SHOULD display it even if it has expired, unless the user has specifically configured the agent to refresh expired history documents ๐.
None of this stops the history mechanism from telling the user that a view might be stale โ ๏ธ.
Note: if history list mechanisms unnecessarily stop users from viewing stale resources, service authors will be tempted 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 don't get error or warning messages when they use navigation controls (such as BACK) to view previously fetched resources ๐. Even if some resources ought not to be cached, or ought to expire quickly, UI considerations may push service authors to use other ways of preventing caching (like "once-only" URLs), so they don't suffer from improperly working history mechanisms ๐ซ .
14. Header Field Definitions โจ
This section defines the syntax and semantics of all the standard HTTP/1.1 header fields ๐. For entity-header fields, "sender" and "recipient" mean 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 if you only want an in-line image, you can say so and keep the request tight ๐
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 what groups media types into ranges ๐ธ so "/" means every media type, and "type/" means every subtype of that type โจ a media-range MAY also include media type parameters that apply to that range ๐ง
each media-range MAY be followed by one or more accept-params, and the first one is always the "q" parameter ๐ that's the relative quality factor. the first "q" is the dividing line between the media-range parameters and 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 is q=1.
Note: using "q" to split media type parameters from Accept extension parameters is basically historical vibes ๐ฐ๏ธ it does mean a media type parameter named "q" can't be used with a media range, but that's believed to be super unlikely since the IANA media type registry has no "q" parameters and barely anyone uses media type parameters in Accept anyway. future media types are discouraged from registering any parameter named "q" ๐ โโ๏ธ
here's the example ๐
Accept: audio/*; q=0.2, audio/basic
this 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 there's no Accept header field, then it's assumed the client accepts all media types ๐ but if there IS an Accept header and the server can't send anything acceptable according to the combined Accept field value, then the server SHOULD send a 406 (not acceptable) response ๐
a more elaborate one ๐
Accept: text/plain; q=0.5, text/html,
text/x-dvi; q=0.8, text/x-c
verbally, that means "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." ๐
media ranges can get overridden by more specific media ranges or specific media types โจ if more than one media range applies to a type, the most specific one wins. 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 quality factor for a given type comes from the media range with the highest precedence that matches it ๐ 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 give these values:
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 might come with a default set of quality values for certain media ranges ๐ unless it's a closed system that can't talk to other rendering agents, that default set ought to be configurable by the user ๐
14.2 Accept-Charset ๐ธ
the Accept-Charset request-header field tells the server which character sets are acceptable for the response ๐ it's how clients who understand fancier or more special-purpose character sets can flex that capability on a server that can represent documents in those sets ๐
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 showing the user's preference for it, and the default is q=1 ๐ here's an example ๐
Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
the special "" value, if it's in the Accept-Charset field, matches every character set (including ISO-8859-1) that isn't mentioned elsewhere in that field ๐ฆ if there's no "", then every character set that isn't explicitly mentioned gets a quality value of 0, except ISO-8859-1, which gets a quality value of 1 unless it's explicitly mentioned ๐ง
if there's no Accept-Charset header, any character set is acceptable ๐ if there IS one, and the server can't send a response that's acceptable according to it, then the server SHOULD send an error response with the 406 (not acceptable) status code ๐ญ though sending an unacceptable response is still allowed ๐
14.3 Accept-Encoding ๐
the Accept-Encoding request-header field is basically a cousin of Accept ๐ but it restricts the content-codings (section 3.5) that are acceptable in the response โจ
Accept-Encoding = "Accept-Encoding" ":"
1#( codings [ ";" "q" "=" qvalue ] )
codings = ( content-coding | "*" )
examples of how it's used ๐ง
Accept-Encoding: compress, gzip
Accept-Encoding:
Accept-Encoding: *
Accept-Encoding: compress;q=0.5, gzip;q=1.0
Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0
a server checks whether a content-coding is acceptable, according to an Accept-Encoding field, using these rules ๐
- if the content-coding is one of the ones listed in the Accept-Encoding field, it's acceptable, unless it comes with a qvalue of 0. (as defined in section 3.9, a qvalue of 0 means "not acceptable.") ๐ โโ๏ธ
- the special "*" symbol in an Accept-Encoding field matches any available content-coding that isn't explicitly listed in the header field ๐ธ
- if multiple content-codings are acceptable, the one with the highest non-zero qvalue is preferred ๐ฅ
- the "identity" content-coding is always acceptable, unless it's specifically refused, either because the Accept-Encoding field includes "identity;q=0", or because the field includes "*;q=0" and doesn't explicitly include "identity" ๐ซถ if the Accept-Encoding field-value is empty, then only "identity" is acceptable ๐
if an Accept-Encoding field is in a request, and the server can't send a response that's acceptable according to it, then the server SHOULD send an error response with the 406 (Not Acceptable) status code ๐ญ
if there's no Accept-Encoding field in a request, the server MAY assume the client will accept any content coding ๐ in that case, if "identity" is one of the available content-codings, the server SHOULD use "identity", unless it has additional info that a different content-coding is meaningful to the client โจ
Note: if the request doesn't have an Accept-Encoding field and "identity" isn't available either, then content-codings that HTTP/1.0 clients commonly understand ("gzip" and "compress") are preferred ๐ฐ๏ธ some older clients improperly display messages sent with other content-codings ๐ the server might also make this decision based on info about the particular user-agent or client ๐ง
Note: most HTTP/1.0 applications don't recognize or obey qvalues associated with content-codings ๐ so qvalues won't work for them and aren't permitted with x-gzip or x-compress ๐ซ
14.4 Accept-Language ๐
the Accept-Language request-header field is also similar to Accept ๐ฆ but it restricts the set of natural languages that are preferred for the response ๐ธ language tags are defined in section 3.10 โจ
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, which is basically an estimate of the user's preference for the languages in 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 where the first tag character after that prefix is "-" ๐ง the special "*" range, if it's in the Accept-Language field, matches every tag not matched by any other range in that field ๐
Note: this prefix matching rule does NOT mean language tags are assigned so that anyone who understands one tag automatically understands every tag it's a prefix of ๐ the prefix rule just lets you use prefix tags when that's actually the case ๐
the language quality factor for a language-tag is the quality value of the longest language-range in the field that matches it โจ if no language-range in the field matches the tag, the language quality factor is 0 ๐ if there's no Accept-Language header in the request, the server SHOULD assume that all languages are equally acceptable ๐ซถ if there IS an Accept-Language header, then every language assigned a quality factor greater than 0 is acceptable ๐ฅ
it might be contrary to the user's privacy expectations to send an Accept-Language header with their complete linguistic preferences in every request ๐ฌ for a discussion of this issue, see section 15.1.4 ๐
because intelligibility depends so much on the individual user, it is recommended that client apps make the choice of linguistic preference available to the user ๐ธ if that choice isn't made available, then the Accept-Language header field MUST NOT be given in the request ๐ซ
Note: when you do make the linguistic preference choice available to the user, remember that users aren't familiar with the details of language matching ๐ฅบ so give them appropriate guidance ๐ for example, users might assume that picking "en-gb" gets them any kind of English document if British English isn't available ๐ฌ๐ง a user agent might suggest adding "en" in that case to get the best matching behavior ๐
14.5 Accept-Ranges โจ
okay so Accept-Ranges is the server's way of saying "yes, I'm open to range requests for this resource" ๐ฆ Here's the grammar:
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 even if they haven't received this header for the resource involved. Range units are defined in section 3.12 ๐
Servers that don't accept any kind of range request for a resource MAY send
Accept-Ranges: none
to tell the client not to bother trying a range request ๐
14.6 Age โณ
The Age response-header field is the sender's estimate of how long it's been since the response (or its revalidation) was generated at the origin server. A cached response is "fresh" if its age doesn't go past its freshness lifetime. Age values get calculated the way section 13.2.3 specifies โจ
Age = "Age" ":" age-value
age-value = delta-seconds
Age values are non-negative decimal integers, measuring time in seconds.
Now the spicy part ๐ถ๏ธ If a cache gets a value bigger than the largest positive integer it can represent, or if any of its age calculations overflows, it MUST transmit an Age header with the value 2147483648 (2^31). An HTTP/1.1 server that includes a cache MUST include an Age header field in every response generated from its own cache. Caches SHOULD use an arithmetic type with at least 31 bits of range. Overflow is not a vibe ๐
14.7 Allow ๐ง
The Allow entity-header field lists the set of methods supported by the resource identified by the Request-URI. Its whole purpose is to tell the recipient which methods are valid for the resource ๐ An Allow header field MUST be present in a 405 (Method Not Allowed) response.
Allow = "Allow" ":" #Method
Example of use:
Allow: GET, HEAD, PUT
This field can't stop 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 that the new or modified resource should support. The server is not required to support these methods, and it 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 doesn't understand all the methods listed, because the user agent might have other ways of talking to the origin server. Hands off ๐
โโ๏ธ
14.8 Authorization ๐
A user agent that wants to authenticate itself with a server (usually, but not always, after getting a 401 response) does so by including an Authorization request-header field with the request ๐ The field value is made of credentials holding the user agent's authentication info for the realm of the resource being requested.
Authorization = "Authorization" ":" credentials
HTTP access authentication is described in "HTTP Authentication: Basic and Digest Access Authentication" [43]. If a request is authenticated and a realm is specified, the same credentials SHOULD be valid for all other requests within that realm (unless the authentication scheme itself says otherwise, like credentials that change based on a challenge value or that rely on synchronized clocks) โฐ
When a shared cache (see section 13.7) receives a request containing an Authorization field, it MUST NOT return the corresponding response as a reply to any other request, unless one of these specific exceptions holds ๐
- If the response includes the "s-maxage" cache-control directive, the cache MAY use that response to reply to a subsequent request. But (if the specified maximum age has passed) a proxy cache MUST first revalidate it with the origin server, using the request-headers from the new request so the origin server can authenticate the new request. (This is the defined behavior for s-maxage.) If the response includes "s-maxage=0", the proxy MUST always revalidate it before re-using it.
- If the response includes the "must-revalidate" cache-control directive, the cache MAY use that response to reply to a subsequent request. But if the response is stale, all caches MUST first revalidate it with the origin server, using the request-headers from the new request so the origin server can authenticate the new request.
- If the response includes the "public" cache-control directive, it MAY be returned in reply to any subsequent request.
14.9 Cache-Control ๐
The Cache-Control general-header field is used to specify directives that MUST be obeyed by all caching mechanisms along the request/response chain ๐ These directives are there to stop caches from messing with the request or response in ways they shouldn't. They usually override the default caching algorithms. Cache directives are unidirectional, so a directive in a request doesn't mean the same directive belongs in the response too ๐ฆ
Note that HTTP/1.0 caches might not implement Cache-Control and might only implement Pragma: no-cache (see section 14.32).
Cache directives MUST be passed through by a proxy or gateway application, no matter whether they matter to that app, since the directives might apply to every recipient along the request/response chain. You can't target a cache-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" ; Section 14.9.1
| "no-store" ; Section 14.9.2
| "max-age" "=" delta-seconds ; Section 14.9.3, 14.9.4
| "max-stale" [ "=" delta-seconds ] ; Section 14.9.3
| "min-fresh" "=" delta-seconds ; Section 14.9.3
| "no-transform" ; Section 14.9.5
| "only-if-cached" ; Section 14.9.4
| cache-extension ; Section 14.9.6
cache-response-directive =
"public" ; Section 14.9.1
| "private" [ "=" <"> 1#field-name <"> ] ; Section 14.9.1
| "no-cache" [ "=" <"> 1#field-name <"> ]; Section 14.9.1
| "no-store" ; Section 14.9.2
| "no-transform" ; Section 14.9.5
| "must-revalidate" ; Section 14.9.4
| "proxy-revalidate" ; Section 14.9.4
| "max-age" "=" delta-seconds ; Section 14.9.3
| "s-maxage" "=" delta-seconds ; Section 14.9.3
| cache-extension ; Section 14.9.6
cache-extension = token [ "=" ( token | quoted-string ) ]
When a directive shows up without any 1#field-name parameter, it applies to the entire request or response. When it shows up with a 1#field-name parameter, it only applies to the named field or fields, not the rest of the request or response ๐งฉ This keeps things extensible, because future versions of HTTP might apply these directives to header fields that HTTP/1.1 doesn't define.
The cache-control directives fall into these general categories:
- Restrictions on what's cacheable, which only the origin server can put in place.
- Restrictions on what a cache may store, which either the origin server or the user agent can impose.
- Changes to the basic expiration mechanism, which either the origin server or the user agent can impose.
- Controls over cache revalidation and reload, which only the user agent can impose.
- Control over transformation of entities.
- Extensions to the caching system ๐
14.9.1 What is Cacheable ๐
By default, a response is cacheable if the requirements of the request method, the request header fields, and the response status all say it's cacheable. Section 13.4 sums up these defaults for cacheability โจ The following Cache-Control response directives let an origin server override the default cacheability of a response:
public : Says the response MAY be cached by any cache, even if it would normally be non-cacheable or only cacheable within a non-shared cache. (For more, see Authorization in section 14.8.) ๐ซถ
private : Says all or part of the response message is meant for a single user and MUST NOT be cached by a shared cache. This lets the origin server say the specified parts are only for one user and aren't a valid response for requests from other users. A private (non-shared) cache MAY cache the response ๐ฆ
Note: This usage of the word private only controls where the response may be cached. It cannot ensure the privacy of the message content. Don't let the name fool you ๐ญ
no-cache : If the no-cache directive doesn't specify a field-name, then a cache MUST NOT use the response to satisfy a subsequent request without successful revalidation with the origin server. This lets the origin server stop caching even by caches that have been set up to return stale responses to clients ๐
If the no-cache directive does specify one or more field-names, then a cache MAY use the response to satisfy a subsequent request, subject to any other caching restrictions. However, the specified field-name(s) MUST NOT be sent in the response to a subsequent request without successful revalidation with the origin server. This lets the origin server stop certain header fields from being reused, while the rest of the response can still be cached ๐ธ
Note: Most HTTP/1.0 caches won't recognize or obey this directive. Not all caches are on the same page ๐
14.9.2. What May be Stored by Caches โจ
okay bestie, let's talk about no-store ๐ Its whole job is stopping sensitive stuff from leaking or hanging around in places it shouldn't, like backup tapes ๐ผ It applies to the entire message, and it MAY be sent in a response or in a request. If it shows up in a request, a cache MUST NOT store any part of that request or any response to it. If it shows up in a response, a cache MUST NOT store any part of that response or the request that triggered it. This applies to both non-shared and shared caches. "MUST NOT store" here means the cache MUST NOT intentionally keep the info in non-volatile storage, and it MUST make a best-effort attempt to clear the info out of volatile storage as quickly as possible after forwarding it. ๐งน
Even when no-store is on a response, users might still save it outside the caching system on purpose (hello, "Save As" dialog ๐พ). History buffers MAY store such responses as part of their normal operation. ๐ฐ๏ธ
The whole point of this directive is to keep service authors and users who worry about accidental info releases through unexpected cache access happy ๐ฅน It might help privacy in some cases, BUT it is not a reliable or sufficient way to protect privacy at all. ๐จ Malicious or compromised caches might not recognize or obey it, and communication networks might be open to eavesdropping. ๐ Please don't treat it as a force field! ๐ก๏ธ
14.9.3. Modifications of the Basic Expiration Mechanism ๐ซ
The expiration time of an entity MAY be set by the origin server using the Expires header (see section 14.21). Or, it MAY be set using the max-age directive in a response. When max-age is present in a cached response, that response is stale if its current age is greater than the age value given (in seconds) at the time of a new request for that resource. A max-age directive on a response implies the response is cacheable (i.e., "public") unless some other, more restrictive cache directive is also there. ๐
If a response has both an Expires header and a max-age directive, max-age overrides Expires, even if Expires is more restrictive. ๐ This rule lets an origin server give a longer expiration time to an HTTP/1.1 (or later) cache than to an HTTP/1.0 cache. That can be useful if certain HTTP/1.0 caches calculate ages or expiration times wrong, maybe because their clocks are desynchronized. โฐ
Lowkey tea: many HTTP/1.0 cache implementations treat an Expires value that is less than or equal to the response Date value as the same thing as the no-cache Cache-Control response directive. ๐ซ If an HTTP/1.1 cache gets a response like that, and the response doesn't include a Cache-Control header field, it SHOULD consider the response non-cacheable to stay compatible with HTTP/1.0 servers. ๐ค
Note: An origin server might want to use a newer cache control feature, like theprivatedirective, on a network that still has older caches that don't understand it. ๐ง The origin server will need to pair the new feature with anExpiresfield whose value is less than or equal to theDatevalue. That stops older caches from caching the response improperly. ๐
s-maxage
If a response includes an s-maxage directive, then for a shared cache (but NOT a private cache), the maximum age set by this directive overrides the maximum age set by either the max-age directive or the Expires header. ๐
The s-maxage directive also brings along the meaning of the proxy-revalidate directive (see section 14.9.4). That means the shared cache must not use the entry after it goes stale to answer a later request without first revalidating it with the origin server. ๐ The s-maxage directive is always ignored by a private cache. ๐
โโ๏ธ
Heads up: most older caches that don't follow this spec don't implement any cache-control directives at all. ๐ฆ An origin server that wants a cache-control directive which restricts, but doesn't prevent, caching by an HTTP/1.1-compliant cache MAY take advantage of the rule that max-age overrides Expires, plus the fact that pre-HTTP/1.1-compliant caches don't look at max-age. ๐ง
Other directives let a user agent tweak the basic expiration mechanism. These directives MAY be specified on a request: ๐ฑ
max-age: The client is happy to accept a response whose age is no greater than the specified time in seconds. Unlessmax-staleis also included, the client is not willing to accept a stale response. ๐min-fresh: The client is happy to accept a response whose freshness lifetime is no less than its current age plus the specified time in seconds. In other words, the client wants a response that will still be fresh for at least that many seconds. โณmax-stale: The client is willing to accept a response that has gone past its expiration time. Ifmax-stalegets a value, the client will accept a response that is past its expiration time by no more than that many seconds. If no value is given tomax-stale, the client will accept a stale response of any age. ๐ฅด
If a cache returns a stale response, whether because of a max-stale directive on a request or because the cache is set up to override a response's expiration time, the cache MUST attach a Warning header to the stale response, using Warning 110 (Response is stale). โ ๏ธ
A cache MAY be configured to return stale responses without validation, but only if this doesn't conflict with any "MUST"-level requirements about cache validation (e.g., a "must-revalidate" cache-control directive). ๐
If both the new request and the cached entry include max-age directives, the lesser of the two values is used to decide the freshness of the cached entry for that request. ๐
14.9.4 Cache Revalidation and Reload Controls โจ
Okay bestie, sometimes a user agent wants or needs to make a cache revalidate its entry with the origin server (not just with the next cache along the path), or to fully reload its entry from the origin server ๐. End-to-end revalidation might be necessary if either the cache or the origin server 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 can be requested in two ways. If the client does not have its own local cached copy, we call it "unspecified end-to-end revalidation". If the client does have a local cached copy, 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. Field names MUST NOT be included with the no-cache directive in a request. The server MUST NOT use a cached copy when responding to such a request. Iconic behavior, no cap ๐
โโ๏ธ
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 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 does not include a cache-validating conditional. Instead, 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 ๐ง
max-age
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 might 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. Lowkey a big deal ๐
However, the choice of validator might 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 can 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 can 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. ๐
only-if-cached
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 ๐ถ
must-revalidate
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.) This is the main character rule for caches ๐ฌ
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. Ngl this part is so important ๐ญ๐ซถ
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. > Be honest with the user every single time, okay? ๐จ
proxy-revalidate
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 ๐จ
no-transform
Implementors of intermediate caches (proxies) have found it useful to convert the media type of certain entity bodies. A non-transparent 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. Smart, right? ๐ง
Serious operational problems occur, however, when these transformations are 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. Not okay to mess with that ๐ฉบ๐ฌ
Therefore, if a message 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, including the value of the entity-body itself. Hands off, literally ๐ โโ๏ธ๐
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. It's giving clever design ๐ฆ
This extension mechanism depends on an 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) could 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. Safe and sound ๐ซถ
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 cacheability) 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. Main character energy for this header ๐
The Connection header has the following grammar:
Connection = "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.
Message headers listed in the Connection header MUST NOT include end-to-end headers, such as Cache-Control. Don't put Cache-Control in there, it's a whole no ๐ โโ๏ธ
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. Bye bye connection ๐๐ฅน
HTTP/1.1 applications that do not support persistent connections MUST include the 'close' connection option in every message. ๐
A system receiving an HTTP/1.0 (or lower-version) message that includes a Connection header MUST, for each connection-token in this field, remove and ignore any header field(s) from the message with the same name as the connection-token. This protects against mistaken forwarding of such header fields by pre-HTTP/1.1 proxies. See section 19.6.2. It's literally protecting the whole chain, iykyk ๐ง๐
14.11 Content-Encoding โจ
Okay bestie, Content-Encoding is a modifier on the media-type ๐ When it shows up, its value tells you which extra content codings got applied to the entity-body, so you know exactly what decoding to do to get back to the media-type in the Content-Type header field ๐ It's mainly there so a document can be compressed without losing the identity of its underlying media type. Iconic, honestly ๐ฆ
Content-Encoding = "Content-Encoding" ":" 1#content-coding
Content codings are defined in section 3.5. Here's an example of how it looks:
Content-Encoding: gzip
The content-coding is a characteristic of the entity identified by the Request-URI. Typically the entity-body is stored with this encoding and only gets decoded before rendering or something similar ๐ง However, a non-transparent proxy MAY modify the content-coding if the new coding is known to be acceptable to the recipient, unless the "no-transform" cache-control directive is present in the message. Not the proxy messing with your stuff ๐
If the content-coding of an entity is not "identity", then the response MUST include a Content-Encoding entity-header (section 14.11) that lists the non-identity content-coding(s) used. Lowkey a must-have ๐ซถ
If the content-coding of an entity in a request message is not acceptable to the origin server, the server SHOULD respond with a status code of 415 (Unsupported Media Type). That's the server being picky, and that's valid ๐
If multiple encodings have been applied to an entity, the content codings MUST be listed in the order in which they were applied. Order matters, bestie ๐ Additional information about the encoding parameters MAY be provided by other entity-header fields not defined by this specification โจ
14.12 Content-Language ๐ธ
The Content-Language entity-header field describes the natural language(s) of the intended audience for the enclosed entity. Quick heads up: that might not match every language used inside the entity-body ๐
Content-Language = "Content-Language" ":" 1#language-tag
Language tags are defined in section 3.10. The whole point of Content-Language is letting a user identify and tell apart entities based on their own preferred language ๐ So if the body is only meant for a Danish-literate audience, the field is:
Content-Language: da
If no Content-Language is specified, the default is that the content is intended for all language audiences. 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 ๐คทโโ๏ธ
Multiple languages MAY be listed for content that is intended for multiple audiences. For example, a rendition of the "Treaty of Waitangi," presented at the same time in the original Maori and English versions, would call for:
Content-Language: mi, en
BUT just because an entity has multiple languages in it doesn't mean it's for multiple linguistic audiences ๐ Think about a beginner's language primer, like "A First Lesson in Latin." That's clearly for an English-literate audience, so the Content-Language would properly only include "en" ๐
Content-Language MAY be applied to any media type -- it is not limited to textual documents. Images and audio can have a language too, periodt ๐
14.13 Content-Length ๐ง
The Content-Length entity-header field tells you the size of the entity-body, as a decimal number of OCTETs, that gets sent to the recipient. Or, if it's a HEAD method, the size the entity-body would have been if the request had been a GET ๐
Content-Length = "Content-Length" ":" 1*DIGIT
Here's an example:
Content-Length: 3495
Applications SHOULD use this field to indicate the transfer-length of the message-body, unless this is prohibited by the rules in section 4.4. That's the main move, unless section 4.4 says no ๐
Any Content-Length greater than or equal to zero is a valid value. Section 4.4 explains how to figure out the length of a message-body if there's no Content-Length given ๐ฆ
Heads up, the meaning of this field is really different from the MIME one ๐ญ In MIME it's an optional field used within the "message/external-body" content-type. In HTTP, it SHOULD be sent whenever the message's length can be figured out before it gets transferred, unless section 4.4 prohibits it. Different vibes, same name ๐
14.14 Content-Location ๐
The Content-Location entity-header field MAY be used to supply the resource location for the entity enclosed in the message, when that entity can be reached from a location separate from the requested resource's URI. A server SHOULD provide a Content-Location for the variant that matches the response entity. Especially when a resource has multiple entities attached and each one has its own location to be accessed by, the server SHOULD provide a Content-Location for the particular variant that gets returned. Main character server energy ๐
Content-Location = "Content-Location" ":"
( absoluteURI | relativeURI )
The value of Content-Location also defines the base URI for the entity โจ
The Content-Location value is NOT a replacement for the original requested URI ๐ โโ๏ธ (lol, not caps, my bad, it's just a note). It's only a statement of where the resource for this particular entity lives at the time of the request. Future requests MAY specify the Content-Location URI as the request-URI if they want to identify the source of that particular entity ๐
A cache cannot assume that an entity with a Content-Location different from the URI used to retrieve it can be used to answer later requests on that Content-Location URI. BUT the 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 the Request-URI ๐งญ
The meaning of the Content-Location header in PUT or POST requests is undefined. Servers are free to ignore it in those cases ๐คทโโ๏ธ
14.15 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 provide an end-to-end message integrity check (MIC) of the entity-body ๐ (Quick note: a MIC is good for catching accidental changes to the entity-body in transit, but it's not proof against malicious attacks ๐)
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 or client to work as an integrity check of the entity-body. Only origin servers or clients MAY generate the Content-MD5 header field. Proxies and gateways MUST NOT generate it, because that would defeat its whole purpose 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 on the content of the entity-body, including any content-coding that has been applied. It does NOT include any transfer-encoding applied to the message-body. If the message comes in with a transfer-encoding, that encoding MUST be removed before you check the Content-MD5 value against the received entity ๐งน
This means the digest is 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 so the digest can be computed for MIME composite media-types (for example multipart/* and message/rfc822). But this doesn't change how the digest is computed, as described in the paragraph above ๐ธ
There are a few consequences of this. The entity-body for composite types MAY contain many body-parts, and each one can have 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's assumed that the content of the body-part already has that encoding applied. The body-part then gets included in the Content-MD5 digest as is, meaning after the encoding was applied. The Transfer-Encoding header field is not allowed within body-parts ๐ซ
Conversion of all line breaks to CRLF MUST NOT be done before computing or checking the digest. The line break convention used in the text that's actually transmitted MUST be left unaltered when computing the digest. Don't touch the line breaks, bestie ๐
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 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's 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. Lots of nuance here, and honestly, I'm obsessed ๐ง๐
14.16 Content-Range โจ
okay so Content-Range is the header that shows up when the server is sending just a piece of the entity-body ๐งฉ and it needs to say where that piece goes in the full thing. (Range units are defined in section 3.12, go read that if you're curious ๐ค)
Content-Range = "Content-Range" ":" content-range-spec
content-range-spec = byte-content-range-spec
byte-content-range-spec = bytes-unit SP
byte-range-resp-spec "/"
( instance-length | "*" )
byte-range-resp-spec = (first-byte-pos "-" last-byte-pos)
| "*"
instance-length = 1*DIGIT
The header SHOULD tell you the total length of the full entity-body ๐, unless that length is unknown or hard to figure out. The asterisk * just means "the instance-length isn't known yet" when the response got generated ๐คทโโ๏ธ
Now this is the part I'm obsessed with ๐ญ Unlike byte-ranges-specifier values (see section 14.35.1), a byte-range-resp-spec MUST only specify ONE range, and it MUST contain absolute byte positions for both the first and last byte of that range. No vibes-based ranges, bestie ๐
A byte-content-range-spec is invalid if its last-byte-pos is less than its first-byte-pos, or if its instance-length is less than or equal to its last-byte-pos. Yikes ๐ The recipient of an invalid one MUST ignore it AND any content that came along with it.
A server sending a 416 (Requested range not satisfiable) response SHOULD include a Content-Range field with a byte-range-resp-spec of * ๐ The instance-length tells you the current length of the selected resource. Meanwhile a 206 (Partial Content) response MUST NOT include a Content-Range field with a byte-range-resp-spec of *. Don't mix those up, periodt ๐ซถ
Here are some examples, assuming the entity has 1234 bytes total ๐
- 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 a message carries the content of a single range (like a response to a request for one range, or a request for a bunch of ranges that overlap with no holes), it gets sent with a Content-Range header AND a Content-Length header saying how many bytes actually got 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 a message carries multiple ranges (like a response to a request for several non-overlapping ranges), they get sent as a multipart message ๐ง The multipart media type for this is "multipart/byteranges", as defined in appendix 19.2. See appendix 19.6.3 for a compatibility issue, it's a whole thing ๐
A response to a request for a single range MUST NOT be sent using the multipart/byteranges media type ๐ซ A response to a request for multiple ranges, whose result is a single range, MAY be sent as a multipart/byteranges media type with one part, so that one's allowed ๐ธ And a client that can't decode a multipart/byteranges message MUST NOT ask for multiple byte-ranges in a single request. Know your limits, bestie ๐ซถ
When a client asks for multiple byte-ranges in one request, the server SHOULD send them back in the order they showed up in the request โจ
If the server ignores a byte-range-spec because it's syntactically invalid, the server SHOULD treat the request as if the invalid Range header field never existed. (Usually that means it returns a 200 response with the full entity ๐ฐ)
If the server gets a request (other than one with an If-Range request-header field) with an unsatisfiable Range request-header field, meaning every one of its byte-range-spec values has a first-byte-pos bigger than the current length of the selected resource, it SHOULD return a 416 (Requested range not satisfiable) response (section 10.4.17) ๐ โโ๏ธ
Note: clients cannot depend on servers to send a 416 (Requested range not satisfiable) response instead of a 200 (OK) response for an unsatisfiable Range request-header, since not all servers implement this request-header. ๐ Servers are unreliable, we have to be ready for anything.
14.17 Content-Type ๐
The Content-Type entity-header field tells the recipient what media type the entity-body is ๐ Or, if the method is HEAD, it tells you the media type that would've been sent if the request had been a GET. Iconic behaviour ๐
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, go to section 7.2.1 ๐ง
14.18 Date ๐ฐ๏ธ
The Date general-header field shows the date and time the message was originated, with the same semantics as orig-date in RFC 822 ๐ฎ The field value is an HTTP-date (see section 3.3.1), and it MUST be sent in RFC 1123 [8]-date format. No other format, babe ๐
Date = "Date" ":" HTTP-date
Here's an example:
Date: Tue, 15 Nov 1994 08:12:31 GMT
Origin servers MUST include a Date header field in all responses ๐ BUT there are some exceptions, lowkey:
- If the response status code is 100 (Continue) or 101 (Switching Protocols), the response MAY include a Date header field, totally up to the server ๐คทโโ๏ธ
- If the response status code is a server error, like 500 (Internal Server Error) or 503 (Service Unavailable), and it's inconvenient or impossible to generate a valid Date, then skip it ๐
- If the server doesn't have a clock that can give a reasonable approximation of the current time, its responses MUST NOT include a Date header field. In that case, the rules in section 14.18.1 MUST be followed ๐ฐ๏ธ๐ซ
A received message that doesn't have a Date header field MUST get one assigned by the recipient if the message is going to be cached by that recipient, or gatewayed over a protocol that requires a Date ๐ซถ An HTTP implementation without a clock MUST NOT cache responses without revalidating them on every use, no shortcuts โฐ And an HTTP cache, especially a shared cache, SHOULD use a mechanism like NTP [28] to sync its clock with a reliable external standard ๐
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 client without a clock MUST NOT send a Date header field in a request.
The HTTP-date in a Date header SHOULD NOT be a time after the message was generated ๐ It SHOULD be the best available approximation of when the message was generated, unless the implementation has no way to get a reasonably accurate date and time. In theory, the date should be the moment just before the entity gets generated. In practice, though, it can be generated at any point during message origination without changing its semantic value ๐ง
14.18.1 Clockless Origin Server Operation โณ
Some origin server implementations might not have a clock at all ๐ญ An origin server without a clock MUST NOT assign Expires or Last-Modified values to a response, UNLESS those values were associated with the resource by a system or user that does have a reliable clock. It MAY assign an Expires value that's known, at or before server configuration time, to be in the past. This lets you do "pre-expiration" of responses without storing separate Expires values for each resource, which is honestly so smart ๐ง โจ
14.19 ETag ๐ท๏ธ
The ETag response-header field gives the current value of the entity tag for the requested variant ๐ The headers used with entity tags are described in sections 14.24, 14.26 and 14.44. The entity tag MAY be used for comparison with other entities from the same resource (see section 13.3.3) ๐ฆ
ETag = "ETag" ":" entity-tag
Examples:
ETag: "xyzzy"
ETag: W/"xyzzy"
ETag: ""
14.20 Expect ๐โโ๏ธ
The Expect request-header field is how the client says "hey, these particular server behaviours are required" ๐ซถ
Expect = "Expect" ":" 1#expectation
expectation = "100-continue" | expectation-extension
expectation-extension = token [ "=" ( token | quoted-string )
*expect-params ]
expect-params = ";" token [ "=" ( token | quoted-string ) ]
A server that doesn't understand any of the expectation values in the Expect field, or can't comply with them, MUST respond with an appropriate error status ๐จ The server MUST respond with a 417 (Expectation Failed) status if any of the expectations can't be met. If there are other problems with the request, it can send some other 4xx status instead ๐
This header field has extensible syntax so future stuff can be added ๐ฎ If a server gets a request with an Expect field that includes an expectation-extension it doesn't support, it MUST respond with a 417 (Expectation Failed) status.
Comparing expectation values is case-insensitive for unquoted tokens (including the 100-continue token), but it's case-sensitive for quoted-string expectation-extensions. Be careful with those quotes, bestie ๐
The Expect mechanism is hop-by-hop ๐ That means an HTTP/1.1 proxy MUST return a 417 (Expectation Failed) status if it gets a request with an expectation it can't meet. HOWEVER, the Expect request-header itself is end-to-end, so it MUST be forwarded if the request is forwarded ๐ซถ
Lots of older HTTP/1.0 and HTTP/1.1 applications don't understand the Expect header, so keep that in mind ๐ง
See section 8.2.3 for how the 100 (continue) status is used โจ
14.21 Expires โฐ
The Expires entity-header field gives the date and time after which the response is considered stale ๐ฅ A stale cache entry usually can't be returned by a cache (whether it's a proxy cache or a user agent cache) unless it gets validated first with the origin server, 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 does NOT mean the original resource will change or cease to exist at, before, or after that time. Not the vibe, so don't assume it ๐ โโ๏ธ
The format is an absolute date and time, as defined by HTTP-date in section 3.3.1, and it MUST be in RFC 1123 date format:
Expires = "Expires" ":" HTTP-date
Here's an example of how it's used:
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Note: if a response includes a Cache-Control field with the max-age directive (see section 14.9.3), that directive overrides the Expires field. Max-age wins, periodt ๐
HTTP/1.1 clients and caches MUST treat other invalid date formats, especially including the value "0", as being in the past (aka "already expired") ๐
To mark a response as "already expired," an origin server sends an Expires date that is equal to the Date header value. (For the rules on expiration calculations, see section 13.2.4 ๐งฎ)
To mark a response as "never expires," an origin server sends 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, so don't get carried away ๐
The presence of an Expires header field with a date value in the future on a response that would otherwise be non-cacheable by default indicates that the response is cacheable, unless a Cache-Control header field (section 14.9) says otherwise ๐ซง
14.22 From ๐ฌ
okay bestie, the From header is if given ๐ and when you do send it, it SHOULD contain an Internet e-mail address for the actual human who controls the requesting user agent. That address SHOULD be machine-usable, going by "mailbox" in RFC 822 [9] as updated by RFC 1123 [8]:
From = "From" ":" mailbox
Here's an example:
From: webmaster@w3.org
This header MAY be used for logging and for spotting where invalid or unwanted requests are coming from ๐ต๏ธโโ๏ธ but it SHOULD NOT be used as a sketchy form of access protection, obviously ๐. The whole point is that the request is happening on behalf of the person listed, and that person takes responsibility for whatever method got performed. Robot agents especially SHOULD include this header ๐ค so the person running the robot can be reached if something goes sideways on the other end. ๐ซถ
The e-mail address here MAY be different from the Internet host that actually sent the request. Like, if a request goes through a proxy, the original issuer's address SHOULD be used ๐ง.
Big rule: the client SHOULD NOT send the From header without the user's approval, because it could clash with their privacy or their site's security policy ๐. It's strongly recommended that the user can turn this field on or off, and change its value, at any time before a request goes out ๐ .
14.23 Host ๐
The Host request-header tells the server which Internet host and port number the resource is being requested from, taken from the original URI the user gave or from the referring resource (usually an HTTP URL, see section 3.2.2 โจ). The Host value MUST represent the naming authority of the origin server or gateway given by the original URL. Why does this matter? Because it lets the server tell apart URLs that look the same inside, like the root "/" of a server hosting many host names on one IP address ๐.
Host = "Host" ":" host [ ":" port ] ; Section 3.2.2
A "host" with no trailing port info means the default port for the service (so "80" for an HTTP URL) ๐ธ. For example, a request to the origin server for <http://www.w3.org/pub/WWW/> would properly look like this:
GET /pub/WWW/ HTTP/1.1
Host: www.w3.org
Real talk, these are all MUST-level:
- A client MUST include a Host header field in all HTTP/1.1 request messages ๐ค.
- If the requested URI doesn't include an Internet host name for the service, the Host header field MUST be given with an empty value ๐ซฅ.
- An HTTP/1.1 proxy MUST ensure that any request message it forwards does contain an appropriate Host header field that identifies the service being requested by the proxy ๐ฎ.
- All Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad Request) status code to any HTTP/1.1 request message which lacks a Host header field ๐.
For other Host requirements, check out sections 5.2 and 19.6.1.1 ๐.
14.24 If-Match ๐
The If-Match request-header makes a method conditional. A client that already has one or more entities from the resource can check that one of them is still current by listing their entity tags in the If-Match header. Entity tags are defined in section 3.11 ๐ท๏ธ. The whole vibe is efficient cache updates with as little transaction overhead as possible โจ, and it also stops you from accidentally changing the wrong version of a resource on updating requests ๐ โโ๏ธ. As a special case, "*" 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 come back in the response to a similar GET request (one 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 didn't exist ๐ฆ.
A server MUST use the strong comparison function (see section 13.3.3) 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 super useful when the client wants to stop an updating method, like PUT, from changing a resource that's been modified since the client last grabbed it ๐.
If the request would, without the If-Match header, end in anything other than a 2xx or 412 status, then the If-Match header MUST be ignored ๐ซ .
Soooo, "If-Match: *" means the method SHOULD be performed if the representation picked by the origin server (or by a cache, maybe using the Vary mechanism, see section 14.44) exists, and it MUST NOT be performed if that representation doesn't exist ๐.
A request that's trying to update a resource (like a PUT) MAY include an If-Match header to signal that the method MUST NOT be applied if the entity matching the If-Match value (a single entity tag) is no longer a representation of that resource ๐. The user is basically saying "don't go through if this changed without me knowing" ๐ฅน. Examples:
If-Match: "xyzzy"
If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-Match: *
Also, a request with both an If-Match header and either an If-None-Match or an If-Modified-Since header is undefined by this spec ๐คทโโ๏ธ.
14.25 If-Modified-Since โฐ
The If-Modified-Since request-header makes a method conditional: if the requested variant hasn't been modified since the time in this field, the server won't send an entity back. Instead it'll send a 304 (not modified) response with no message-body ๐.
If-Modified-Since = "If-Modified-Since" ":" HTTP-date
Here's 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 entity only if it's been modified since the date in that header. The algorithm for that includes these cases ๐งฎ:
- a) If the request would normally end in anything other than a 200 (OK) status, or if the If-Modified-Since date is invalid, the response is exactly the same as a normal GET. A date 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 hasn't been modified since a valid If-Modified-Since date, the server SHOULD return a 304 (Not Modified) response ๐ค.
Same energy as before: the purpose is efficient cache updates with minimal transaction overhead ๐ท.
Note: The Range request-header changes what If-Modified-Since means. See section 14.35 for the full tea โ.
Note: The server interprets If-Modified-Since times, and its clock might not be synced with the client's ๐ฐ๏ธ.
Note: When handling an If-Modified-Since header, some servers use an exact date comparison instead of a less-than check to decide whether to send a 304 (Not Modified) response. For the best results when sending If-Modified-Since for cache validation, clients are advised to use the exact date string from a previous Last-Modified header whenever possible ๐ฏ.
Note: If a client uses an arbitrary date in If-Modified-Since instead of one taken from the Last-Modified header for the same request, it should be aware that the server reads this date in its own understanding of time. The client should think about unsynchronized clocks and rounding problems from the different time encodings on each side ๐ง . That includes race conditions if the document changed between the first request and the If-Modified-Since date of a later request, plus clock-skew problems if the date comes from the client's clock without being corrected to the server's clock. Corrections for different time bases between client and server are at best approximate, because of network latency ๐.
Last thing: a request with both an If-Modified-Since header and either an If-Match or an If-Unmodified-Since header is undefined by this specification ๐ซฃ.
14.26 If-None-Match โจ
okay so the If-None-Match request-header field is what makes a request conditional ๐ a client that already has one or more entities from a resource can check that none of them are current by listing their entity tags in this header. the whole point is letting caches update with barely any transaction overhead ๐ it also stops a method like PUT from accidentally overwriting a resource the client thinks doesn't exist ๐
as a special case, the value * matches any current entity of the resource ๐ฆ
If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag )
so if any of the entity tags match the entity tag of the entity that would've come back in the response to a similar GET request (the one 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 ๐ญ the only exception is when it's required to, because the resource's modification date doesn't match the one given in an If-Modified-Since header field in the request. instead, if the request method was GET or HEAD, the server SHOULD respond with a 304 (Not Modified) response, and include the cache-related header fields (especially ETag) from one of the entities that matched ๐ง for every other request method, the server MUST respond with a status of 412 (Precondition Failed) ๐
see section 13.3.3 for the rules on figuring out whether two entity tags match ๐ the weak comparison function can only be used with GET or HEAD requests ๐ธ
if none of the entity tags match, the server MAY perform the requested method as if the If-None-Match header field didn't exist ๐ but it MUST also ignore any If-Modified-Since header field(s) in the request. so basically, if no entity tags match, the server MUST NOT return a 304 (Not Modified) response โจ
if the request would otherwise result in anything other than a 2xx or 304 status without the If-None-Match header field, then the If-None-Match header MUST be ignored ๐ โโ๏ธ (check section 13.3.4 for how the server handles it when both If-Modified-Since and If-None-Match show up in the same request.)
the meaning of If-None-Match: * is that the method MUST NOT be performed if the representation selected by the origin server exists (or by a cache, possibly using the Vary mechanism, see section 14.44). and it SHOULD be performed if the representation doesn't exist ๐ซถ this is super useful for stopping 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: *
the result of a request that has both an If-None-Match header field and either an If-Match or an If-Unmodified-Since header field is undefined by this spec ๐คทโโ๏ธ
14.27 If-Range ๐
okay picture this: a client has a partial copy of an entity in its cache and wants the full up-to-date copy ๐ 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 changed, the client would have to make a second request just to grab the whole current entity-body ๐ฉ
the If-Range header lets the client "short-circuit" that second request ๐ฆ informally, it means 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 tell a valid HTTP-date apart from any form of entity-tag by looking at no more than two characters, which is so clever ๐ง ) the If-Range header SHOULD only be used together with a Range header, and MUST be ignored if the request doesn't include a Range header, or if the server doesn't support the sub-range operation ๐
if the entity tag 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 doesn't match, the server SHOULD return the entire entity using a 200 (OK) response ๐ซถ
14.28 If-Unmodified-Since ๐
the If-Unmodified-Since request-header field makes a method conditional ๐ธ if the requested resource hasn't been modified since the time given in this field, the server SHOULD perform the requested operation as if the If-Unmodified-Since header weren't there at all ๐ฆ
if the requested variant HAS been modified since that 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 (meaning without the If-Unmodified-Since header) result in anything other than a 2xx or 412 status, the If-Unmodified-Since header SHOULD be ignored ๐ โโ๏ธ
if the specified date is invalid, the header is ignored ๐๏ธ
the result of a request that has both an If-Unmodified-Since header field and either an If-None-Match or an If-Modified-Since header field is undefined by this specification ๐คทโโ๏ธ
14.29 Last-Modified ๐
the Last-Modified entity-header field tells you the date and time the origin server believes the variant was last modified โฐ
Last-Modified = "Last-Modified" ":" HTTP-date
an example of how it's used:
Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
what this header means depends on the origin server's implementation and what the original resource actually is ๐ง for files, it might just be the file system's 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 ๐๏ธ and for virtual objects, it might be the last time the internal state changed ๐ป
an origin server MUST NOT send a Last-Modified date that's later than the server's time of message origination ๐ซ if 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 for its response โฑ๏ธ this lets a recipient accurately judge the entity's modification time, especially if the entity changes right around when the response gets generated ๐ฏ
HTTP/1.1 servers SHOULD send Last-Modified whenever that's feasible ๐
14.30 Location ๐ฆ
the Location response-header field redirects the recipient to a location other than the Request-URI, either to finish the request or to identify a new resource ๐บ๏ธ for 201 (Created) responses, the Location is the new resource that the request created ๐ for 3xx responses, the location SHOULD point to the server's preferred URI for automatic redirection to the resource ๐ the field value is a single absolute URI.
Location = "Location" ":" absoluteURI
an example:
Location: http://www.w3.org/pub/WWW/People.html
Note: the Content-Location header field (section 14.14) is different from Location because 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 check section 13.10 for the cache requirements of some methods ๐
14.31 Max-Forwards ๐ฅ
the Max-Forwards request-header field gives you a way, together with the TRACE (section 9.8) and OPTIONS (section 9.2) methods, to limit how many proxies or gateways can forward the request to the next inbound server ๐ this is super handy when a client is trying to trace a request chain that seems to be failing or looping in the middle ๐
Max-Forwards = "Max-Forwards" ":" 1*DIGIT
the Max-Forwards value is a decimal integer that tells you how many more times this request message can be forwarded ๐ข
each proxy or gateway that receives a TRACE or OPTIONS request with a Max-Forwards header field MUST check and update its value before forwarding the request ๐งพ if the received value is zero (0), the recipient MUST NOT forward the request, and instead MUST respond as the final recipient ๐ฌ if the received Max-Forwards value is greater than zero, then the forwarded message MUST contain an updated Max-Forwards field with a value decremented by one (1) โ
the Max-Forwards header field MAY be ignored for all other methods defined by this specification, and for any extension methods that don't explicitly refer to it as part of their method definition ๐
14.32 Pragma ๐ธ
the Pragma general-header field carries implementation-specific directives that might apply to any recipient along the request/response chain ๐ง all pragma directives specify optional behavior from the protocol's point of view, although some systems MAY require that behavior to 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 already 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 backward compatibility with HTTP/1.0 ๐ฐ๏ธ clients SHOULD include both header fields when they send a no-cache request 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, no matter how significant they are to that application ๐ that's because the directives might apply to all recipients along the request/response chain ๐ you can't specify a pragma for one specific recipient, but any pragma directive that isn't relevant to a recipient SHOULD be ignored by that recipient ๐
HTTP/1.1 caches SHOULD treat Pragma: no-cache as if the client had sent Cache-Control: no-cache ๐ and no new Pragma directives will be defined in HTTP ๐
Note: because the meaning ofPragma: no-cacheas a response header field isn't actually specified, it doesn't give you a reliable replacement forCache-Control: no-cachein a response
14.33 Proxy-Authenticate โจ
okay bestie, so the Proxy-Authenticate response header MUST be included in a 407 (Proxy Authentication Required) response ๐ซถ. Its value is a challenge that spells out the auth scheme and params the proxy wants for this Request-URI ๐
Proxy-Authenticate = "Proxy-Authenticate" ":" 1#challenge
The whole HTTP access auth process is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43] ๐. Unlike WWW-Authenticate, this one only applies to the current connection and SHOULD NOT be passed on to downstream clients ๐ โโ๏ธ. BUT an intermediate proxy might need its own creds, so it asks the downstream client for them, and in some situations that looks exactly like the proxy is forwarding Proxy-Authenticate ๐๐ฅ
14.34 Proxy-Authorization ๐
the Proxy-Authorization request header lets the client identify itself (or its user) to a proxy that requires authentication ๐. Its value is credentials with the auth info of the user agent for the proxy and/or the realm of the resource being requested โจ
Proxy-Authorization = "Proxy-Authorization" ":" credentials
The HTTP access auth process is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43]. Unlike Authorization, this header only applies to the next outbound proxy that demanded auth through the Proxy-Authenticate field ๐ฆ. When proxies are chained, the first outbound proxy that was expecting credentials is the one that consumes the Proxy-Authorization header ๐. A proxy MAY relay the credentials from the client request to the next proxy, but only if that's how the proxies cooperatively authenticate a given request ๐ง
14.35 Range ๐
14.35.1 Byte Ranges
okay so since every HTTP entity shows up in messages as a sequence of bytes, byte ranges make sense for any HTTP entity ๐. (Not every client and server has to support byte-range ops tho ๐)
Byte range specs apply to the sequence of bytes in the entity-body, which isn't necessarily the same as the message-body ๐ธ
A byte range operation MAY specify a single range of bytes, or a set of ranges within one 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, so the positions are inclusive. Byte offsets start at zero ๐งฎ
If last-byte-pos is present, it MUST be greater than or equal to the first-byte-pos in that byte-range-spec, or that spec is syntactically invalid ๐ซ. If a recipient gets a byte-range-set with one or more syntactically invalid byte-range-spec values, it MUST ignore the header field that includes that byte-range-set ๐
If last-byte-pos is absent, or if it's greater than or equal to the current length of the entity-body, last-byte-pos is taken to be one less than the current length of the entity-body in bytes ๐ท
by picking its last-byte-pos, a client can limit how many bytes it gets back without knowing the size of the entity ๐
suffix-byte-range-spec = "-" suffix-length
suffix-length = 1*DIGIT
a suffix-byte-range-spec gives you the suffix of the entity-body, with a length from the suffix-length value. (So this form asks for the last N bytes of an entity-body ๐ซถ) If the entity is shorter than the suffix-length, the whole entity-body gets used โจ
If a syntactically valid byte-range-set has at least one byte-range-spec whose first-byte-pos is less than the current length of the entity-body, or at least one suffix-byte-range-spec with a non-zero suffix-length, then the byte-range-set is satisfiable ๐ฅณ. Otherwise it's unsatisfiable. If it's unsatisfiable, the server SHOULD return a response with a status of 416 (Requested range not satisfiable) ๐ญ. Otherwise, the server SHOULD return a response with a status of 206 (Partial Content) containing the satisfiable ranges of the entity-body ๐
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-999bytes=500-700,601-999
14.35.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, using 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 ought to support byte ranges when possible, since Range helps with efficient recovery from partially failed transfers, and with efficient partial retrieval of large entities ๐
If the server supports the Range header and the specified range or ranges are appropriate for the entity:
- 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) ๐
- 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 does NOT affect the 304 (Not Modified) response returned when the conditional is false ๐
Sometimes it's more fitting to use the If-Range header (see section 14.27) alongside the Range header ๐ง
If a proxy that supports ranges gets a Range request, forwards it 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 fits its cache allocation policies ๐๏ธ
14.36 Referer ๐
The Referer[sic] request header lets the client tell the server, for the server's benefit, the address (URI) of the resource the Request-URI was obtained from (the "referrer", even though the header field is misspelled ๐). It lets a server build lists of back-links to resources for interest, logging, optimized caching, etc. It also helps trace obsolete or mistyped links for maintenance ๐ ๏ธ. The Referer field MUST NOT be sent if the Request-URI came from a source that doesn't have its own URI, like input from the user's keyboard โจ๏ธ
Referer = "Referer" ":" ( absoluteURI | relativeURI )
Example:
Referer: http://www.w3.org/hypertext/DataSources/Overview.html
If the field value is a relative URI, it SHOULD be interpreted relative to the Request-URI. The URI MUST NOT include a fragment ๐ซ. See section 15.1.3 for security considerations ๐
14.37 Retry-After โฐ
The Retry-After response header can go with a 503 (Service Unavailable) response to show how long the service is expected to be unavailable to the requesting client ๐ฉ. It MAY also be used with any 3xx (Redirection) response to show the minimum time the user-agent is asked to wait before issuing the redirected request ๐ง. Its value can be an HTTP-date or an integer number of seconds (in decimal) after the time of the response ๐ธ
Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds )
Two examples of how it's used:
Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
Retry-After: 120
In the latter example, the delay is 2 minutes โณโจ
14.38 Server ๐ฅ๏ธ
The Server response header has 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 ๐
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.45) ๐ฆ
Note: revealing the specific software version of the server might make the server machine more vulnerable to attacks against software known to contain security holes ๐ญ๐จ Server implementors are encouraged to make this field a configurable option ๐ซถ
14.39 TE โจ
okay bestie, the TE request-header field is how a client tells the server which extension transfer-codings it's willing to accept in the response, and whether it's cool with trailer fields in a chunked transfer-coding ๐ Its value can be the keyword "trailers", a comma-separated list of extension transfer-coding names, or both, and each name can come with optional accept parameters (see section 3.6) ๐
TE = "TE" ":" #( t-codings )
t-codings = "trailers" | ( transfer-extension [ accept-params ] )
So "trailers" means the client will take trailer fields in a chunked transfer-coding (section 3.6.1) ๐ฆ It's reserved for transfer-coding use even though it isn't a transfer-coding itself, which is very "it's complicated" of it ๐
Some examples, because we love a good example ๐
TE: deflate
TE:
TE: trailers, deflate;q=0.5
The TE header field only applies to the immediate connection, so the keyword MUST be supplied within a Connection header field (section 14.10) whenever TE is present in an HTTP/1.1 message. Not optional, bestie ๐
A server checks whether a transfer-coding is acceptable under a TE field using these rules:
- The "chunked" transfer-coding is always acceptable ๐ธ If the keyword "trailers" is listed, the client is saying it's willing to accept trailer fields in the chunked response for itself AND any downstream clients too. So, if it's there, the client is basically claiming that either every downstream client is fine with trailer fields in the forwarded response, or that it'll buffer the response for the downstream recipients itself ๐ญ
Note: HTTP/1.1 does not define any means to limit the size of a chunked response such that a client can be assured of buffering the entire response.
- If the transfer-coding being tested is one of the transfer-codings listed in the TE field, it's acceptable UNLESS it comes with a qvalue of 0 ๐ (As defined in section 3.9, a qvalue of 0 means "not acceptable." Iconic behavior, honestly โจ)
- If multiple transfer-codings are acceptable, the one with the highest non-zero qvalue wins ๐ The "chunked" transfer-coding always has a qvalue of 1, so it's always on top ๐
If the TE field-value is empty, or there's no TE field at all, the only transfer-coding is "chunked" ๐ง And a message with no transfer-coding is always acceptable, no drama ๐
14.40 Trailer ๐
The Trailer general field value says that the given set of header fields is present in the trailer of a message encoded with chunked transfer-coding ๐
Trailer = "Trailer" ":" 1#field-name
An HTTP/1.1 message SHOULD include a Trailer header field when it uses chunked transfer-coding with a non-empty trailer. This is lowkey essential, because it lets the recipient know which header fields to expect in the trailer ๐ซถ
If there's no Trailer header field, the trailer SHOULD NOT include any header fields ๐ โโ๏ธ Check section 3.6.1 for the restrictions on trailer fields in a "chunked" transfer-coding, periodt ๐
Message header fields listed in the Trailer header field MUST NOT include the following header fields:
- Transfer-Encoding
- Content-Length
- Trailer
Not allowed, not ever ๐
14.41 Transfer-Encoding ๐ฆ
The Transfer-Encoding general-header field indicates what (if any) type of transformation has been applied to the message body so it can be transferred safely between sender and recipient โจ Here's the tea: this is different from content-coding, 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. Here's an example:
Transfer-Encoding: chunked
If multiple encodings have been applied to an entity, the transfer-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 ๐ธ
Heads up though, many older HTTP/1.0 applications don't understand the Transfer-Encoding header at all ๐
14.42 Upgrade ๐
The Upgrade general-header lets the client specify what additional communication protocols it supports and would like to use IF the server finds it appropriate to switch ๐ฆ The server MUST use the Upgrade header field within a 101 (Switching Protocols) response to indicate which protocol(s) are being switched. Non-negotiable, bestie ๐
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'd like to use another protocol, like a later HTTP version with a higher major version number, even though the current request is being made over HTTP/1.1 ๐ This makes the transition between incompatible protocols way smoother, since the client can start the request in the more commonly supported protocol while still telling the server it'd prefer a "better" protocol if one's available. ("Better" is decided by the server, possibly based on the method and/or the resource being requested, so the server's the one with the final say ๐)
Upgrade only applies to switching application-layer protocols on the existing transport-layer connection โจ It CANNOT be used to insist on a protocol change. The server's acceptance and use of it is optional ๐ The capabilities and nature of the application-layer communication after the switch depend entirely on the new protocol chosen. BUT, the first action after changing protocols MUST be a response to the initial HTTP request that contained 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 ๐
Upgrade also cannot be used to switch to a protocol on a different connection. For that, a 301, 302, 303, or 305 redirection response is the better move ๐ฆ
This specification only defines the protocol name "HTTP" for the family of Hypertext Transfer Protocols, following the HTTP version rules of section 3.1 and future updates to this spec ๐ Any token can be used as a protocol name, but it'll only be useful if both the client and server associate that name with the same protocol. Communication, bestie ๐
14.43 User-Agent ๐ธ
The User-Agent request-header field has info about the user agent that sent 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 that identify the agent and any subproducts that make up a significant part of it. By convention, the product tokens are listed in order of how significant they are for identifying the application ๐
User-Agent = "User-Agent" ":" 1*( product | comment )
Example:
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
14.44 Vary ๐
The Vary field value lists the set of request-header fields that fully determines, while the response is fresh, whether a cache is allowed to use the response to answer a later request without revalidation ๐ฆ For uncacheable or stale responses, the Vary field value tells the user agent which criteria were used to select the representation ๐ A Vary value of "*" means a cache can't work out from a later request's headers whether this response is the right representation, so it's a whole mood ๐ See section 13.6 for how caches use the Vary header field.
Vary = "Vary" ":" ( "*" | 1#field-name )
An HTTP/1.1 server SHOULD include a Vary header field with any cacheable response that's subject to server-driven negotiation โจ This lets a cache properly interpret future requests on that resource, and tells the user agent that negotiation is happening on it ๐ A server MAY include a Vary header field with a non-cacheable response that's subject to server-driven negotiation too, since it can give the user agent useful info about the dimensions the response varies over at that moment ๐ซถ
A Vary field value that's a list of field-names means the representation was picked by 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 field names, for as long as the response is fresh ๐
The field-names don't have to be standard request-header fields defined by this spec, and field names are case-insensitive ๐ธ
A Vary value of "" means that unspecified parameters, not limited to request-headers (like the client's network address), play a role in choosing the representation ๐ง The "" value MUST NOT be generated by a proxy server. Only an origin server can generate it ๐
14.45. Via ๐ฆ
okay bestie, the Via header is literally a trail of breadcrumbs ๐โจ. Gateways and proxies MUST use it to show which intermediate protocols and recipients sat between the user agent and the server on requests, and between the origin server and the client on responses. It's the HTTP cousin of the "Received" field from RFC 822 [9], and it's for three things: tracking where messages got forwarded, avoiding request loops, and figuring out the protocol capabilities of every sender along the chain ๐ .
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 is the protocol version the message arrived on at each segment of the chain. It gets tacked onto the Via value when the message is forwarded, so the upstream apps' protocol 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 (and optional port) of the recipient that forwarded the message ๐. But if the real host is sensitive info, it MAY be swapped out for a pseudonym ๐. 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 end result is ordered by the sequence of forwarding apps ๐.
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 the 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 then forwards it to the origin server at www.ics.uci.edu. The request that www.ics.uci.edu receives would have this Via header ๐ฆ:
Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
Proxies and gateways acting 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 be propagated if it's explicitly enabled. If it isn't 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 requirements about hiding internal structures, a proxy MAY combine an ordered subsequence of Via entries that have identical received-protocol values into one single entry. For example:
Via: 1.0 ricky, 1.1 ethel, 1.1 fred, 1.0 lucy
could be collapsed to
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 ๐ซ.
14.46. Warning โ ๏ธ
The Warning header carries extra info about the status or transformation of a message that might not otherwise show up in the message itself. It's usually there to flag a possible loss of semantic transparency from caching or from transformations applied to the entity body ๐.
Warning headers get sent with responses, using this grammar:
Warning = "Warning" ":" 1#warning-value
warning-value = warn-code SP warn-agent SP warn-text
[SP warn-date]
warn-code = 3DIGIT
warn-agent = ( host [ ":" port ] ) | pseudonym
; the name or pseudonym of the server adding
; the Warning header, for use in debugging
warn-text = quoted-string
warn-date = <"> HTTP-date <">
A response MAY carry more than one Warning header ๐.
The warn-text SHOULD be in a natural language and character set that's most likely to be understood by the human user receiving the response ๐ธ. That choice MAY be based on any available knowledge, like where the cache or user is, the Accept-Language field in a request, the Content-Language field in a response, and so on. 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 2047 [14] ๐งพ.
Warning headers can generally go on any message, but some warn-codes are specific to caches and can only go on response messages. New Warning headers SHOULD be added after any existing ones. A cache MUST NOT delete any Warning header it received with a message. However, 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 ought to tell the user as many of them as it can, in the order they appear in the response. If it's not possible to inform the user of all of them, 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 ๐ .
Requirements for how caches behave with respect to Warnings are stated in section 13.1.2 ๐ง .
Here's the list of the warn-codes defined right now. Each one has a recommended English warn-text and a description of what it means โจ.
110 Response is stale: MUST be included whenever the returned response is stale.111 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.112 Disconnected operation: SHOULD be included if the cache is intentionally disconnected from the rest of the network for a period of time.113 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.199 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, besides presenting the warning to the user.214 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, or the entity-body of the response, unless this Warning code already appears in the response.299 Miscellaneous persistent 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.
If an implementation sends a message with one or more Warning headers whose version is HTTP/1.0 or lower, then the sender MUST include in each warning-value a warn-date that matches the date in the response ๐ .
If an implementation receives a message with a warning-value that includes a warn-date, and that warn-date is different from the Date value in the response, then that warning-value MUST be deleted from the message before storing, forwarding, or using it. (This prevents bad consequences of naive caching of Warning header fields ๐ .) If all of the warning-values get deleted for this reason, the Warning header MUST be deleted as well.
14.47. WWW-Authenticate ๐
The WWW-Authenticate response-header MUST be included in 401 (Unauthorized) response messages. Its value is at least one challenge that indicates the authentication scheme(s) and parameters that apply to the Request-URI ๐๏ธ.
WWW-Authenticate = "WWW-Authenticate" ":" 1#challenge
The HTTP access authentication process is described in "HTTP Authentication: Basic and Digest Access Authentication" [43]. User agents are advised to be extra careful when parsing the WWW-Authenticate value ๐ง. It might contain more than one challenge, or more than one WWW-Authenticate header might be provided, and the contents of a challenge can themselves contain a comma-separated list of authentication parameters.
15. Security Considerations ๐ฅ
This section is here to inform app developers, info providers, and users about the security limitations of HTTP/1.1 as described by this document. It doesn't include definitive solutions to the problems revealed, though it does make some suggestions for reducing security risks ๐ก๏ธ.
15.1. Personal Information ๐ซฃ
HTTP clients are often privy to huge amounts of personal information (e.g. the user's name, location, mail address, passwords, encryption keys, etc.), and they SHOULD be very careful to prevent unintentional leakage of this information via the HTTP protocol to other sources ๐จ. We very strongly recommend that a convenient interface be provided so the user can control dissemination of such information, and that designers and implementors be particularly careful in this area. History shows that errors here often create serious security and/or privacy problems and generate highly adverse publicity for the implementor's company ๐.
15.1.1. Abuse of Server Log Information ๐ต๏ธ
A server is in the position to save personal data about a user's requests, which might identify their reading patterns or subjects of interest. This info is clearly confidential in nature, and its handling can be constrained by law in certain countries ๐. People using the HTTP protocol to provide data are responsible for making sure such material isn't distributed without the permission of any individuals who are identifiable by the published results ๐ซถ.
15.1.2. Transfer of Sensitive Information โจ
Okay so bestie, HTTP is a generic data transfer protocol, which means it literally cannot regulate what's inside the data it moves ๐. There's also no way to know ahead of time how sensitive a piece of info is inside any given request. So applications SHOULD give the info provider as much control over it as possible ๐ซถ. Four header fields deserve special mention here: Server, Via, Referer and From ๐ฆ.
Revealing the exact software version of the server could make the server machine more vulnerable to attacks on software that's known to have security holes ๐ญ. Implementors 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 header lets people study reading patterns and draw reverse links ๐. It can be super useful, but its power can be abused if user details aren't separated from the info in the Referer. Even when the personal info has been removed, the Referer header might still reveal a private document's URI, and publishing that would be inappropriate ๐.
The info sent in the From field might clash with the user's privacy interests or their site's security policy ๐. So it SHOULD NOT be transmitted unless the user can disable, enable, and modify the contents of the field. The user MUST be able to set the contents of this field within a user preference or application defaults configuration.
We suggest, though do not require, that a convenient toggle interface be provided so the user can enable or disable sending From and Referer info ๐.
The User-Agent (section 14.43) or Server (section 14.38) header fields can sometimes be used to figure out that a specific client or server has a particular security hole that might get exploited ๐. Unfortunately, that same info is often used for other valuable purposes, and HTTP doesn't currently have a better mechanism for them ๐ญ.
15.1.3. Encoding Sensitive Information in URI's ๐ธ
Because the source of a link might be private info, or might reveal an otherwise private info 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 or anonymously, which would enable or disable sending Referer and From info respectively ๐.
Clients SHOULD NOT include a Referer header field in a (non-secure) HTTP request if the referring page was transferred with a secure protocol ๐.
Authors of services that use the HTTP protocol SHOULD NOT use GET based forms for submitting sensitive data ๐ซ, because that causes the data to be encoded in the Request-URI. Many existing servers, proxies, and user agents log the request URI somewhere it might be visible to third parties ๐. Servers can use POST-based form submission instead
15.1.4. 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 in particular can reveal info the user would consider private, because understanding particular languages is often strongly correlated with membership of a particular ethnic group ๐ญ. User agents that offer an option to configure the contents of an Accept-Language header to be sent in every request are strongly encouraged to have that configuration process include a message that makes the user aware of the privacy loss involved ๐.
One way to limit the privacy loss is for a user agent to leave out Accept-Language headers by default. It can then detect, by looking for any Vary response-header fields generated by the server, that sending them could improve the quality of service, and ask the user whether to start sending them to that server ๐.
Elaborate, user-customized accept header fields sent in every request can be used by servers as pretty reliable, long-lived user identifiers, especially if they include quality values ๐ต๏ธ. Those identifiers would let content providers do click-trail tracking, and let collaborating content providers match cross-server click-trails or form submissions of individual users ๐ณ. For lots of users not behind a proxy, the network address of the host running the user agent will also work as a long-lived user identifier ๐. In environments where proxies are used to enhance privacy, user agents ought to be conservative about offering accept header configuration options to end users ๐ซฃ. As an extreme privacy measure, proxies could filter the accept headers in relayed requests โจ. General purpose user agents that offer a high degree of header configurability SHOULD warn users about the loss of privacy that can be involved ๐ฅ.
15.2. Attacks Based On File and Path Names ๐๏ธ
Implementations of HTTP origin servers SHOULD be careful to restrict the documents returned by HTTP requests to only the ones the server administrators intended ๐ . If an HTTP server translates HTTP URIs directly into file system calls, the server MUST take special care not to serve files that weren't meant to be delivered to HTTP clients ๐จ. For example, UNIX, Microsoft Windows, and other operating systems use ".." as a path component to mean a directory level above the current one ๐. On a system like that, an HTTP server MUST disallow any such construct in the Request-URI if it would otherwise allow access to a resource outside those intended to be accessible via the HTTP server. Similarly, files meant only for internal reference by the server (such as access control files, configuration files, and script code) MUST be protected from inappropriate retrieval, since they might contain sensitive information ๐ญ. Experience has shown that minor bugs in such HTTP server implementations have turned into security risks ๐.
15.3. DNS Spoofing ๐ญ
Clients using HTTP rely heavily on the Domain Name Service, so they're generally prone to security attacks based on deliberate mis-association of IP addresses and DNS names ๐ฌ. Clients need to be cautious about assuming that an IP number/DNS name association is still valid ๐ง.
In particular, HTTP clients SHOULD rely on their name resolver to confirm an IP number/DNS name association, instead of caching the results of previous host name lookups ๐. Many platforms can already cache host name lookups locally when appropriate, and they SHOULD be configured to do so โญ. It's only proper for these lookups to be cached, however, when the TTL (Time To Live) info reported by 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 HTTP clients don't follow this rule, they could get spoofed when a previously accessed server's IP address changes ๐ฑ. Since network renumbering is expected to become more and more common [24], the chance of this attack will grow. Following this requirement cuts down on this potential security vulnerability ๐ก๏ธ.
This requirement also improves load-balancing behavior for clients using replicated servers with the same DNS name, and it lowers the odds of a user failing to access sites that use that strategy ๐.
15.4. Location Headers and Spoofing ๐
If a single server supports multiple organizations that don't trust each other, then it MUST check the values of Location and Content-Location headers in responses generated under control of those organizations ๐ต๏ธ. It needs to make sure they don't try to invalidate resources they have no authority over ๐ซ.
15.5. Content-Disposition Issues ๐
RFC 1806 [35], which the often implemented Content-Disposition header in HTTP (see section 19.5.1) is derived from, has a bunch of very serious security considerations ๐ฌ. Content-Disposition isn't part of the HTTP standard, but since it's widely implemented, we're documenting its use and risks for implementors ๐. See RFC 2183 [49] (which updates RFC 1806) for details ๐.
15.6. Authentication Credentials and Idle Clients ๐
Existing HTTP clients and user agents typically keep authentication info indefinitely ๐ณ. HTTP/1.1. doesn't give a server a method to tell clients to discard these cached credentials. This is a significant defect that needs further extensions to HTTP ๐. Here are some situations where credential caching can mess with the application's security model, though the list isn't limited to these ๐:
- Clients that have been idle for a long time, after which the server might want the client to reprompt the user for credentials โฐ.
- Applications that include a session termination indication (such as a
logout'orcommit'button on a page) after which the server side of the application "knows" there's no further reason for the client to keep the credentials ๐ โโ๏ธ.
This is currently under separate study ๐งช. There are a number of work-arounds for parts of this problem, and we encourage using password protection in screen savers, idle time-outs, and other methods that reduce the security problems inherent in this issue ๐ซถ. In particular, user agents that cache credentials are encouraged to provide an easy-to-reach mechanism for discarding cached credentials under user control ๐ .
15.7 Proxies and Caching โจ
Okay bestie, proxies are literally men-in-the-middle by design ๐ญ, which makes them a juicy target for man-in-the-middle attacks ๐. If the machine a proxy runs on gets compromised, it's a whole disaster. Proxies can see security-related info, personal info about users and organizations, and proprietary info belonging to users and content providers ๐. A compromised proxy, or one set up without thinking about security and privacy, could be used for a wide range of potential attacks ๐ฅ.
Proxy operators should protect the systems their proxies run on, the same way they'd protect any system that holds or carries sensitive info ๐ซถ. Log info collected at proxies often has highly sensitive personal info and/or info about organizations, so it needs to be carefully guarded, with guidelines for its use developed and followed (Section 15.1.1). Main character energy means treating those logs like gold ๐.
Caching proxies add extra vulnerabilities ๐งบ, since the cache is an attractive target for malicious exploitation. Cache contents stick around after an HTTP request is done, so an attack on the cache can reveal info long after a user thinks it's been removed from the network ๐. So cache contents should be protected as sensitive information.
Proxy implementors should consider the privacy and security implications of their design and coding decisions, and of the configuration options they give proxy operators (especially the default configuration) ๐ .
Users of a proxy need to be aware that they're no more trustworthy than the people who run the proxy ๐ค. HTTP itself can't solve this one.
The judicious use of cryptography, when appropriate, may suffice to protect against a broad range of security and privacy attacks ๐. That cryptography is beyond the scope of the HTTP/1.1 specification.
15.7.1 Denial of Service Attacks on Proxies
They exist. They are hard to defend against. Research continues. Beware. ๐๐
16 Acknowledgments โจ
This specification makes heavy use of the augmented BNF and generic constructs defined by David H. Crocker for RFC 822 [9]. Similarly, it reuses many of the definitions provided by Nathaniel Borenstein and Ned Freed for MIME [7]. We hope that including them here helps reduce past confusion over the relationship between HTTP and Internet mail message formats ๐.
The HTTP protocol has evolved considerably over the years ๐ธ. It has benefited from a large and active developer community (the many people who have participated on the www-talk mailing list), and that community has been most responsible for the success of HTTP and of the World-Wide Web in general ๐ซถ. 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 special recognition for their efforts in defining early aspects of the protocol ๐.
This document has benefited greatly from the comments of everyone participating in the HTTP-WG. In addition to those already mentioned, the following individuals have contributed to this specification ๐ง:
Gary Adams Ross Patterson
Harald Tveit Alvestrand Albert Lunde
Keith Ball John C. Mallery
Brian Behlendorf Jean-Philippe Martin-Flatin
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 Josh Cohen
Much of the content and presentation of the caching design is thanks to suggestions and comments from individuals including Shel Kaphan, Paul Leach, Koen Holtman, David Morris, and Larry Masinter ๐.
Most of the specification of ranges is based on work originally done by Ari Luotonen and John Franks, with additional input from Steve Zilles ๐.
Thanks to the "cave men" of Palo Alto. You know who you are ๐ฆ.
Jim Gettys (the current editor of this document) wishes particularly to thank Roy Fielding, the previous editor of this document, along with John Klensin, Jeff Mogul, Paul Leach, Dave Kristol, Koen Holtman, John Franks, Josh Cohen, Alex Hopmann, Scott Lawrence, and Larry Masinter for their help โจ. And thanks go particularly to Jeff Mogul and Scott Lawrence for performing the "MUST/MAY/SHOULD" audit ๐.
The Apache Group, Anselm Baird-Smith, author of Jigsaw, and Henrik Frystyk implemented RFC 2068 early, and we wish to thank them for discovering many of the problems that this document attempts to rectify ๐.
17 References โจ
okay bestie, the bibliography is literally where all the receipts live ๐งพ๐ every single source is listed below, with all the details, so you can go find them yourself if you want to go down a rabbit hole ๐
- [1] Alvestrand, H., "Tags for the Identification of Languages", RFC 1766, 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, March 1993.
- [3] Berners-Lee, T., "Universal Resource Identifiers in WWW", RFC 1630, June 1994.
- [4] Berners-Lee, T., Masinter, L. and M. McCahill, "Uniform Resource Locators (URL)", RFC 1738, December 1994.
- [5] Berners-Lee, T. and D. Connolly, "Hypertext Markup Language - 2.0", RFC 1866, November 1995.
- [6] Berners-Lee, T., Fielding, R. and H. Frystyk, "Hypertext Transfer Protocol -- HTTP/1.0", RFC 1945, May 1996.
- [7] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC 2045, November 1996.
- [8] Braden, R., "Requirements for Internet Hosts -- Communication Layers", STD 3, RFC 1123, October 1989.
- [9] Crocker, D., "Standard for The Format of ARPA Internet Text Messages", STD 11, RFC 822, 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, June 1995.
- [12] Horton, M. and R. Adams, "Standard for Interchange of USENET Messages", RFC 1036, December 1987.
- [13] Kantor, B. and P. Lapsley, "Network News Transfer Protocol", RFC 977, February 1986.
- [14] Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text", RFC 2047, November 1996.
- [15] Nebel, E. and L. Masinter, "Form-based File Upload in HTML", RFC 1867, November 1995.
- [16] Postel, J., "Simple Mail Transfer Protocol", STD 10, RFC 821, August 1982.
- [17] Postel, J., "Media Type Registration Procedure", RFC 1590, November 1996.
- [18] Postel, J. and J. Reynolds, "File Transfer Protocol", STD 9, RFC 959, October 1985.
- [19] Reynolds, J. and J. Postel, "Assigned Numbers", STD 2, RFC 1700, October 1994.
- [20] Sollins, K. and L. Masinter, "Functional Requirements for Uniform Resource Names", RFC 1737, 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, October 1995.
- [24] Carpenter, B. and Y. Rekhter, "Renumbering Needs Work", RFC 1900, February 1996.
- [25] Deutsch, P., "GZIP file format specification version 4.3", RFC 1952, 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 Conference '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/touch/pubs/http-perf96/>, ISI Research Report ISI/RR-98-463, (original report dated Aug. 1996), USC/Information Sciences Institute, August 1998.
- [28] Mills, D., "Network Time Protocol (Version 3) Specification, Implementation and Analysis", RFC 1305, March 1992.
- [29] Deutsch, P., "DEFLATE Compressed Data Format Specification version 1.3", RFC 1951, May 1996.
- [30] S. Spero, "Analysis of HTTP Performance Problems," http://sunsite.unc.edu/mdma-release/http-prob.html.
- [31] Deutsch, P. and J. Gailly, "ZLIB Compressed Data Format Specification version 3.3", RFC 1950, 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.
- [33] Fielding, R., Gettys, J., Mogul, J., Frystyk, H. and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2068, January 1997.
- [34] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
- [35] Troost, R. and Dorner, S., "Communicating Presentation Information in Internet Messages: The Content-Disposition Header", RFC 1806, June 1995.
- [36] Mogul, J., Fielding, R., Gettys, J. and H. Frystyk, "Use and Interpretation of HTTP Version Numbers", RFC 2145, May 1997. [jg639]
- [37] Palme, J., "Common Internet Message Headers", RFC 2076, February 1997. [jg640]
- [38] Yergeau, F., "UTF-8, a transformation format of Unicode and ISO-10646", RFC 2279, January 1998. [jg641]
- [39] Nielsen, H.F., Gettys, J., Baird-Smith, A., Prud'hommeaux, E., Lie, H., and C. Lilley. "Network Performance Effects of HTTP/1.1, CSS1, and PNG," Proceedings of ACM SIGCOMM '97, Cannes France, September 1997.[jg642]
- [40] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types", RFC 2046, November 1996. [jg643]
- [41] Alvestrand, H., "IETF Policy on Character Sets and Languages", BCP 18, RFC 2277, January 1998. [jg644]
- [42] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform Resource Identifiers (URI): Generic Syntax and Semantics", RFC 2396, August 1998. [jg645]
- [43] Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S., Leach, P., Luotonen, A., Sink, E. and L. Stewart, "HTTP Authentication: Basic and Digest Access Authentication", RFC 2617, June 1999. [jg646]
- [44] Luotonen, A., "Tunneling TCP based protocols through Web proxy servers," Work in Progress. [jg647]
- [45] Palme, J. and A. Hopmann, "MIME E-mail Encapsulation of Aggregate Documents, such as HTML (MHTML)", RFC 2110, March 1997.
- [46] Bradner, S., "The Internet Standards Process -- Revision 3", BCP 9, RFC 2026, October 1996.
- [47] Masinter, L., "Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0)", RFC 2324, 1 April 1998.
- [48] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Five: Conformance Criteria and Examples", RFC 2049, November 1996.
- [49] Troost, R., Dorner, S. and K. Moore, "Communicating Presentation Information in Internet Messages: The Content-Disposition Header Field", RFC 2183, August 1997.
18 Authors' Addresses ๐
these are the lovely people who wrote the whole thing, and where you can reach them ๐ซถ the contact details are copied exactly as they appear in the document:
Roy T. Fielding
Information and Computer Science
University of California, Irvine
Irvine, CA 92697-3425, USA
Fax: +1 (949) 824-1715
EMail: fielding@ics.uci.edu
James Gettys
World Wide Web Consortium
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
Compaq Computer Corporation
250 University Avenue
Palo Alto, California, 94305, USA
EMail: mogul@wrl.dec.com
Henrik Frystyk Nielsen
World Wide Web Consortium
MIT Laboratory for Computer Science
545 Technology Square
Cambridge, MA 02139, USA
Fax: +1 (617) 258 8682
EMail: frystyk@w3.org
Larry Masinter
Xerox Corporation
3333 Coyote Hill Road
Palo Alto, CA 94034, USA
EMail: masinter@parc.xerox.com
Paul J. Leach
Microsoft Corporation
1 Microsoft Way
Redmond, WA 98052, USA
EMail: paulle@microsoft.com
Tim Berners-Lee
Director, World Wide Web 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 and application/http ๐จ
okay so this appendix is the official paperwork for two media types ๐งพโจ besides defining HTTP/1.1, this document also acts as the spec for "message/http" and "application/http". ๐ the message/http one can wrap a single HTTP request or response, as long as it follows the MIME rules for "message" types about line length and encodings ๐ the application/http one can wrap a pipeline of one or more HTTP requests or responses, which are not intermixed ๐ฆ the registration details go to IANA [17], and they look like this:
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
Media Type name: application
Media subtype name: http
Required parameters: none
Optional parameters: version, msgtype
version: The HTTP-Version number of the enclosed messages
(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: HTTP messages enclosed by this type
are in "binary" format; use of an appropriate
Content-Transfer-Encoding is required when
transmitted via E-mail.
Security considerations: none
that's the whole media type paperwork, bestie! ๐๐ฅ
19.2. Internet Media Type multipart/byteranges
Okay bestie, so when an HTTP 206 (Partial Content) response includes the content of multiple ranges (a response to a request for multiple non-overlapping ranges) ๐งฉ, it gets sent as a multipart message-body โจ. The media type for this is called multipart/byteranges ๐.
The multipart/byteranges media type includes two or more parts, and each part has its own Content-Type and Content-Range fields ๐. The required boundary parameter is the boundary string that separates each body-part ๐ฆ.
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
Here's an example, because examples are everything ๐ธ:
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--
Some notes for you, bestie ๐:
- Additional CRLFs may precede the first boundary string in the entity.
- Although RFC 2046 [40] permits the boundary string to be quoted, some existing implementations handle a quoted boundary string incorrectly. ๐
- A number of browsers and servers were coded to an early draft of the byteranges specification to use a media type of
multipart/x-byteranges, which is almost, but not quite, compatible with the version documented in HTTP/1.1 ๐
19.3. Tolerant Applications
Okay so, this document lays out the requirements for generating HTTP/1.1 messages, but not every app is going to get it perfectly right ๐ญ. We therefore recommend that operational applications be tolerant of deviations whenever those deviations can be interpreted unambiguously ๐ซถ.
Clients SHOULD be tolerant in parsing the Status-Line, and servers tolerant when parsing the Request-Line ๐. In particular, they SHOULD accept any amount of SP or HT characters between fields, even though only a single SP is required โจ.
The line terminator for message-header fields is the sequence CRLF. However, we recommend that applications, when parsing such headers, recognize a single LF as a line terminator and ignore the leading CR ๐.
The character set of an entity-body SHOULD be labeled as the lowest common denominator of the character codes used within that body, with the exception that not labeling the entity is preferred over labeling the entity with the labels US-ASCII or ISO-8859-1 ๐
. See section 3.7.1 and 3.4.1.
Here are the extra rules for parsing and encoding dates, plus other date drama to watch out for ๐ :
- HTTP/1.1 clients and caches SHOULD assume that an RFC-850 date which appears to be more than 50 years in the future is in fact in the past (this helps solve the "year 2000" problem) ๐.
- An HTTP/1.1 implementation MAY internally represent a parsed Expires date as earlier than the proper value, but MUST NOT internally represent a parsed Expires date 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 incorrectly carries a date value 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 RFC 2045 Entities
HTTP/1.1 borrows a lot of constructs from Internet Mail (RFC 822 [9]) and the Multipurpose Internet Mail Extensions (MIME [7]) so entities can be sent in an open variety of representations with extensible mechanisms ๐ธ. But RFC 2045 is all about mail, and HTTP has a few features that are different from what RFC 2045 describes ๐. These differences were carefully chosen to optimize performance over binary connections, to allow greater freedom in the use of new media types, to make date comparisons easier, and to acknowledge the practice of some early HTTP servers and clients ๐.
This appendix describes the specific areas where HTTP differs from RFC 2045. Proxies and gateways to strict MIME environments SHOULD be aware of these differences and provide the appropriate conversions where necessary ๐. Proxies and gateways from MIME environments to HTTP also need to be aware of the differences, because some conversions might be required โจ.
19.4.1. MIME-Version
HTTP is not a MIME-compliant protocol ๐. However, HTTP/1.1 messages MAY include a single MIME-Version general-header field to indicate what version of the MIME protocol was used to construct the message. Use of the MIME-Version header field indicates that the message is in full compliance with the MIME protocol (as defined in RFC 2045[7]). Proxies/gateways are responsible for ensuring full compliance (where possible) when exporting 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. However, HTTP/1.1 message parsing and semantics are defined by this document and not the MIME specification ๐.
19.4.2. Conversion to Canonical Form
RFC 2045 [7] requires that an Internet mail entity be converted to canonical form prior to being transferred, as described in section 4 of RFC 2049 [48] ๐ฌ. Section 3.7.1 of this document describes the forms allowed for subtypes of the "text" media type when transmitted over HTTP. RFC 2046 requires that content with a type of "text" represent line breaks as CRLF and forbids the use of CR or LF outside of line break sequences. HTTP allows CRLF, bare CR, and bare LF to indicate a line break within text content when a message is transmitted over HTTP ๐ซง.
Where it is possible, a proxy or gateway from HTTP to a strict MIME environment SHOULD translate all line breaks within the text media types described in section 3.7.1 of this document to the RFC 2049 canonical form of CRLF. Note, however, that this might be complicated by the presence of a Content-Encoding, and by the fact that HTTP allows the use of some character sets which do not use octets 13 and 10 to represent CR and LF, as is the case for some multi-byte character sets ๐.
Implementors should note that conversion will break any cryptographic checksums applied to the original content unless the original content is already in canonical form. Therefore, the canonical form is recommended for any content that uses such checksums in HTTP ๐.
19.4.3. Conversion of Date Formats
HTTP/1.1 uses a restricted set of date formats (section 3.3.1) to simplify the process of date comparison ๐๏ธ. Proxies and gateways from other protocols SHOULD ensure that any Date header field present in a message conforms to one of the HTTP/1.1 formats, and rewrite the date if necessary ๐ .
19.4.4. Introduction of Content-Encoding
RFC 2045 does not include any concept equivalent to HTTP/1.1's Content-Encoding header field. Since this acts as a modifier on the media type, proxies and gateways 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 applications of Content-Type for Internet mail have used a media-type parameter of ;conversions=<content-coding> to perform a function equivalent to Content-Encoding. However, this parameter is not part of RFC 2045.) ๐ง
19.4.5. No Content-Transfer-Encoding
HTTP does not use the Content-Transfer-Encoding (CTE) field of RFC 2045 ๐ โโ๏ธ. Proxies and gateways from MIME-compliant protocols to HTTP MUST remove any non-identity CTE ("quoted-printable" or "base64") encoding prior to delivering the response message to an HTTP client ๐งน.
Proxies and gateways from HTTP to MIME-compliant protocols are responsible for ensuring that the message is in the correct format and encoding for safe transport on that protocol, where "safe transport" is defined by the limitations of the protocol being used. Such a proxy or gateway SHOULD label the data with an appropriate Content-Transfer-Encoding if doing so will improve the likelihood of safe transport over the destination protocol โจ.
19.4.6. Introduction of Transfer-Encoding
HTTP/1.1 introduces the Transfer-Encoding header field (section 14.41) ๐. Proxies/gateways MUST remove any transfer-coding prior to forwarding a message via a MIME-compliant protocol ๐ซถ.
A process for decoding the "chunked" transfer-coding (section 3.6) can be represented in pseudo-code as:
length := 0
read chunk-size, chunk-extension (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. MHTML and Line Length Limitations
HTTP implementations which share code with MHTML [45] implementations need to be aware of MIME line length limitations ๐. Since HTTP does not have this limitation, HTTP does not fold long lines ๐ฆ. MHTML messages being transported by HTTP follow all conventions of MHTML, including line length limitations and folding, canonicalization, etc., since HTTP transports all message-bodies as payload (see section 3.7.2) and does not interpret the content or any MIME header lines that might be contained therein ๐ง.
19.5. Additional Features
RFC 1945 and RFC 2068 document protocol elements used by some existing HTTP implementations, but not consistently and correctly across most HTTP/1.1 applications ๐. Implementors are advised to be aware of these features, but cannot rely upon their presence in, or interoperability with, other HTTP/1.1 applications. Some of these describe proposed experimental features, and some describe features that experimental deployment found lacking that are now addressed in the base HTTP/1.1 specification ๐.
A number of other headers, such as Content-Disposition and Title, from SMTP and MIME are also often implemented (see RFC 2076 [37]) ๐.
19.5.1. Content-Disposition ๐
okay so Content-Disposition is a response header field that lets the origin server suggest a default filename when the user wants to save the content to a file ๐โจ. It's derived from how RFC 1806 [35] defined Content-Disposition, so it has history, bestie ๐ง
content-disposition = "Content-Disposition" ":"
disposition-type *( ";" disposition-parm )
disposition-type = "attachment" | disp-extension-token
disposition-parm = filename-parm | disp-extension-parm
filename-parm = "filename" "=" quoted-string
disp-extension-token = token
disp-extension-parm = token "=" ( token | quoted-string )
An example is:
Content-Disposition: attachment; filename="fname.ext"
The receiving user agent SHOULD NOT respect any directory path information present in the filename-parm parameter, which is the only parameter believed to apply to HTTP implementations at this time. The filename SHOULD be treated as a terminal component only. ๐ โโ๏ธ๐๏ธ so the filename is just a name, not a whole path. no directory vibes allowed ๐
If this header is used in a response with the application/octet-stream content-type, the implied suggestion is that the user agent should not display the response, but directly enter a `save response as...' dialog. ๐ฅ basically "don't open this, just save it" energy.
See section 15.5 for Content-Disposition security issues. ๐จ Please go read that one, it's giving serious danger zone vibes.
19.6. Compatibility with Previous Versions ๐ฆ
okay so it's beyond the scope of a protocol spec to force anyone to stay compatible with older versions ๐ but HTTP/1.1 was deliberately built to make supporting previous versions easy, which is so thoughtful ๐ฅน Worth noting: when this spec was written (1996), they expected 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 they expected 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. Some implementations use the Keep-Alive version of persistent connections described in section 19.7.1 of RFC 2068 [33]. ๐งธ
19.6.1. Changes from HTTP/1.0 ๐ธ
This section gives the big picture on the major differences between HTTP/1.0 and HTTP/1.1 โจ
19.6.1.1. Changes to Simplify Multi-homed Web Servers and Conserve IP Addresses ๐
the requirements that clients and servers support the Host request-header, report an error if the Host request-header (section 14.23) is missing from an HTTP/1.1 request, and accept absolute URIs (section 5.1.2) are some of the most important changes in this spec ๐ no cap.
Old HTTP/1.0 clients assumed one IP address per server, because there was no other established way to tell which server a request was meant for besides the IP address it was sent to ๐ The changes above will let the Internet, once older HTTP clients aren't common anymore, host multiple websites on a single IP address. That makes big operational Web servers way simpler, where giving one host tons of IP addresses caused serious problems ๐ The Internet could also get back IP addresses that were only handed out so special-purpose domain names could be used in root-level HTTP URLs. Given how fast the Web grew and how many servers are already out there, it's extremely important that all HTTP implementations (including updates to existing HTTP/1.0 apps) correctly implement these requirements:
- Both clients and servers MUST support the Host request-header.
- A client that sends an HTTP/1.1 request MUST send a Host header.
- Servers MUST report a 400 (Bad Request) error if an HTTP/1.1 request does not include a Host request-header.
- Servers MUST accept absolute URIs.
19.6.2. Compatibility with HTTP/1.0 Persistent Connections ๐งต
Some clients and servers might want to stay compatible with older implementations of persistent connections in HTTP/1.0 clients and servers. In HTTP/1.0, persistent connections are explicitly negotiated because they aren't the default behavior. The HTTP/1.0 experimental implementations were faulty, and HTTP/1.1's new facilities were designed to fix those problems ๐ง The problem was that some existing 1.0 clients may 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 HTTP/1.0 proxy would end up hung, waiting for the close on the response ๐ญ The result is that 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 ๐ โโ๏ธ So we need some other mechanism for indicating a persistent connection is desired, one that's safe to use 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. See section 14.10. ๐ซถ
The original HTTP/1.0 form of persistent connections (the Connection: Keep-Alive and Keep-Alive header) is documented in RFC 2068. [33]
19.6.3. Changes from RFC 2068 ๐
This specification has been carefully audited to correct and disambiguate key word usage. RFC 2068 had many problems with the conventions laid out in RFC 2119 [34] ๐ค
Clarified which error code should be used for inbound server failures (e.g. DNS failures). (Section 10.5.5).
CREATE had a race that required an Etag be sent when a resource is first created. (Section 10.2.2).
Content-Base was deleted from the specification: it wasn't implemented widely, and there's no simple, safe way to introduce it without a robust extension mechanism. It's also used in a similar, but not identical, fashion in MHTML [45]. ๐๏ธ
Transfer-coding and message lengths all interact in ways that needed fixing, especially exactly when chunked encoding is used (to allow for transfer encoding that may not be self delimiting). It was important to straighten out exactly how message lengths are computed. (Sections 3.6, 4.4, 7.2.2, 13.5.2, 14.13, 14.16)
A content-coding of "identity" was introduced to solve problems discovered in caching. (section 3.5)
Quality Values of zero should indicate that "I don't want something," so clients can refuse a representation. (Section 3.9) ๐ โโ๏ธ
The use and interpretation of HTTP version numbers was clarified by RFC 2145. Require proxies to upgrade requests to the highest protocol version they support, to deal with problems discovered in HTTP/1.0 implementations (Section 3.1) โฌ๏ธ
Charset wildcarding was introduced to avoid an explosion of character set names in accept headers. (Section 14.2)
A case was missed in the Cache-Control model of HTTP/1.1, so s-maxage was introduced to add that missing case. (Sections 13.4, 14.8, 14.9, 14.9.3)
The Cache-Control: max-age directive wasn't properly defined for responses. (Section 14.9.3)
There are situations where a server (especially a proxy) doesn't know the full length of a response but can still serve a byterange request. We therefore need a mechanism that allows byteranges with a content-range that doesn't indicate the full length of the message. (Section 14.16) ๐งฉ
Range request responses would get super verbose if all metadata were always returned. By letting the server send only the needed headers in a 206 response, this problem goes away. (Section 10.2.7, 13.5.3, and 14.27) ๐
Fixed the problem with unsatisfiable range requests. There are two cases: syntactic problems, and a range that doesn't exist in the document. The 416 status code was needed to resolve this ambiguity and to indicate an error for a byte range request that falls outside of the actual contents of a document. (Section 10.4.17, 14.16) ๐
Rewrite of the message transmission requirements to make it much harder for implementors to get it wrong, since errors here can have a big impact on the Internet, and to deal with the following problems:
- Changing "HTTP/1.1 or later" to "HTTP/1.1", in contexts where this was incorrectly placing a requirement on the behavior of an implementation of a future version of HTTP/1.x
- Made it clear that user-agents should retry requests, not "clients" in general.
- Converted requirements for clients to ignore unexpected 100 (Continue) responses, and for proxies to forward 100 responses, into a general requirement for 1xx responses.
- Modified some TCP-specific language, to make it clearer that non-TCP transports are possible for HTTP.
- Require that the origin server MUST NOT wait for the request body before it sends a required 100 (Continue) response.
- Allow, rather than require, a server to omit 100 (Continue) if it has already seen some of the request body.
- Allow servers to defend against denial-of-service attacks and broken clients.
This change adds the Expect header and 417 status code. The message transmission requirement fixes are in sections 8.2, 10.4.18, 8.1.2.2, 13.11, and 14.20. ๐ฆ
Proxies should be able to add Content-Length when appropriate. (Section 13.5.2)
Cleaned up the confusion between 403 and 404 responses. (Section 10.4.4, 10.4.5, and 10.4.11)
Warnings could be cached incorrectly, or not updated appropriately. (Section 13.1.2, 13.2.4, 13.5.2, 13.5.3, 14.9.3, and 14.46) Warning also needed to be a general header, since PUT or other methods may need it in requests. โ ๏ธ
Transfer-coding had significant problems, particularly with its interactions with chunked encoding. The solution is that transfer-codings become as full-fledged as content-codings. This involves adding an IANA registry for transfer-codings (separate from content codings), a new header field (TE), and enabling trailer headers in the future. Transfer encoding is a major performance benefit, so it was worth fixing [39]. TE also solves another, obscure, downward interoperability problem that could have occurred due to interactions between authentication trailers, chunked encoding, and HTTP/1.0 clients. (Section 3.6, 3.6.1, and 14.39) ๐ง
The PATCH, LINK, UNLINK methods were defined but not commonly implemented in previous versions of this specification. See RFC 2068 [33]. ๐ฉน
The Alternates, Content-Version, Derived-From, Link, URI, Public and Content-Base header fields were defined in previous versions of this specification, but not commonly implemented. See RFC 2068 [33]. ๐ชฆ
20. Index ๐
Please see the PostScript version of this RFC for the INDEX. ๐งโโ๏ธ
21. Full Copyright Statement ๐
Copyright (C) The Internet Society (1999). All Rights Reserved. ๐
okay so this is the legal part, but it's still lowkey iconic โจ The Internet Society owns the copyright, and everyone can copy and share this document and translations of it. People are also allowed to write derivative works that comment on or explain it, or that help people implement it. Those can be prepared, copied, published, and distributed, in whole or in part, with no real restrictions, as long as the copyright notice and this paragraph stay on every copy and derivative work ๐ซถ
The one thing you can't do is modify this document itself. That means you can't remove the copyright notice or the references to the Internet Society or other Internet organizations. The exceptions are when you need it to develop Internet standards, in which case you have to follow the copyright procedures in the Internet Standards process, or when you translate it into languages other than English ๐
The permissions above are perpetual. The Internet Society, its successors, and its assigns won't take them back, so they're forever, bestie ๐
This document and the information in it are provided "AS IS," and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. ๐ญ no cap, that's the legal energy we're dealing with.
Acknowledgement ๐ธ
Funding for the RFC Editor function is currently provided by the Internet Society. ๐ง Someone has to keep the lights on, and the Internet Society is the one doing it right now. ๐
๐ฆ where this page comes from
- ietf: rfc2616 1999-06
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms