RFC 9110
HTTP Semantics
HTTP Semantics โจ
Okay bestie, welcome to RFC 9110, aka the HTTP Semantics spec ๐ฆ It's STD 97, which means it's an official Internet Standard, and it's giving main character energy. This is part 1 of 48, so we're just getting the setup first ๐ธ
- Number: RFC 9110, from the Internet Engineering Task Force (IETF) ๐
- Written by: R. Fielding, Ed. (Adobe), M. Nottingham, Ed. (Fastly), and J. Reschke, Ed. (greenbytes) ๐
- Category: Standards Track, so it's an official standard ๐
- Date: June 2022 ๐
- ISSN: 2070-1721
- Obsoletes: RFCs 2818, 7230, 7231, 7232, 7233, 7235, 7538, 7615, and 7694 ๐ (the abstract says it only obsoletes portions of 7230, so that's the detail to remember ๐)
- Updates: RFC 3864 โจ
Abstract
Okay so HTTP, the Hypertext Transfer Protocol, is a stateless application-level protocol ๐ง It's built for distributed, collaborative hypertext information systems, which is the fancy way of saying the web ๐ This doc lays out the overall architecture of HTTP, sets the common terminology everyone uses, and defines the parts of the protocol that are shared by all versions ๐ It covers the core protocol elements, the extensibility mechanisms, and the "http" and "https" Uniform Resource Identifier (URI) schemes ๐ฅ
The abstract also says this document updates RFC 3864 and obsoletes RFCs 2818, 7231, 7232, 7233, 7235, 7538, 7615, 7694, and portions of 7230 ๐ฆ Major glow-up energy, periodt ๐
Status of This Memo
This is an Internet Standards Track document โญ
It's a product of the Internet Engineering Task Force (IETF) and represents the consensus of the IETF community ๐ซถ It went through public review and got approved for publication by the Internet Engineering Steering Group (IESG) ๐ For more on Internet Standards, check out Section 2 of RFC 7841 ๐
Info about the current status of this document, any errata, and how to send feedback can be found at https://www.rfc-editor.org/info/rfc9110 ๐
Copyright Notice
Copyright (c) 2022 IETF Trust and the persons identified as the document authors. All rights reserved ๐
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they stand on the publication date. Please actually read these, bestie, because they spell out your rights and restrictions for this document ๐ Any Code Components pulled out of this document have to include Revised BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come without warranty as described in that license ๐ฅ
This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The people who control the copyright in some of that older material may not have given the IETF Trust permission to allow modifications outside the IETF Standards Process. So unless you've got an adequate license from whoever controls that copyright, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process ๐ The only exceptions are formatting it for publication as an RFC or translating it into languages other than English ๐
Okay bestie, the table of contents comes first so we can see the whole map of the doc ๐บ๏ธโจ
Table of Contents ๐
Table of Contents
1. Introduction
1.1. Purpose
1.2. History and Evolution
1.3. Core Semantics
1.4. Specifications Obsoleted by This Document
2. Conformance
2.1. Syntax Notation
2.2. Requirements Notation
2.3. Length Requirements
2.4. Error Handling
2.5. Protocol Version
3. Terminology and Core Concepts
3.1. Resources
3.2. Representations
3.3. Connections, Clients, and Servers
3.4. Messages
3.5. User Agents
3.6. Origin Server
3.7. Intermediaries
3.8. Caches
3.9. Example Message Exchange
4. Identifiers in HTTP
4.1. URI References
4.2. HTTP-Related URI Schemes
4.2.1. http URI Scheme
4.2.2. https URI Scheme
4.2.3. http(s) Normalization and Comparison
4.2.4. Deprecation of userinfo in http(s) URIs
4.2.5. http(s) References with Fragment Identifiers
4.3. Authoritative Access
4.3.1. URI Origin
4.3.2. http Origins
4.3.3. https Origins
4.3.4. https Certificate Verification
4.3.5. IP-ID Reference Identity
5. Fields
5.1. Field Names
5.2. Field Lines and Combined Field Value
5.3. Field Order
5.4. Field Limits
5.5. Field Values
5.6. Common Rules for Defining Field Values
5.6.1. Lists (#rule ABNF Extension)
5.6.1.1. Sender Requirements
5.6.1.2. Recipient Requirements
5.6.2. Tokens
5.6.3. Whitespace
5.6.4. Quoted Strings
5.6.5. Comments
5.6.6. Parameters
5.6.7. Date/Time Formats
6. Message Abstraction
6.1. Framing and Completeness
6.2. Control Data
6.3. Header Fields
6.4. Content
6.4.1. Content Semantics
6.4.2. Identifying Content
6.5. Trailer Fields
6.5.1. Limitations on Use of Trailers
6.5.2. Processing Trailer Fields
6.6. Message Metadata
6.6.1. Date
6.6.2. Trailer
7. Routing HTTP Messages
7.1. Determining the Target Resource
7.2. Host and :authority
7.3. Routing Inbound Requests
7.3.1. To a Cache
7.3.2. To a Proxy
7.3.3. To the Origin
7.4. Rejecting Misdirected Requests
7.5. Response Correlation
7.6. Message Forwarding
7.6.1. Connection
7.6.2. Max-Forwards
7.6.3. Via
7.7. Message Transformations
7.8. Upgrade
8. Representation Data and Metadata
8.1. Representation Data
8.2. Representation Metadata
8.3. Content-Type
8.3.1. Media Type
8.3.2. Charset
8.3.3. Multipart Types
8.4. Content-Encoding
8.4.1. Content Codings
8.4.1.1. Compress Coding
8.4.1.2. Deflate Coding
8.4.1.3. Gzip Coding
8.5. Content-Language
8.5.1. Language Tags
8.6. Content-Length
8.7. Content-Location
8.8. Validator Fields
8.8.1. Weak versus Strong
8.8.2. Last-Modified
8.8.2.1. Generation
8.8.2.2. Comparison
8.8.3. ETag
8.8.3.1. Generation
8.8.3.2. Comparison
8.8.3.3. Example: Entity Tags Varying on Content-Negotiated
Resources
9. Methods
9.1. Overview
9.2. Common Method Properties
9.2.1. Safe Methods
9.2.2. Idempotent Methods
9.2.3. Methods and Caching
9.3. Method Definitions
9.3.1. GET
9.3.2. HEAD
9.3.3. POST
9.3.4. PUT
9.3.5. DELETE
9.3.6. CONNECT
9.3.7. OPTIONS
9.3.8. TRACE
10. Message Context
10.1. Request Context Fields
10.1.1. Expect
10.1.2. From
10.1.3. Referer
10.1.4. TE
10.1.5. User-Agent
10.2. Response Context Fields
10.2.1. Allow
10.2.2. Location
10.2.3. Retry-After
10.2.4. Server
11. HTTP Authentication
11.1. Authentication Scheme
11.2. Authentication Parameters
11.3. Challenge and Response
11.4. Credentials
11.5. Establishing a Protection Space (Realm)
11.6. Authenticating Users to Origin Servers
11.6.1. WWW-Authenticate
11.6.2. Authorization
11.6.3. Authentication-Info
11.7. Authenticating Clients to Proxies
11.7.1. Proxy-Authenticate
11.7.2. Proxy-Authorization
11.7.3. Proxy-Authentication-Info
12. Content Negotiation
12.1. Proactive Negotiation
12.2. Reactive Negotiation
12.3. Request Content Negotiation
12.4. Content Negotiation Field Features
12.4.1. Absence
12.4.2. Quality Values
12.4.3. Wildcard Values
12.5. Content Negotiation Fields
12.5.1. Accept
12.5.2. Accept-Charset
12.5.3. Accept-Encoding
12.5.4. Accept-Language
12.5.5. Vary
13. Conditional Requests
13.1. Preconditions
13.1.1. If-Match
13.1.2. If-None-Match
13.1.3. If-Modified-Since
13.1.4. If-Unmodified-Since
13.1.5. If-Range
13.2. Evaluation of Preconditions
13.2.1. When to Evaluate
13.2.2. Precedence of Preconditions
14. Range Requests
14.1. Range Units
14.1.1. Range Specifiers
14.1.2. Byte Ranges
14.2. Range
14.3. Accept-Ranges
14.4. Content-Range
14.5. Partial PUT
14.6. Media Type multipart/byteranges
15. Status Codes
15.1. Overview of Status Codes
15.2. Informational 1xx
15.2.1. 100 Continue
15.2.2. 101 Switching Protocols
15.3. Successful 2xx
15.3.1. 200 OK
15.3.2. 201 Created
15.3.3. 202 Accepted
15.3.4. 203 Non-Authoritative Information
15.3.5. 204 No Content
15.3.6. 205 Reset Content
15.3.7. 206 Partial Content
15.3.7.1. Single Part
15.3.7.2. Multiple Parts
15.3.7.3. Combining Parts
15.4. Redirection 3xx
15.4.1. 300 Multiple Choices
15.4.2. 301 Moved Permanently
15.4.3. 302 Found
15.4.4. 303 See Other
15.4.5. 304 Not Modified
15.4.6. 305 Use Proxy
15.4.7. 306 (Unused)
15.4.8. 307 Temporary Redirect
15.4.9. 308 Permanent Redirect
15.5. Client Error 4xx
15.5.1. 400 Bad Request
15.5.2. 401 Unauthorized
15.5.3. 402 Payment Required
15.5.4. 403 Forbidden
15.5.5. 404 Not Found
15.5.6. 405 Method Not Allowed
15.5.7. 406 Not Acceptable
15.5.8. 407 Proxy Authentication Required
15.5.9. 408 Request Timeout
15.5.10. 409 Conflict
15.5.11. 410 Gone
15.5.12. 411 Length Required
15.5.13. 412 Precondition Failed
15.5.14. 413 Content Too Large
15.5.15. 414 URI Too Long
15.5.16. 415 Unsupported Media Type
15.5.17. 416 Range Not Satisfiable
15.5.18. 417 Expectation Failed
15.5.19. 418 (Unused)
15.5.20. 421 Misdirected Request
15.5.21. 422 Unprocessable Content
15.5.22. 426 Upgrade Required
15.6. Server Error 5xx
15.6.1. 500 Internal Server Error
15.6.2. 501 Not Implemented
15.6.3. 502 Bad Gateway
15.6.4. 503 Service Unavailable
15.6.5. 504 Gateway Timeout
15.6.6. 505 HTTP Version Not Supported
16. Extending HTTP
16.1. Method Extensibility
16.1.1. Method Registry
16.1.2. Considerations for New Methods
16.2. Status Code Extensibility
16.2.1. Status Code Registry
16.2.2. Considerations for New Status Codes
16.3. Field Extensibility
16.3.1. Field Name Registry
16.3.2. Considerations for New Fields
16.3.2.1. Considerations for New Field Names
16.3.2.2. Considerations for New Field Values
16.4. Authentication Scheme Extensibility
16.4.1. Authentication Scheme Registry
16.4.2. Considerations for New Authentication Schemes
16.5. Range Unit Extensibility
16.5.1. Range Unit Registry
16.5.2. Considerations for New Range Units
16.6. Content Coding Extensibility
16.6.1. Content Coding Registry
16.6.2. Considerations for New Content Codings
16.7. Upgrade Token Registry
17. Security Considerations
17.1. Establishing Authority
17.2. Risks of Intermediaries
17.3. Attacks Based on File and Path Names
17.4. Attacks Based on Command, Code, or Query Injection
17.5. Attacks via Protocol Element Length
17.6. Attacks Using Shared-Dictionary Compression
17.7. Disclosure of Personal Information
17.8. Privacy of Server Log Information
17.9. Disclosure of Sensitive Information in URIs
17.10. Application Handling of Field Names
17.11. Disclosure of Fragment after Redirects
17.12. Disclosure of Product Information
17.13. Browser Fingerprinting
17.14. Validator Retention
17.15. Denial-of-Service Attacks Using Range
17.16. Authentication Considerations
17.16.1. Confidentiality of Credentials
17.16.2. Credentials and Idle Clients
17.16.3. Protection Spaces
17.16.4. Additional Response Fields
18. IANA Considerations
18.1. URI Scheme Registration
18.2. Method Registration
18.3. Status Code Registration
18.4. Field Name Registration
18.5. Authentication Scheme Registration
18.6. Content Coding Registration
18.7. Range Unit Registration
18.8. Media Type Registration
18.9. Port Registration
18.10. Upgrade Token Registration
19. References
19.1. Normative References
19.2. Informative References
Appendix A. Collected ABNF
Appendix B. Changes from Previous RFCs
B.1. Changes from RFC 2818
B.2. Changes from RFC 7230
B.3. Changes from RFC 7231
B.4. Changes from RFC 7232
B.5. Changes from RFC 7233
B.6. Changes from RFC 7235
B.7. Changes from RFC 7538
B.8. Changes from RFC 7615
B.9. Changes from RFC 7694
Acknowledgements
Index
Authors' Addresses
1. Introduction โจ
1.1. Purpose
Okay so HTTP (the Hypertext Transfer Protocol) is a whole family of stateless, application-level, request/response protocols ๐ They all share a generic interface, extensible semantics, and self-descriptive messages, which is what lets them do flexible interaction with network-based hypertext information systems. It's giving modular and it's giving iconic ๐ฆ
HTTP hides the messy details of how a service is actually built behind a uniform interface that clients can use no matter what kind of resource they're talking to ๐ซถ The servers don't need to know each client's purpose either. A request can be looked at all on its own, rather than being tied to one specific type of client or some predetermined sequence of app steps. That's how general-purpose implementations get to be useful in loads of different contexts, reduces interaction complexity, and lets things evolve independently over time ๐ The way that this is designed is just chef's kiss ๐
HTTP is also built to work as an intermediation protocol ๐ง Proxies and gateways can take non-HTTP information systems and translate them into a more generic interface, so everybody gets to hang out in the same place ๐
Now here's the tea ๐ต Because of all this flexibility, the protocol can't be defined by what goes on behind the interface. Instead, we're limited to defining the syntax of communication, the intent of received communication, and the expected behavior of recipients. ๐ญ If you look at a communication all by itself, successful actions ought to show up as matching changes in the observable interface that servers provide. BUT since multiple clients might act in parallel (and maybe at cross-purposes ๐), we can't require those changes to be observable beyond the scope of a single response ๐
1.2. History and Evolution ๐ฐ๏ธโจ
okay so HTTP has been the main information transfer protocol for the World Wide Web since it showed up in 1990 ๐ป bestie it started out super simple, just low-latency requests with one method, GET, to grab a presumed hypertext document at a given pathname ๐ then the Web grew and HTTP got upgraded to wrap requests and responses in messages, send arbitrary data formats using MIME-like media types, and route requests through intermediaries ๐ฆ those versions ended up being named HTTP/0.9 and HTTP/1.0 (see [HTTP/1.0]) ๐ธ
HTTP/1.1 was the glow-up ๐ it refined the features while keeping compatibility with the existing text-based messaging syntax, so interoperability, scalability, and robustness across the Internet all got better ๐ it added length-based data delimiters for both fixed and dynamic (chunked) content, a consistent framework for content negotiation, opaque validators for conditional requests, cache controls for better cache consistency, range requests for partial updates, and default persistent connections ๐ซถ HTTP/1.1 was introduced in 1995 and published on the Standards Track in 1997 [RFC2068], revised in 1999 [RFC2616], and revised again in 2014 ([RFC7230] through [RFC7235]) ๐
HTTP/2 ([HTTP/2]) brought a multiplexed session layer on top of the existing TLS and TCP protocols so you can exchange concurrent HTTP messages with efficient field compression and server push ๐ฅ HTTP/3 ([HTTP/3]) gives concurrent messages even more independence by using QUIC as a secure multiplexed transport over UDP instead of TCP ๐ง
all three major versions of HTTP rely on the semantics defined by this document โจ they haven't obsoleted each other, because each one has specific benefits and limitations depending on the context of use ๐ implementations are expected to pick the most appropriate transport and messaging syntax for their particular context, no cap ๐
this revision separates the definition of semantics (this document) and caching ([CACHING]) from the current HTTP/1.1 messaging syntax ([HTTP/1.1]) ๐ the point is to let each major protocol version progress independently while still referring to the same core semantics ๐ฆ
1.3. Core Semantics ๐ง
HTTP gives you a uniform interface for interacting with a resource (Section 3.1) ๐ regardless of its type, nature, or implementation ๐ธ you do it by sending messages that manipulate or transfer representations (Section 3.2) โจ
every message is either a request or a response ๐ a client builds request messages that communicate its intentions and routes them toward an identified origin server ๐ a server listens for requests, parses each message it receives, interprets the message semantics in relation to the identified target resource, and responds to that request with one or more response messages ๐ซถ the client checks received responses to see if its intentions were carried out, then decides what to do next based on the status codes and content it got ๐
HTTP semantics include the intentions defined by each request method (Section 9) ๐ฆ extensions to those semantics that might be described in request header fields ๐ status codes that describe the response (Section 15) ๐ and other control data and resource metadata that might be given in response fields ๐
semantics also cover representation metadata that describes how content is meant to be interpreted by a recipient ๐ request header fields that might influence content selection โจ and the various selection algorithms that are collectively called "content negotiation" (Section 12) ๐ iykyk, it's a whole thing ๐ญ
1.4. Specifications Obsoleted by This Document ๐๏ธ
this document obsoletes the following specs, so here's the tea, bestie โ
+============================================+===========+=====+
| Title | Reference | See |
+============================================+===========+=====+
| HTTP Over TLS | [RFC2818] | B.1 |
+--------------------------------------------+-----------+-----+
| HTTP/1.1 Message Syntax and Routing [*] | [RFC7230] | B.2 |
+--------------------------------------------+-----------+-----+
| HTTP/1.1 Semantics and Content | [RFC7231] | B.3 |
+--------------------------------------------+-----------+-----+
| HTTP/1.1 Conditional Requests | [RFC7232] | B.4 |
+--------------------------------------------+-----------+-----+
| HTTP/1.1 Range Requests | [RFC7233] | B.5 |
+--------------------------------------------+-----------+-----+
| HTTP/1.1 Authentication | [RFC7235] | B.6 |
+--------------------------------------------+-----------+-----+
| HTTP Status Code 308 (Permanent Redirect) | [RFC7538] | B.7 |
+--------------------------------------------+-----------+-----+
| HTTP Authentication-Info and Proxy- | [RFC7615] | B.8 |
| Authentication-Info Response Header Fields | | |
+--------------------------------------------+-----------+-----+
| HTTP Client-Initiated Content-Encoding | [RFC7694] | B.9 |
+--------------------------------------------+-----------+-----+
Table 1
[*] This document only obsoletes the portions of RFC 7230 that are independent of the HTTP/1.1 messaging syntax and connection management ๐งฉ the remaining bits of RFC 7230 are obsoleted by "HTTP/1.1" [HTTP/1.1] ๐
2. Conformance โ
2.1. Syntax Notation โ๏ธ
this spec uses the Augmented Backus-Naur Form (ABNF) notation of [RFC5234], extended with the notation for case-sensitivity in strings defined in [RFC7405] ๐
it also uses a list extension, defined in Section 5.6.1, that lets you define comma-separated lists compactly with a "#" operator ๐ฆ (it's kinda like how the "*" operator shows repetition) Appendix A shows the collected grammar with all list operators expanded to standard ABNF notation ๐
as a convention, ABNF rule names prefixed with "obs-" denote obsolete grammar rules that only show up for historical reasons ๐ฐ๏ธ
the following core rules are included by reference, as defined in Appendix B.1 of [RFC5234] ๐ :
- ALPHA (letters)
- CR (carriage return)
- CRLF (CR LF)
- CTL (controls)
- DIGIT (decimal 0-9)
- DQUOTE (double quote)
- HEXDIG (hexadecimal 0-9/A-F/a-f)
- HTAB (horizontal tab)
- LF (line feed)
- OCTET (any 8-bit sequence of data)
- SP (space)
- VCHAR (any visible US-ASCII character)
Section 5.6 defines some generic syntactic components for field values ๐ธ
this spec uses the terms "character", "character encoding scheme", "charset", and "protocol element" as they are defined in [RFC6365] ๐
2.2. Requirements Notation ๐
okay, this part is the big one ๐ญ the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] ๐ฅ but only when they show up in all capitals, exactly like this ๐ lowercase versions are just regular words, bestie ๐ซถ
this spec sets conformance criteria based on the role a participant plays in HTTP communication โจ so requirements land on senders, recipients, clients, servers, user agents, intermediaries, origin servers, proxies, gateways, or caches, depending on which behaviour the requirement is limiting ๐ฆ extra requirements can go on implementations, resource owners, and protocol element registrations when they apply beyond the scope of a single communication ๐ง
the verb "generate" gets used instead of "send" where a requirement only applies to implementations that create the protocol element ๐ as opposed to an implementation that forwards a received element downstream ๐
an implementation counts as conformant if it complies with all of the requirements tied to the roles it plays in HTTP ๐
A sender MUST NOT generate protocol elements that do not match the grammar defined by the corresponding ABNF rules ๐ โโ๏ธ within a given message, a sender MUST NOT generate protocol elements or syntax alternatives that are only allowed to be generated by participants in other roles (i.e., a role that the sender does not have for that message) ๐ so like, stay in your lane ๐ค
conformance to HTTP covers both the particular messaging syntax of the protocol version in use AND conformance to the semantics of the protocol elements sent ๐ for example, a client that claims conformance to HTTP/1.1 but fails to recognize the features required of HTTP/1.1 recipients will fail to interoperate with servers that adjust their responses to match those claims ๐ features that reflect user choices, like content negotiation and user-selected extensions, can affect application behaviour beyond the protocol stream ๐ซถ so sending protocol elements that inaccurately reflect a user's choices will confuse the user and get in the way of their choice ๐ญ
when an implementation fails semantic conformance, recipients of its messages will eventually come up with workarounds to adjust their behaviour accordingly ๐ a recipient MAY use such workarounds and still be conformant to this protocol, as long as the workarounds are limited to the implementations at fault ๐ for example, servers often scan parts of the User-Agent field value, and user agents often scan the Server field value, to adjust their own behaviour around known bugs or poorly chosen defaults ๐ง
2.3. Length Requirements ๐
a recipient SHOULD parse a received protocol element defensively ๐ก๏ธ with only marginal expectations that the element will conform to its ABNF grammar and fit within a reasonable buffer size ๐ธ
HTTP doesn't have specific length limits for many of its protocol elements, because what counts as appropriate varies wildly depending on the deployment context and purpose of the implementation ๐ so interoperability between senders and recipients depends on shared expectations about what's a reasonable length for each protocol element ๐ฆ also, what's commonly considered reasonable for some protocol elements has changed over the past three decades of HTTP use, and it's expected to keep changing in the future ๐ฐ๏ธโจ
at a minimum, a recipient MUST be able to parse and process protocol element lengths that are at least as long as the values it generates for those same protocol elements in other messages ๐ for example, an origin server that publishes very long URI references to its own resources needs to be able to parse and process those same references when they're received as a target URI ๐
a lot of received protocol elements only get parsed as far as needed to identify and forward that element downstream ๐ for example, an intermediary might parse a received field into its field name and field value components, then forward the field without any further parsing inside the field value ๐
2.4. Error Handling โจ
okay bestie, this one is a big rule ๐ซถ A recipient MUST interpret a received protocol element according to the semantics this spec defines for it, extensions included. The only exception is when the recipient has figured out (through experience or configuration) that the sender is getting what those semantics imply wrong. For example, an origin server might ignore an Accept-Encoding header if the User-Agent header shows a specific implementation version that's known to break on certain content codings ๐
Unless noted otherwise, a recipient MAY attempt to recover a usable protocol element from an invalid construct. HTTP doesn't define specific error handling mechanisms unless they directly affect security ๐ because different apps need totally different strategies. A web browser might want to quietly recover when a Location header doesn't parse according to the ABNF, while a systems control client might think any kind of error recovery is dangerous ๐ญ
Some requests can be automatically retried by a client if the underlying connection fails, as described in Section 9.2.2 ๐
2.5. Protocol Version ๐
HTTP's version number is two decimal digits separated by a "." (period or decimal point). The first digit is the major version and tells you the messaging syntax. The second digit is the minor version and tells you the highest minor version within that major version the sender is conformant to (able to understand for future communication) ๐
HTTP's core semantics don't change between protocol versions, but how they show up "on the wire" can. So the HTTP version number changes when incompatible changes are made to the wire format. HTTP also allows incremental, backwards-compatible changes without a version bump, through the defined extension points in Section 16 ๐ง
The protocol version as a whole shows the sender's conformance with the requirements in that version's specification(s). For example, "HTTP/1.1" is defined by the combined specifications of this document, "HTTP Caching" [CACHING], and "HTTP/1.1" [HTTP/1.1] ๐
The major version number goes up when an incompatible message syntax is introduced. The minor number goes up when changes to the protocol add to the message semantics or imply additional capabilities of the sender ๐
The minor version advertises the sender's communication capabilities even when the sender is only using a backwards-compatible subset of the protocol. This lets the recipient know that more advanced features can be used in response (by servers) or in future requests (by clients) ๐
When a major version of HTTP doesn't define any minor versions, the minor version "0" is implied. The "0" is used when referring to that protocol within elements that require a minor version identifier ๐
3. Terminology and Core Concepts ๐ฆ
HTTP was created for the World Wide Web (WWW) architecture and has evolved over time to support the scalability needs of a worldwide hypertext system. A lot of that architecture shows up in the terminology used to define HTTP, so it's all connected ๐ธ
3.1. Resources ๐
The target of an HTTP request is called a "resource". HTTP doesn't limit what a resource can be. It just defines an interface that might be used to interact with resources โจ Most resources are identified by a Uniform Resource Identifier (URI), as described in Section 4.
One design goal of HTTP is to separate resource identification from request semantics. This is possible because the request semantics live in the request method (Section 9) and a few request-modifying header fields. A resource cannot treat a request in a way that's inconsistent with the semantics of the request's method. For example, even if a resource's URI implies semantics that aren't safe, a client can expect the resource to avoid unsafe actions when processing a request with a safe method (see Section 9.2.1) ๐
HTTP relies on the Uniform Resource Identifier (URI) standard [URI] to indicate the target resource (Section 7.1) and the relationships between resources ๐
3.2. Representations ๐ฆ
A "representation" is information meant to reflect a past, current, or desired state of a given resource, in a format that can be easily communicated via the protocol. A representation is made up of a set of representation metadata and a potentially unbounded stream of representation data (Section 8) ๐ฆ
HTTP allows "information hiding" behind its uniform interface. It does this by describing communication in terms of a transferable representation of the resource state, instead of transferring the resource itself ๐ซฃ That means the resource identified by a URI can be pretty much anything, even temporal stuff like "the current weather in Laguna Beach", while still giving info that represents the resource at the time a message is generated [REST]. iconic ๐ญ
The uniform interface is kind of like a window. You can observe and act on a thing only by sending messages to an independent actor on the other side. So we need a shared abstraction that "takes the place of" the current or desired state of that thing in our communications. When a representation is hypertext, it can provide both a representation of the resource state and processing instructions that help guide the recipient's future interactions ๐ช
A target resource might be provided with, or be capable of generating, multiple representations that each try to reflect the resource's current state. An algorithm, usually based on content negotiation (Section 12), is used to pick the one representation that's most applicable to a given request. This "selected representation" provides the data and metadata for evaluating conditional requests (Section 13) and for building the content of 200 (OK), 206 (Partial Content), and 304 (Not Modified) responses to GET (Section 9.3.1) ๐
3.3. Connections, Clients, and Servers ๐
HTTP is a client/server protocol that operates over a reliable transport- or session-layer "connection" ๐งต
An HTTP "client" is a program that establishes a connection to a server so it can send one or more HTTP requests. An HTTP "server" is a program that accepts connections in order to service HTTP requests by sending HTTP responses ๐ค
The terms client and server only refer to the roles these programs play for a particular connection. The same program might be a client on some connections and a server on others ๐
HTTP is defined as a stateless protocol. That means each request message's semantics can be understood in isolation, and the relationship between connections and the messages on them has no impact on how those messages are interpreted. For example, a CONNECT request (Section 9.3.6) or a request with the Upgrade header field (Section 7.8) can happen at any time, not just in the first message on a connection. Lots of implementations depend on HTTP's stateless design to reuse proxied connections or to dynamically load balance requests across multiple servers โ๏ธ
So, a server MUST NOT assume that two requests on the same connection come from the same user agent, unless the connection is secured and specific to that agent. Some non-standard HTTP extensions (e.g., [RFC4559]) have been known to break this requirement, which caused security and interoperability problems ๐ฌ this is a serious one, bestie ๐จ
3.4. Messages ๐
HTTP is a stateless request/response protocol for exchanging "messages" across a connection. The terms "sender" and "recipient" refer to any implementation that sends or receives a given message, respectively ๐จ
A client sends requests to a server in the form of a "request" message with a method (Section 9) and a request target (Section 7.1). The request might also contain header fields (Section 6.3) for request modifiers, client information, and representation metadata. It can carry content (Section 6.4) meant to be processed according to the method, plus trailer fields (Section 6.5) that communicate information collected while sending the content ๐
A server responds to a client's request by sending one or more "response" messages, each including a status code (Section 15) โจ The response might also contain header fields for server information, resource metadata, and representation metadata. It can carry content that gets interpreted according to the status code, plus trailer fields that communicate information collected while sending the content ๐
3.5. User Agents ๐ง
The term "user agent" refers to any of the various client programs that initiate a request ๐
The most familiar user agent is the general-purpose Web browser, but that's only a small percentage of implementations. Other common user agents include spiders (web-traversing robots), command-line tools, billboard screens, household appliances, scales, light bulbs, firmware update scripts, mobile apps, and communication devices in a multitude of shapes and sizes ๐ค๐ก it's giving everything
Being a user agent doesn't mean a human is directly interacting with the software at the time of a request. In lots of cases, a user agent is installed or configured to run in the background and save its results for later inspection (or to save only the subset of results that might be interesting or erroneous). Spiders, for example, are usually given a start URI and configured to follow certain behavior while crawling the Web as a hypertext graph ๐ท๏ธ
Many user agents can't, or choose not to, make interactive suggestions to their user or give adequate warnings about security or privacy concerns. In the few cases where this specification requires reporting errors to the user, it's acceptable for that reporting to only be visible in an error console or log file ๐ Likewise, if a requirement says an automated action has to be confirmed by the user before proceeding, it might be met through advance configuration choices, run-time options, or simply avoiding the unsafe action altogether. Confirmation doesn't imply any specific user interface or interruption of normal processing if the user has already made that choice ๐
3.6. Origin Server ๐
The term "origin server" refers to a program that can originate authoritative responses for a given target resource ๐๏ธ
The most familiar origin servers are large public websites. But just like user agents being equated with browsers, it's easy to think all origin servers are the same. Common origin servers also include home automation units, configurable networking components, office machines, autonomous robots, news feeds, traffic cameras, real-time ad selectors, and video-on-demand platforms ๐ฌ
Most HTTP communication is a retrieval request (GET) for a representation of some resource identified by a URI. In the simplest case, this happens over a single bidirectional connection (===) between the user agent (UA) and the origin server (O) ๐ช
request >
UA ======================================= O
< response
Figure 1
3.7. Intermediaries ๐ฆ
okay so HTTP lets intermediaries step in and help satisfy requests along a whole chain of connections ๐โจ There are three common flavours: proxy, gateway, and tunnel. Sometimes one single intermediary can be an origin server, a proxy, a gateway, or a tunnel, switching roles depending on each request ๐
> > > >
UA =========== A =========== B =========== C =========== O
< < < <
Figure 2
Figure 2 shows three intermediaries (A, B, and C) sitting between the user agent and the origin server ๐ A request or response that travels the whole chain goes through four separate connections, so it's a lot of hops bestie ๐ญ Some HTTP options might only apply to the connection with the nearest, non-tunnel neighbour, some only to the endpoints of the chain, and some to every connection along the way ๐ง The diagram looks linear, but everyone can be juggling multiple conversations at once. For example, B might be getting requests from clients other than A and/or forwarding requests to servers other than C, all while it's handling A's request ๐ And later requests can take a totally different path through the connections, often based on dynamic configuration for load balancing. main character routing energy ๐
The terms "upstream" and "downstream" describe directional requirements relative to the message flow. All messages flow from upstream to downstream ๐ The terms "inbound" and "outbound" describe directional requirements relative to the request route. Inbound means "toward the origin server", and outbound means "toward the user agent" ๐ฆ
A "proxy" is a message-forwarding agent that the client chooses, usually through local configuration rules ๐ง It receives requests for some type(s) of absolute URI and tries to satisfy them by translating through the HTTP interface. Some translations are minimal, like proxy requests for "http" URIs. Others might need translation to and from completely different application-level protocols ๐ Proxies are often used to group an organisation's HTTP requests through one common intermediary, for security services, annotation services, or shared caching ๐ Some proxies apply transformations to selected messages or content while they're being forwarded, as described in Section 7.7 โจ
A "gateway" (a.k.a. "reverse proxy") is an intermediary that acts as an origin server for the outbound connection, but translates received requests and forwards them inbound to another server or servers ๐ช Gateways are often used to encapsulate legacy or untrusted information services, to improve server performance through "accelerator" caching, and to enable partitioning or load balancing of HTTP services across multiple machines ๐
All HTTP requirements that apply to an origin server also apply to the outbound communication of a gateway ๐ A gateway talks to inbound servers using any protocol it likes, including private extensions to HTTP that are outside the scope of this specification ๐ซถ However, an HTTP-to-HTTP gateway that wants to interoperate with third-party HTTP servers needs to conform to user agent requirements on the gateway's inbound connection. it has to be a good guest ๐
A "tunnel" acts as a blind relay between two connections and doesn't change the messages ๐ Once it's active, a tunnel isn't considered a party to the HTTP communication, even though it might have been started by an HTTP request ๐ A tunnel stops existing when both ends of the relayed connection are closed. Tunnels are used to extend a virtual connection through an intermediary, such as when Transport Layer Security (TLS, [TLS13]) is used to set up confidential communication through a shared firewall proxy ๐
The categories above only cover intermediaries that take part in the HTTP communication. There are also intermediaries that act on lower layers of the network protocol stack, filtering or redirecting HTTP traffic without the knowledge or permission of the message senders ๐ > Network intermediaries are indistinguishable (at a protocol level) from an on-path attacker, and they often introduce security flaws or interoperability problems by mistakenly violating HTTP semantics. this is the part where you should be scared ๐ญ
For example, an "interception proxy" [RFC3040] (also commonly known as a "transparent proxy" [RFC1919]) differs from an HTTP proxy because it is not chosen by the client ๐ต๏ธ Instead, an interception proxy filters or redirects outgoing TCP port 80 packets (and occasionally other common port traffic). They're commonly found on public network access points, as a way of enforcing account subscription before you can use non-local Internet services, and inside corporate firewalls to enforce network usage policies ๐ผ
3.8. Caches ๐ธ
A "cache" is a local store of previous response messages, plus the subsystem that controls its message storage, retrieval, and deletion ๐๏ธ A cache stores cacheable responses so that the response time and network bandwidth consumption get reduced for future, equivalent requests ๐ Any client or server MAY employ a cache, though a cache cannot be used while acting as a tunnel. tunnels are cache-free zones, sorry not sorry ๐ โโ๏ธ
The effect of a cache is that the request/response chain gets shortened if one of the participants along the chain has a cached response applicable to that request โ๏ธ The figure below shows the resulting chain if B has a cached copy of an earlier response from O (via C) for a request that hasn't been cached by UA or A.
> >
UA =========== A =========== B - - - - - - C - - - - - - O
< <
Figure 3
A response is "cacheable" if a cache is allowed to store a copy of the response message for use in answering subsequent requests ๐พ Even when a response is cacheable, the client or the origin server might place additional constraints on when that cached response can be used for a particular request ๐ง HTTP requirements for cache behaviour and cacheable responses are defined in [CACHING] ๐
There is a wide variety of cache architectures and configurations across the World Wide Web and inside large organisations ๐ These include national hierarchies of proxy caches to save bandwidth and reduce latency, content delivery networks that use gateway caching to optimise regional and global distribution of popular sites, collaborative systems that broadcast or multicast cache entries, archives of pre-fetched cache entries for use in off-line or high-latency environments, and so on ๐ง
3.9. Example Message Exchange ๐
okay let's see it in action ๐ฌ The following example shows a typical HTTP/1.1 message exchange for a GET request (Section 9.3.1) on the URI http://www.example.com/hello.txt:
Client request:
GET /hello.txt HTTP/1.1
User-Agent: curl/7.64.1
Host: www.example.com
Accept-Language: en, mi
Server response:
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
ETag: "34aa387-d-1568eb00"
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain
Hello World! My content includes a trailing CRLF.
4. Identifiers in HTTP โจ
okay the identifier era ๐ชช Uniform Resource Identifiers (URIs) [URI] are used all throughout HTTP as the way to identify resources (Section 3.1) ๐
4.1. URI References ๐
URI references are used to target requests, indicate redirects, and define relationships. they're basically the glue of the web ๐ซถ
The definitions of "URI-reference", "absolute-URI", "relative-part", "authority", "port", "host", "path-abempty", "segment", and "query" are adopted from the URI generic syntax ๐ค An "absolute-path" rule is defined for protocol elements that can contain a non-empty path component. (This rule differs slightly from the path-abempty rule of RFC 3986, which allows for an empty path, and from the path-absolute rule, which does not allow paths that begin with "//".) A "partial-URI" rule is defined for protocol elements that can contain a relative URI but not a fragment component ๐งฉ
URI-reference = <URI-reference, see [URI], Section 4.1>
absolute-URI = <absolute-URI, see [URI], Section 4.3>
relative-part = <relative-part, see [URI], Section 4.2>
authority = <authority, see [URI], Section 3.2>
uri-host = <host, see [URI], Section 3.2.2>
port = <port, see [URI], Section 3.2.3>
path-abempty = <path-abempty, see [URI], Section 3.3>
segment = <segment, see [URI], Section 3.3>
query = <query, see [URI], Section 3.4>
absolute-path = 1*( "/" segment )
partial-URI = relative-part [ "?" query ]
Each protocol element in HTTP that allows a URI reference will say in its ABNF production whether it allows any form of reference (URI-reference), only a URI in absolute form (absolute-URI), only the path and optional query components (partial-URI), or some combination of the above ๐บ๏ธ Unless otherwise indicated, URI references are parsed relative to the target URI (Section 7.1) ๐
It is RECOMMENDED that all senders and recipients support, at a minimum, URIs with lengths of 8000 octets in protocol elements. Note that this implies some structures and on-wire representations (for example, the request line in HTTP/1.1) will necessarily be larger in some cases ๐
4.2. HTTP-Related URI Schemes ๐ฆ
IANA maintains the registry of URI Schemes [BCP35] at <https://www.iana.org/assignments/uri-schemes/>. Although requests might target any URI scheme, the following schemes are inherent to HTTP servers ๐
+============+====================================+=========+
| URI Scheme | Description | Section |
+============+====================================+=========+
| http | Hypertext Transfer Protocol | 4.2.1 |
+------------+------------------------------------+---------+
| https | Hypertext Transfer Protocol Secure | 4.2.2 |
+------------+------------------------------------+---------+
Table 2
Note that the presence of an "http" or "https" URI does not imply that there is always an HTTP server at the identified origin listening for connections ๐ Anyone can mint a URI, whether or not a server exists and whether or not that server currently maps that identifier to a resource ๐ช The delegated nature of registered names and IP addresses creates a federated namespace whether or not an HTTP server is present ๐
4.2.1. http URI Scheme ๐ธ
okay so the "http" URI scheme is defined right here ๐ It's for minting identifiers inside the hierarchical namespace run by a potential HTTP origin server, one that's listening for TCP ([TCP]) connections on a given port. Maybe there's a server there, maybe there isn't, but the name lives in that namespace ๐ฆ
http-URI = "http" "://" authority path-abempty [ "?" query ]
The origin server for an "http" URI is identified by the authority component. That includes a host identifier ([URI], Section 3.2.2) and an optional port number ([URI], Section 3.2.3). If the port subcomponent is empty or just not given, TCP port 80 (the reserved port for WWW services) is the default ๐. The origin decides who has the right to respond authoritatively to requests aimed at the identified resource, as defined in Section 4.3.2 ๐ .
ok but bestie, a sender MUST NOT generate an "http" URI with an empty host identifier ๐ โโ๏ธ And if a recipient gets one anyway, it MUST reject it as invalid. no exceptions, no vibes-based parsing ๐
The hierarchical path component and the optional query component identify the target resource within that origin server's namespace โจ
4.2.2. https URI Scheme ๐
the "https" URI scheme is also defined here ๐ It's basically the same energy, minting identifiers in the hierarchical namespace governed by a potential origin server listening for TCP connections on a given port. The difference is the glow-up: that server also has to be capable of setting up a TLS ([TLS13]) connection that's been secured for HTTP communication ๐
In this context, "secured" has a very specific meaning. The server has been authenticated as acting on behalf of the identified authority, AND all HTTP communication with that server has confidentiality and integrity protection that's acceptable to both client and server ๐ซถ
https-URI = "https" "://" authority path-abempty [ "?" query ]
The origin server for an "https" URI is also identified by the authority component, with a host identifier ([URI], Section 3.2.2) and an optional port number ([URI], Section 3.2.3). If the port subcomponent is empty or not given, TCP port 443 (the reserved port for HTTP over TLS) is the default ๐ The origin determines who has the right to respond authoritatively to requests for the identified resource, as defined in Section 4.3.3.
A sender MUST NOT generate an "https" URI with an empty host identifier ๐ โโ๏ธ A recipient that processes such a URI reference MUST reject it as invalid, same as with "http" ๐
The hierarchical path component and optional query component identify the target resource within that origin server's namespace ๐ฆ
A client MUST ensure that its HTTP requests for an "https" resource are secured before they're communicated, and that it only accepts secured responses to those requests. Also, the cryptographic mechanisms that are acceptable to client and server are usually negotiated, and they can change over time ๐
Resources on the "https" scheme have no shared identity with the "http" scheme. They're distinct origins with separate namespaces, so no mixing them up ๐ Still, extensions to HTTP that apply to all origins with the same host, like the Cookie protocol [COOKIE], let information set by one service impact communication with other services in a matching group of host domains. Those extensions ought to be designed with great care to stop information from a secured connection getting inadvertently exchanged within an unsecured context ๐จ
4.2.3. http(s) Normalization and Comparison ๐
URIs with an "http" or "https" scheme are normalized and compared according to the methods defined in Section 6 of [URI], using the defaults described above for each scheme. It's giving tidy-up energy ๐งน
HTTP does not require a specific method for determining equivalence. For example, a cache key might be compared as a simple string, after syntax-based normalization, or after scheme-based normalization ๐
Scheme-based normalization (Section 6.2.3 of [URI]) of "http" and "https" URIs involves these extra rules:
- If the port is equal to the default port for a scheme, the normal form is to omit the port subcomponent.
- When not being used as the target of an OPTIONS request, an empty path component is equivalent to an absolute path of "/", so the normal form is to provide a path of "/" instead.
- The scheme and host are case-insensitive and normally provided in lowercase; all other components are compared in a case-sensitive manner.
- Characters other than those in the "reserved" set are equivalent to their percent-encoded octets: the normal form is to not encode them (see Sections 2.1 and 2.2 of [URI]).
For example, these three URIs are equivalent โจ
http://example.com:80/~smith/home.html
http://EXAMPLE.com/%7Esmith/home.html
http://EXAMPLE.com:/%7esmith/home.html
Two HTTP URIs that are equivalent after normalization (using any method) can be assumed to identify the same resource, and any HTTP component MAY perform normalization ๐ As a result, distinct resources SHOULD NOT be identified by HTTP URIs that are equivalent after normalization (using any method defined in Section 6.2 of [URI]). so don't give two different things the same-looking address, bestie ๐
4.2.4. Deprecation of userinfo in http(s) URIs ๐ โโ๏ธ
The URI generic syntax for authority also includes a userinfo subcomponent ([URI], Section 3.2.1) for putting user authentication information in the URI. The "user:password" format inside that subcomponent is deprecated, so we're moving on from it ๐
Some implementations use the userinfo component for internal configuration of authentication information, like in command invocation options, configuration files, or bookmark lists. Even so, that usage might expose a user identifier or password ๐ญ
A sender MUST NOT generate the userinfo subcomponent (and its "@" delimiter) when an "http" or "https" URI reference is generated within a message as a target URI or field value. no "@" sneaking in, period ๐ซ
Before making use of an "http" or "https" URI reference received from an untrusted source, a recipient SHOULD parse for userinfo and treat its presence as an error. Its presence is a red flag because it's likely being used to hide the real authority for phishing attacks ๐ฃ
4.2.5. http(s) References with Fragment Identifiers ๐ง
Fragment identifiers let you indirectly identify a secondary resource, no matter the URI scheme, as defined in Section 3.5 of [URI]. Some protocol elements that refer to a URI allow a fragment to be included, while others don't. You can tell them apart by the ABNF rule: elements where a fragment is allowed use one rule, and the others use a specific rule that excludes fragments ๐ฆ
Note: The fragment identifier component isn't part of the scheme definition for a URI scheme (see Section 4.3 of [URI]). That's why it doesn't show up in the ABNF definitions for the "http" and "https" URI schemes above ๐ค
4.3. Authoritative Access ๐
Authoritative access means dereferencing a given identifier to access the identified resource, in a way the client believes is authoritative, which means controlled by the resource owner ๐ The URI scheme defines how access is granted, and that process often uses data inside the URI components, like the authority component when the generic syntax is used. Still, authoritative access isn't limited to that one mechanism โจ
Section 4.3.1 defines the concept of an origin as a helper for these uses, and the subsections after it explain how to establish that a peer has the authority to represent an origin ๐
See Section 17.1 for security considerations related to establishing authority ๐จ
4.3.1. URI Origin ๐
The "origin" for a given URI is the triple of scheme, host, and port, after normalizing the scheme and host to lowercase and normalizing the port to remove any leading zeros. If the port is elided from the URI, the default port for that scheme is used. For example, this URI:
https://Example.Com/happy.js
would have the origin:
{ "https", "example.com", "443" }
which can also be written as the normalized URI prefix with the port always present:
https://example.com:443
Each origin defines its own namespace and controls how identifiers within that namespace are mapped to resources ๐บ๏ธ How the origin responds to valid requests, consistently over time, determines the semantics users associate with a URI. The usefulness of those semantics is what ultimately turns these mechanisms into a resource people can reference and access later ๐
Two origins are distinct if they differ in scheme, host, or port. Even when it can be verified that the same entity controls two distinct origins, the two namespaces under those origins are distinct unless a server authoritative for that origin explicitly aliases them ๐
Origin is also used within HTML and related Web protocols, which are beyond the scope of this document, as described in [RFC6454] ๐
4.3.2. http Origins ๐ฆ
Although HTTP is independent of the transport protocol, the "http" scheme (Section 4.2.1) is specific to associating authority with whoever controls the origin server listening for TCP connections on the indicated port of whatever host is identified in the authority component. This is a very weak sense of authority ๐ฌ It depends on client-specific name resolution mechanisms, and on communication that might not be secured from an on-path attacker. Still, it's a sufficient minimum for binding "http" identifiers to an origin server for consistent resolution within a trusted environment ๐ซถ
If the host identifier is an IP address, the origin server is the listener (if any) on the indicated TCP port at that IP address. If the host is a registered name, that name is an indirect identifier for use with a name resolution service, such as DNS, to find an address for an appropriate origin server ๐งญ
When an "http" URI is used in a context that calls for access to the indicated resource, a client MAY attempt access. It does this by resolving the host identifier to an IP address, establishing a TCP connection to that address on the indicated port, and sending over that connection an HTTP request message. That request has a request target matching the client's target URI (Section 7.1) ๐จ
If the server responds to such a request with a non-interim HTTP response message, as described in Section 15, then that response is considered an authoritative answer to the client's request ๐ฏ
Note, however, that the above is not the only way to get an authoritative response, and it doesn't mean an authoritative response is always necessary (see [CACHING]) ๐ค For example, the Alt-Svc header field [ALTSVC] lets an origin server identify other services that are also authoritative for that origin. Access to "http" identified resources might also be provided by protocols outside the scope of this document ๐
4.3.3. https Origins โจ
okay so the "https" scheme (Section 4.2.2) is all about trust. a server gets authority because it can use the private key that goes with a certificate the client finds trustworthy for that origin server ๐ the client usually leans on a chain of trust that starts from some prearranged or configured trust anchor, and that's how it decides a certificate is trustworthy (Section 4.3.4) ๐ง
in HTTP/1.1 and earlier, a client only gives a server authority when they're talking over a connection that got successfully established and secured, and that connection goes specifically to the host in that URI origin. the connection setup and the certificate check together count as the proof ๐
in HTTP/2 and HTTP/3 it's a little more relaxed ๐ฆ a client gives a server authority when it's on a successfully established and secured connection and the URI origin's host matches any of the hosts listed in the server's certificate, AND the client believes it could open a connection to that host for that URI. in practice the client does a DNS query to check that the origin's host resolves to the same server IP address as the connection it already has. this restriction can be lifted if the origin server sends an equivalent ORIGIN frame [RFC8336] โจ
the request target's host and port value get sent inside every HTTP request. that's how the origin is identified and kept separate from other namespaces the same server might control (Section 7.2) ๐ it's on the origin to make sure any services that get control over its certificate's private key are just as responsible for managing the matching "https" namespaces, or at least ready to reject requests that look misdirected (Section 7.4) ๐ซถ
an origin server might not want to process requests for certain target URIs even when it has the authority to do so ๐ for example, when one host runs different services on different ports (like 443 and 8000), the origin server has to check the target URI (even after the connection is secured) because a network attacker might get connections meant for one port delivered to some other port. if nobody checks, that attacker could swap a response for one target URI (like "https://example.com/foo") with a seemingly authoritative response from the other port (like "https://example.com:8000/foo") ๐ญ
the "https" scheme doesn't rely on TCP or the connected port number to link up authority, because both sit outside the secured communication and so can't be trusted as definitive ๐ that means the HTTP communication can happen over any channel that's been secured (as defined in Section 4.2.2), including protocols that don't use TCP at all ๐
when an "https" URI gets used somewhere that calls for access to the resource it points at, a client MAY try access by resolving the host identifier to an IP address, opening a TCP connection to that address on the indicated port, securing that connection end-to-end by successfully starting TLS over TCP with confidentiality and integrity protection, and then sending over that connection an HTTP request message whose request target matches the client's target URI (Section 7.1) ๐
if the server answers that request with a non-interim HTTP response message (see Section 15), then that response counts as an authoritative answer to the client's request ๐
BUT the above isn't the only way to get an authoritative response, and it doesn't mean an authoritative response is always needed either (see [CACHING]) ๐ง
4.3.4. https Certificate Verification
to set up a secured connection so it can dereference a URI, a client MUST verify that the service's identity is an acceptable match for the URI's origin server ๐ certificate verification is what stops server impersonation, whether it comes from an on-path attacker or from an attacker who controls name resolution. this process needs the client to be configured with a set of trust anchors ๐ง
generally speaking, a client MUST verify the service identity using the verification process defined in Section 6 of [RFC6125] ๐ the client MUST also build a reference identity from the service's host. if the host is a literal IP address (Section 4.3.5), the reference identity is an IP-ID. otherwise the host is a name, and the reference identity is a DNS-ID ๐ธ
a reference identity of type CN-ID MUST NOT be used by clients ๐ซ as noted in Section 6.2.1 of [RFC6125], a CN-ID reference identity might still get used by older clients ๐ฆ
a client might be specially configured to accept a different form of server identity verification โจ for example, a client might be connecting to a server whose address and hostname are dynamic, with the expectation that the service will present a specific certificate (or a certificate matching some externally defined reference identity) instead of one matching the target URI's origin ๐
in special cases it might make sense for a client to just ignore the server's identity, but it has to be understood that this leaves the connection open to active attack ๐ฌโ ๏ธ
if the certificate isn't valid for the target URI's origin, a user agent MUST either get confirmation from the user before going ahead (see Section 3.5) or end the connection with a bad certificate error ๐ โโ๏ธ automated clients MUST log the error to an appropriate audit log (if there is one available) and SHOULD end the connection (with a bad certificate error) ๐ automated clients MAY offer a configuration setting that turns this check off, but they MUST offer a setting that turns it on ๐
4.3.5. IP-ID Reference Identity
a server that's identified with an IP address literal in the "host" field of an "https" URI has a reference identity of type IP-ID ๐ง an IP version 4 address uses the "IPv4address" ABNF rule, and an IP version 6 address uses the "IP-literal" production with the "IPv6address" option (see Section 3.2.2 of [URI]). a reference identity of IP-ID holds the decoded bytes of the IP address ๐ข
an IP version 4 address is 4 octets, and an IP version 6 address is 16 octets ๐ IP-ID isn't defined for any other IP version ๐ โโ๏ธ the iPAddress choice in the certificate subjectAltName extension doesn't explicitly say which IP version it is, so it relies on the length of the address to tell the versions apart (see Section 4.2.1.6 of [RFC5280]) ๐ค
a reference identity of type IP-ID matches if the address is identical to an iPAddress value in the certificate's subjectAltName extension โจ๐
5. Fields ๐
HTTP uses "fields" to carry data as extensible name/value pairs with a registered key namespace ๐ fields get sent and received inside the header and trailer sections of messages (Section 6) ๐
5.1. Field Names ๐ท๏ธ
a field name labels its field value so you know what semantics it has ๐ง for example, the Date header field is defined in Section 6.6.1 as holding the origination timestamp for the message it shows up in ๐ฐ๏ธ
field-name = token
field names are case-insensitive, and they ought to get registered in the "Hypertext Transfer Protocol (HTTP) Field Name Registry" (see Section 16.3.1) ๐
the meaning of a field doesn't change between minor versions of the same major HTTP version, though the default behavior of a recipient when that field is missing can change ๐ unless it says otherwise, fields are defined for all versions of HTTP ๐ธ in particular, the Host and Connection fields ought to be recognized by every HTTP implementation, whether or not it claims to conform with HTTP/1.1 ๐ซถ
new fields can be introduced without changing the protocol version, as long as their defined semantics let recipients that don't recognize them safely ignore them (see Section 16.3) ๐ฆ
a proxy MUST forward unrecognized header fields unless the field name is listed in the Connection header field (Section 7.6.1), or the proxy is specifically configured to block or otherwise transform those fields ๐ช other recipients SHOULD ignore unrecognized header and trailer fields ๐ following these requirements is what lets HTTP keep getting extended without anyone having to update or remove the intermediaries already out there ๐โจ
5.2. Field Lines and Combined Field Value ๐งฉ
field sections are made up of any number of "field lines" ๐ each one has a "field name" (see Section 5.1) that identifies the field, and a "field line value" that carries the data for that particular instance of the field ๐ท
when a field name only shows up once in a section, the combined "field value" for that field is just that field line's value ๐ซง when a field name repeats within a section, its combined field value is the list of its field line values in that section, joined together in order with a comma between each one ๐
here's an example of that ๐
Example-Field: Foo, Bar
Example-Field: Baz
this section has two field lines, and they both use the field name "Example-Field" ๐ the first field line value is "Foo, Bar", and the second is "Baz" ๐ so the field value for "Example-Field" comes out as the list "Foo, Bar, Baz" ๐
5.3. Field Order ๐
a recipient MAY combine multiple field lines in a field section that share the same field name into one field line, and that doesn't change the message's semantics ๐ง you do it by appending each following field line value to the first one, in order, separated by a comma (",") and optional whitespace (OWS, defined in Section 5.6.3) โจ for consistency, use comma SP ๐
the order that field lines with the same name arrive in really matters for what the field value means ๐ง so a proxy MUST NOT change the order of those field line values when it forwards a message ๐ซ
that means (apart from the well-known exception below) a sender MUST NOT generate multiple field lines with the same name in a message (whether in the headers or trailers), and it MUST NOT append a field line when a field line with the same name is already in the message ๐
โโ๏ธ the only exception is when the field's definition lets multiple field line values be recombined as a comma-separated list. that means at least one option in the field's definition has to allow a comma-separated list, like an ABNF rule of #(values) defined in Section 5.6.1 ๐งฉ
Note: In practice, the "Set-Cookie" header field ([COOKIE]) often shows up across multiple field lines in a response message, and it doesn't use list syntax. that breaks the rules above about multiple field lines with the same field name ๐ญ since it can't be combined into a single field value, recipients ought to handle "Set-Cookie" as a special case while processing fields ๐ช (See Appendix A.2.3 of [Kri2001] for details.)
the order that field lines with different field names come in within a section doesn't matter ๐คทโโ๏ธ still, it's good practice to send header fields that carry extra control data first, like Host on requests and Date on responses, so implementations can decide as early as possible when not to handle a message ๐ฆ
a server MUST NOT apply a request to the target resource until it has received the entire request header section ๐ that's because later header field lines might include conditionals, authentication credentials, or sneaky misleading duplicate header fields that could change how the request gets processed ๐ต๏ธโโ๏ธ๐
5.4. Field Limits โจ
okay so HTTP doesn't put a set limit on how long each field line is, or on each field value, or on a whole header or trailer section ๐ (that's what Section 2 is about). People do add their own little limits in the real world, often depending on what the field is for ๐
if a server gets a request header field line, field value, or group of fields that's bigger than it wants to deal with, it MUST respond with an appropriate 4xx (Client Error) status code ๐ซ ignoring those headers would make the server way more vulnerable to request smuggling attacks (Section 11.2 of [HTTP/1.1]), so don't be that server ๐
clients get a little more freedom ๐ฆ a client MAY discard or truncate received field lines that are bigger than it wants to process, but only if the field's meaning is such that the dropped value(s) can be safely ignored without messing up the message framing or response semantics ๐ธ
5.5. Field Values ๐
HTTP field values are a sequence of characters in a format that the field's grammar defines. Each field's grammar is usually written in ABNF ([RFC5234]) ๐ง
field-value = *field-content
field-content = field-vchar
[ 1*( SP / HTAB / field-vchar ) field-vchar ]
field-vchar = VCHAR / obs-text
obs-text = %x80-FF
a field value doesn't include leading or trailing whitespace โจ and when a specific HTTP version lets that whitespace show up in a message, a field parsing implementation MUST exclude it before it evaluates the field value ๐งน
field values are usually kept to the US-ASCII range ([USASCII]) ๐ fields that need more characters can use an encoding like the one in [RFC8187] ๐ historically, HTTP let field content carry text in the ISO-8859-1 charset ([ISO-8859-1]), and other charsets only worked through [RFC2047] encoding ๐ for newly defined fields, the spec SHOULD limit values to visible US-ASCII octets (VCHAR), SP, and HTAB ๐ซถ and a recipient SHOULD treat any other allowed octets in field content (that's obs-text) as opaque data, meaning it doesn't try to read into them ๐
okay now this part is serious bestie ๐ญ field values with CR, LF, or NUL characters are invalid and dangerous, because implementations can parse and interpret those characters in all kinds of different ways ๐ so a recipient that finds CR, LF, or NUL inside a field value MUST either reject the message or replace each of those characters with SP before it does any further processing or forwards the message ๐จ field values with other CTL characters are invalid too, but recipients MAY keep those characters for robustness when they show up in a safe context (like an application-specific quoted string that no downstream HTTP parser will touch) ๐ฅ
fields that only expect one member as the value are called "singleton fields" ๐ fields that take several members are called "list-based fields" ๐ the list operator extension in Section 5.6.1 is the shared notation for defining field values that can hold multiple members โจ
commas (",") are the delimiter between members, so they need extra care if they're allowed as data inside a member ๐ซฃ this applies to both list-based and singleton fields, since a singleton might get sent with multiple members by mistake, and catching that kind of error makes things more interoperable ๐ค fields that need a comma inside a member, like an HTTP-date or URI-reference element, ought to be defined with delimiters around that element so the comma in the data doesn't get mistaken for a list separator ๐
here's an example. a textual date and a URI can both have commas in them, and they can still be safely carried in list-based field values like these ๐ฆ
Example-URIs: "http://example.com/a.html,foo",
"http://without-a-comma.example.com/"
Example-Dates: "Sat, 04 May 1996", "Wed, 14 Sep 2005"
quick reminder that double quotes are almost always paired with the quoted-string production (Section 5.6.4), so using a different syntax inside the double quotes will probably cause a lot of confusion ๐ตโ๐ซ
lots of fields (like Content-Type, from Section 8.3) use a shared parameter syntax, which lets a parameter value be unquoted (token) or quoted (quoted-string) (Section 5.6.6) ๐ using that common syntax means recipients can reuse the parser parts they already have ๐งฉ and if both forms are allowed, the meaning of a parameter value ought to be the same whether it came in as a token or as a quoted string โจ
Note: for defining field value syntax, this spec uses an ABNF rule named after the field name to describe the allowed grammar for that field's value. that happens after the value has been pulled out of the underlying messaging syntax and multiple instances have been combined into a list ๐ง
5.6. Common Rules for Defining Field Values ๐
5.6.1. Lists (#rule ABNF Extension)
an extension called #rule gets added to the ABNF rules from [RFC5234] to make the list-based field value definitions way easier to read ๐
there's a "#" construct, kind of like "*", for defining comma-delimited lists of elements. the full form is "<n>#<m>element", which means at least <n> and at most <m> elements, each separated by a single comma (",") and optional whitespace (OWS, defined in Section 5.6.3) ๐
5.6.1.1. Sender Requirements
in any production that uses the list construct, a sender MUST NOT generate empty list elements ๐ โโ๏ธ in other words, a sender has to generate lists that follow this syntax:
1#element => element *( OWS "," OWS element )
and:
#element => [ 1#element ]
and for n >= 1 and m > 1:
<n>#<m>element => element <n-1>*<m-1>( OWS "," OWS element )
Appendix A has the collected ABNF for senders once the list constructs have been expanded ๐
5.6.1.2. Recipient Requirements
empty elements don't count toward the number of elements present ๐ซ a recipient MUST parse and ignore a reasonable number of empty list elements. that's enough to handle common sender mistakes that merge values, but not so many that they could be abused as a denial-of-service mechanism ๐ซ so a recipient MUST accept lists that follow this syntax:
#element => [ element ] *( OWS "," OWS [ element ] )
because empty list elements can show up, the RFC 5234 ABNF can't enforce how many list elements there are. so every case gets mapped as if no cardinality was specified ๐คทโโ๏ธ
for example, with these ABNF productions:
example-list = 1#example-list-elmt
example-list-elmt = token ; see Section 5.6.2
these are valid values for example-list (the double quotes aren't part of the value, they're just there to show where it starts and ends) ๐
"foo,bar"
"foo ,bar,"
"foo , ,bar,charlie"
and these are invalid, since example-list needs at least one non-empty element ๐
""
","
", ,"
5.6.2. Tokens ๐งโโ๏ธ
tokens are short textual identifiers with no whitespace or delimiters in them โจ
token = 1*tchar
tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
/ "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
/ DIGIT / ALPHA
; any VCHAR, except delimiters
lots of HTTP field values are built from common syntax parts that are separated by whitespace or specific delimiting characters ๐ธ the delimiters come from the US-ASCII visual characters that aren't allowed in a token, which are DQUOTE and "(),/:;<=>?@[\]{}" ๐
5.6.3. Whitespace ๐ซง
this spec uses three rules for linear whitespace: OWS (optional whitespace), RWS (required whitespace), and BWS ("bad" whitespace) ๐ฉท
the OWS rule covers places where zero or more linear whitespace octets might show up. when a protocol element prefers optional whitespace for readability, a sender SHOULD generate that optional whitespace as a single SP. otherwise, a sender SHOULD NOT generate optional whitespace, except when it's needed to overwrite invalid or unwanted protocol elements during in-place message filtering ๐งฝ
the RWS rule is for when at least one linear whitespace octet is required to separate field tokens. a sender SHOULD generate RWS as a single SP ๐
OWS and RWS mean exactly the same thing as a single SP ๐ค any content known to be OWS or RWS MAY be replaced with a single SP before it gets interpreted or forwarded downstream โจ
the BWS rule is for places where the grammar only allows optional whitespace for historical reasons ๐ฐ๏ธ a sender MUST NOT generate BWS in messages, and a recipient MUST parse for that bad whitespace and remove it before interpreting the protocol element ๐ โโ๏ธ BWS has no semantics, so any content known to be BWS MAY be removed before it gets interpreted or forwarded ๐งน
OWS = *( SP / HTAB )
; optional whitespace
RWS = 1*( SP / HTAB )
; required whitespace
BWS = OWS
; "bad" whitespace
5.6.4. Quoted Strings ๐ฌ
a string of text gets parsed as a single value if it's wrapped in double-quote marks ๐
quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text
the backslash octet ("") works as a single-octet quoting mechanism inside quoted-string and comment constructs ๐ฆ recipients that process the value of a quoted-string MUST handle a quoted-pair as if it were replaced by the octet that follows the backslash ๐
quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
a sender SHOULD NOT generate a quoted-pair in a quoted-string unless it's necessary to quote DQUOTE and backslash octets inside that string ๐ and a sender SHOULD NOT generate a quoted-pair in a comment unless it's necessary to quote parentheses ["(" and ")"] and backslash octets inside that comment ๐ซถ
5.6.5. Comments ๐
comments can go in some HTTP fields by wrapping the comment text in parentheses ๐ง but they're only allowed in fields that have "comment" as part of their field value definition ๐
comment = "(" *( ctext / quoted-pair / comment ) ")"
ctext = HTAB / SP / %x21-27 / %x2A-5B / %x5D-7E / obs-text
5.6.6. Parameters ๐ฆ
parameters are name/value pairs ๐ they're often used in field values as a shared syntax for adding extra info to an item. each parameter is usually introduced by an immediately preceding semicolon ๐ช
parameters = *( OWS ";" OWS [ parameter ] )
parameter = parameter-name "=" parameter-value
parameter-name = token
parameter-value = ( token / quoted-string )
parameter names are case-insensitive ๐ค parameter values might or might not be case-sensitive, depending on what the parameter name means ๐ค you can see examples of parameters, and some equivalent forms, in media types (Section 8.3.1) and in the Accept header field (Section 12.5.1) ๐
a parameter value that matches the token production can be sent either as a token or inside a quoted-string, and the quoted and unquoted versions are equivalent ๐ท
Note: parameters don't allow any whitespace (not even "bad" whitespace) around the "=" character ๐ โโ๏ธ
5.6.7. Date/Time Formats ๐ฐ๏ธโจ
Okay so, before 1995 servers had like three different ways to write timestamps ๐ญ For the sake of old implementations, all three are defined here. The preferred one is a fixed-length, single-zone slice of the date and time spec from the Internet Message Format [RFC5322] ๐
HTTP-date = IMF-fixdate / obs-date
Here's an example of the preferred format:
Sun, 06 Nov 1994 08:49:37 GMT ; IMF-fixdate
And here are the two obsolete ones:
Sunday, 06-Nov-94 08:49:37 GMT ; obsolete RFC 850 format
Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
Okay, the big rule here: a recipient that parses a timestamp in an HTTP field MUST accept all three HTTP-date formats ๐ซถ And when a sender generates a field with one or more timestamps defined as HTTP-date, the sender MUST generate those timestamps in the IMF-fixdate format. No vibes-based formatting, periodt ๐ โโ๏ธ
Now, an HTTP-date is an instance of Coordinated Universal Time (UTC) ๐ The first two formats say so with "GMT", which is basically the older cousin of the UTC name ๐ง The asctime format doesn't say it out loud, so its values are just assumed to be UTC.
A "clock" is an implementation that can give a reasonable approximation of the current instant in UTC โฐ A clock implementation ought to use NTP ([RFC5905]), or some similar protocol, to sync up with UTC. Iconic behavior, honestly ๐
Preferred format:
IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT
; fixed length/zone/capitalization subset of the format
; see Section 3.3 of [RFC5322]
day-name = %s"Mon" / %s"Tue" / %s"Wed"
/ %s"Thu" / %s"Fri" / %s"Sat" / %s"Sun"
date1 = day SP month SP year
; e.g., 02 Jun 1982
day = 2DIGIT
month = %s"Jan" / %s"Feb" / %s"Mar" / %s"Apr"
/ %s"May" / %s"Jun" / %s"Jul" / %s"Aug"
/ %s"Sep" / %s"Oct" / %s"Nov" / %s"Dec"
year = 4DIGIT
GMT = %s"GMT"
time-of-day = hour ":" minute ":" second
; 00:00:00 - 23:59:60 (leap second)
hour = 2DIGIT
minute = 2DIGIT
second = 2DIGIT
Obsolete formats (the throwback era ๐):
obs-date = rfc850-date / asctime-date
rfc850-date = day-name-l "," SP date2 SP time-of-day SP GMT
date2 = day "-" month "-" 2DIGIT
; e.g., 02-Jun-82
day-name-l = %s"Monday" / %s"Tuesday" / %s"Wednesday"
/ %s"Thursday" / %s"Friday" / %s"Saturday"
/ %s"Sunday"
asctime-date = day-name SP date3 SP time-of-day SP year
date3 = month SP ( 2DIGIT / ( SP 1DIGIT ))
; e.g., Jun 2
HTTP-date is case sensitive ๐ง Note that Section 4.2 of [CACHING] relaxes this for cache recipients, which is a whole mood ๐ฆ
A sender MUST NOT generate additional whitespace in an HTTP-date beyond what's specifically included as SP in the grammar. The meanings of day-name, day, month, year, and time-of-day are the same as the Internet Message Format constructs with the matching name ([RFC5322], Section 3.3). Same energy, different app ๐
Recipients of a timestamp in rfc850-date format, which uses a two-digit year, MUST interpret a timestamp that seems to be more than 50 years in the future as the most recent year in the past that had the same last two digits. Time-travel handling, but make it logical ๐
Recipients of timestamp values are encouraged to be robust when parsing timestamps, unless the field definition restricts them otherwise. For example, messages sometimes get forwarded over HTTP from a non-HTTP source that might generate any of the date and time specifications defined by the Internet Message Format ๐ฌ
Note: HTTP requirements for timestamp formats apply only to their usage within the protocol stream. Implementations are not required to use these formats for user presentation, request logging, etc. ๐
6. Message Abstraction ๐งฉ
Each major version of HTTP defines its own syntax for messages, which is very relatable honestly ๐ This section defines an abstract data type for HTTP messages, built by generalizing their characteristics, common structure, and ability to convey semantics. The abstraction is used to write requirements for senders and recipients that don't depend on the HTTP version. That way, a message from one version can get relayed through other versions without changing its meaning ๐ฆ
A "message" consists of the following:
- control data to describe and route the message,
- a headers lookup table of name/value pairs for extending that control data and conveying additional information about the sender, message, content, or context,
- a potentially unbounded stream of content, and
- a trailers lookup table of name/value pairs for communicating information obtained while sending the content.
Framing and control data get sent first, followed by a header section containing fields for the headers table. When a message includes content, that content is sent after the header section, and it might be followed by a trailer section with fields for the trailers table โจ
Messages are meant to be processed as a stream, so the purpose of the stream reveals itself while you're reading it ๐ Control data tells the recipient what it needs to know right away, header fields describe what needs to be known before content arrives, the content (when present) usually has what the recipient wants or needs to fulfill the message semantics, and trailer fields are optional metadata that wasn't known until after the content was sent ๐
Messages are supposed to be "self-descriptive": everything a recipient needs to know can be figured out by looking at the message itself, after decoding or rebuilding any parts that were compressed or left out in transit. You don't need to know the sender's current app state (set up by earlier messages) to get it. However, a client MUST retain knowledge of the request when parsing, interpreting, or caching a corresponding response. For example, responses to the HEAD method look just like the start of a response to GET, but they can't be parsed the same way ๐
Note that this message abstraction is a generalization across many versions of HTTP, including features that might not exist in some versions. For example, trailers were introduced within the HTTP/1.1 chunked transfer coding as a trailer section after the content. An equivalent feature exists in HTTP/2 and HTTP/3 within the header block that ends each stream ๐ธ
6.1. Framing and Completeness ๐ชข
Message framing shows how each message begins and ends, so every message can be told apart from other messages or noise on the same connection ๐ Each major version of HTTP defines its own framing mechanism.
HTTP/0.9 and early deployments of HTTP/1.0 used closing the underlying connection to end a response ๐ For backwards compatibility, this implicit framing is also allowed in HTTP/1.1. The catch is that implicit framing can fail to tell an incomplete response apart when the connection closes early. That's why almost all modern implementations use explicit framing, in the form of length-delimited sequences of message data ๐
A message is considered "complete" when all of the octets indicated by its framing are available. Note that when no explicit framing is used, a response message that ends with the underlying connection closing is considered complete, even though it might look exactly like an incomplete response. The exception is if a transport-level error shows it isn't complete ๐ฌ
6.2. Control Data ๐๏ธ
Messages start with control data that describes their primary purpose. Request message control data includes a request method (Section 9), request target (Section 7.1), and protocol version (Section 2.5). Response message control data includes a status code (Section 15), an optional reason phrase, and a protocol version ๐
In HTTP/1.1 ([HTTP/1.1]) and earlier, control data is sent as the first line of a message. In HTTP/2 ([HTTP/2]) and HTTP/3 ([HTTP/3]), control data is sent as pseudo-header fields with a reserved name prefix (e.g., ":authority") ๐ง
Every HTTP message has a protocol version. Depending on the version in use, it might be identified explicitly within the message or inferred from the connection it arrived on. Recipients use that version info to figure out the limitations or potential for later communication with that sender ๐
When an intermediary forwards a message, the protocol version gets updated to reflect the version that intermediary used ๐ The Via header field (Section 7.6.3) is how upstream protocol info gets communicated inside a forwarded message.
A client SHOULD send a request version equal to the highest version it's conformant with, as long as that major version isn't higher than the highest version the server supports, if that's known ๐ง A client MUST NOT send a version it isn't conformant with ๐ โโ๏ธ
A client MAY send a lower request version if it's known that the server incorrectly implements the HTTP specification. But it can only do that after the client has tried at least one normal request and figured out from the response status code or header fields (e.g., Server) that the server handles higher request versions badly ๐ญ
A server SHOULD send a response version equal to the highest version it's conformant with that has a major version less than or equal to the one received in the request ๐ A server MUST NOT send a version it isn't conformant with. A server can send a 505 (HTTP Version Not Supported) response if it wants, for any reason, to refuse service for the client's major protocol version ๐ซ
A recipient that gets a message with a major version number it implements and a minor version number higher than what it implements SHOULD process the message as if it were in the highest minor version, within that major version, that the recipient is conformant with โจ A recipient can assume that a message with a higher minor version, when sent to a recipient that hasn't yet indicated support for that higher version, is backwards-compatible enough to be safely processed by any implementation of the same major version ๐
6.3. Header Fields ๐
Fields (Section 5) that are sent or received before the content get called "header fields" (or just "headers," colloquially) ๐
The "header section" of a message is a sequence of header field lines. Each header field might modify or extend message semantics, describe the sender, define the content, or provide additional context ๐ธ
Note: We refer to named fields specifically as a "header field" when they are only allowed to be sent in the header section. ๐
6.4. Content โจ
HTTP messages often carry a complete or partial representation as the message "content": a stream of octets that shows up after the header section, as marked out by the message framing. ๐
This abstract definition of content is the data after it's been pulled out of the message framing. ๐ For example, an HTTP/1.1 message body (Section 6 of [HTTP/1.1]) might be a stream of data sent with the chunked transfer coding (a sequence of data chunks, one zero-length chunk, and a trailer section) ๐ง, but the content of that same message only covers the data stream after the transfer coding has been decoded. It does NOT include the chunk lengths, the chunked framing syntax, or the trailer fields (Section 6.5). ๐
๐ Quick aside: some field names have a "Content-" prefix. This is an informal convention, okay? ๐ซถ Some of these fields talk about the content of the message as defined above, but others are scoped to the selected representation (Section 3.2). Check each individual field's definition to figure out which one it is. ๐ธ
6.4.1. Content Semantics โจ
The purpose of content in a request is defined by the method semantics (Section 9). ๐ฆ
For example, a representation in the content of a PUT request (Section 9.3.4) represents the desired state of the target resource after the request is successfully applied ๐ , whereas a representation in the content of a POST request (Section 9.3.3) represents information to be processed by the target resource. ๐ง
In a response, the content's purpose is defined by the request method, the response status code (Section 15), and the response fields describing that content. ๐ For example, the content of a 200 (OK) response to GET (Section 9.3.1) represents the current state of the target resource, as observed at the time of the message origination date (Section 6.6.1). Meanwhile, the content of that same status code in a response to POST might represent either the processing result or the new state of the target resource after the processing is applied. ๐
The content of a 206 (Partial Content) response to GET contains either a single part of the selected representation, or a multipart message body containing multiple parts of that representation, as described in Section 15.3.7. ๐
Response messages with an error status code usually contain content that represents the error condition, so the content describes the error state and what steps are suggested for resolving it. ๐ญ
Responses to the HEAD request method (Section 9.3.2) never include content. The associated response header fields only indicate what their values would have been if the request method had been GET (Section 9.3.1). ๐
2xx (Successful) responses to a CONNECT request method (Section 9.3.6) switch the connection to tunnel mode instead of having content. ๐ฅ
All 1xx (Informational), 204 (No Content), and 304 (Not Modified) responses do not include content. ๐ โโ๏ธ
All other responses do include content, although that content might be of zero length. โจ
6.4.2. Identifying Content โจ
When a complete or partial representation is transferred as message content, it's often desirable for the sender to supply an identifier (or for the recipient to figure one out) for a resource corresponding to that specific representation. ๐ For example, a client making a GET request on a resource for "the current weather report" might want an identifier specific to the content that came back (e.g., "weather report for Laguna Beach at 20210720T1711"). This is super useful for sharing or bookmarking content from resources whose representations are expected to change over time. ๐ธ
For a request message: ๐
- If the request has a Content-Location header field, then the sender asserts that the content is a representation of the resource identified by the Content-Location field value. However, such an assertion cannot be trusted unless it can be verified by other means (not defined by this specification). The information might still be useful for revision history links. ๐ฆ
- Otherwise, the content is unidentified by HTTP, but a more specific identifier might be supplied within the content itself. ๐ง
For a response message, the following rules are applied in order until a match is found: ๐
- If the request method is HEAD or the response status code is 204 (No Content) or 304 (Not Modified), there is no content in the response. ๐
- If the request method is GET and the response status code is 200 (OK), the content is a representation of the target resource (Section 7.1). โจ
- If the request method is GET and the response status code is 203 (Non-Authoritative Information), the content is a potentially modified or enhanced representation of the target resource as provided by an intermediary. ๐
- If the request method is GET and the response status code is 206 (Partial Content), the content is one or more parts of a representation of the target resource. ๐
- If the response has a Content-Location header field and its field value is a reference to the same URI as the target URI, the content is a representation of the target resource. ๐
- If the response has a Content-Location header field and its field value is a reference to a URI different from the target URI, then the sender asserts that the content is a representation of the resource identified by the Content-Location field value. However, such an assertion cannot be trusted unless it can be verified by other means (not defined by this specification). ๐ซถ
- Otherwise, the content is unidentified by HTTP, but a more specific identifier might be supplied within the content itself. ๐
6.5. Trailer Fields โจ
Fields (Section 5) that are located within a "trailer section" are called "trailer fields" (or just "trailers", colloquially). ๐ Trailer fields are super handy for supplying message integrity checks, digital signatures, delivery metrics, or post-processing status information. ๐
Trailer fields ought to be processed and stored separately from the fields in the header section, so they don't contradict message semantics that were already known when the header section was complete. ๐ง The presence or absence of certain header fields might affect choices made about routing or processing the message as a whole before the trailers arrive, and those choices can't be undone by discovering trailer fields later. ๐ฌ
6.5.1. Limitations on Use of Trailers โจ
A trailer section is only possible when the version of HTTP in use supports it and an explicit framing mechanism enables it. ๐ฆ For example, the chunked transfer coding in HTTP/1.1 lets a trailer section be sent after the content (Section 7.1.2 of [HTTP/1.1]). ๐ธ
Many fields can't be processed outside the header section, because their evaluation has to happen before the content is received. These include fields that describe message framing, routing, authentication, request modifiers, response controls, or content format. ๐ โโ๏ธ A sender MUST NOT generate a trailer field unless the sender knows that the corresponding header field name's definition permits the field to be sent in trailers. ๐ซ
Trailer fields can be tricky for intermediaries that forward messages from one protocol version to another. ๐ต If the entire message can be buffered in transit, some intermediaries could merge trailer fields into the header section (as appropriate) before forwarding it. However, in most cases, the trailers are simply discarded. ๐๏ธ A recipient MUST NOT merge a trailer field into a header section unless the recipient understands the corresponding header field definition, and that definition explicitly permits and defines how trailer field values can be safely merged. ๐
The presence of the keyword "trailers" in the TE header field (Section 10.1.4) of a request indicates that the client is willing to accept trailer fields, on behalf of itself and any downstream clients. For requests from an intermediary, this implies that all downstream clients are willing to accept trailer fields in the forwarded response. ๐ Note that the presence of "trailers" does NOT mean that the client(s) will process any particular trailer field in the response. It only means that the trailer section(s) won't be dropped by any of the clients. ๐
Because trailer fields might get discarded in transit, a server SHOULD NOT generate trailer fields that it believes are necessary for the user agent to receive. ๐ฅบ
6.5.2. Processing Trailer Fields โจ
The "Trailer" header field (Section 6.6.2) can be sent to indicate fields likely to be sent in the trailer section, which lets recipients get ready for them before processing the content. ๐ง For example, this could be useful if a field name indicates that a dynamic checksum should be calculated as the content is received and then immediately checked when the trailer field value shows up. ๐ฅ
Like header fields, trailer fields with the same name are processed in the order received. Multiple trailer field lines with the same name have the equivalent semantics of appending the multiple values as a list of members. ๐ Trailer fields that might be generated more than once during a message MUST be defined as a list-based field, even if each member value is only processed once per field line received. ๐
At the end of a message, a recipient MAY treat the set of received trailer fields as a data structure of name/value pairs, similar to (but separate from) the header fields. ๐ Any additional processing expectations can be defined within the field specification for a field intended for use in trailers. โจ
6.6. Message Metadata โจ
Fields that describe the message itself, like when and how the message has been generated, can show up in both requests and responses. ๐
6.6.1. Date โจ
okay so the Date header field tells everyone when the message was originated, bestie ๐ฐ๏ธ๐ it has the same semantics as the Origination Date Field (orig-date) from Section 3.6.1 of [RFC5322], and its value is an HTTP-date, as defined in Section 5.6.7. no cap, it's giving precision ๐
Date = HTTP-date
here's a cute example ๐
Date: Tue, 15 Nov 1994 08:12:31 GMT
so a sender that generates a Date header field SHOULD put in the best available approximation of when the message was generated ๐ธ in theory, the date ought to be the moment just before the message content gets generated, but in practice a sender can set the date at any time during message origination, which is lowkey relatable ๐
an origin server with a clock (as defined in Section 5.6.7) MUST generate a Date header field in all 2xx (Successful), 3xx (Redirection), and 4xx (Client Error) responses ๐ซถ and it MAY generate a Date header field in 1xx (Informational) and 5xx (Server Error) responses โจ
an origin server without a clock MUST NOT generate a Date header field ๐
โโ๏ธ no vibes without a clock, periodt ๐
a recipient with a clock that receives a response message without a Date header field MUST record the time it was received and append a corresponding Date header field to the message's header section if it is cached or forwarded downstream ๐ฆ
a recipient with a clock that receives a response with an invalid Date header field value MAY replace that value with the time that response was received ๐ง
a user agent MAY send a Date header field in a request, though generally it will not do so unless it is believed to convey useful information to the server ๐ for example, custom applications of HTTP might convey a Date if the server is expected to adjust its interpretation of the user's request based on differences between the user agent and server clocks โฐ
6.6.2. Trailer ๐
the Trailer header field is basically the sender's guest list ๐ it provides a list of field names that the sender anticipates sending as trailer fields within that message, so a recipient can prep for receiving that metadata before it starts processing the content ๐
Trailer = #field-name
for example, a sender might indicate that a signature will be computed as the content is being streamed and then provide the final signature as a trailer field ๐ this lets a recipient do the same check on the fly as it receives the content, which is seriously iconic ๐
a sender that intends to generate one or more trailer fields in a message SHOULD generate a Trailer header field in the header section of that message to indicate which fields might be present in the trailers ๐
if an intermediary discards the trailer section in transit, the Trailer field could provide a hint of what metadata was lost ๐ซฃ though there is no guarantee that a sender of Trailer will always follow through by sending the named fields ๐
7. Routing HTTP Messages ๐บ๏ธ
okay so HTTP request message routing is determined by each client based on the target resource, the client's proxy configuration, and establishment or reuse of an inbound connection ๐งญ the corresponding response routing then follows the same connection chain back to the client ๐
7.1. Determining the Target Resource ๐ฏ
although HTTP is used in a wide variety of applications, most clients rely on the same resource identification mechanism and configuration techniques as general-purpose Web browsers ๐ even when communication options are hard-coded in a client's configuration, we can think of their combined effect as a URI reference (Section 4.1) โจ
a URI reference is resolved to its absolute form in order to obtain the "target URI" ๐ the target URI excludes the reference's fragment component, if any, since fragment identifiers are reserved for client-side processing ([URI], Section 3.5) ๐ช
to perform an action on a "target resource", the client sends a request message containing enough components of its parsed target URI to enable recipients to identify that same resource ๐ for historical reasons, the parsed target URI components, collectively referred to as the "request target", are sent within the message control data and the Host header field (Section 7.2) ๐ซถ
there are two unusual cases where the request target components are in a method-specific form ๐
- For
CONNECT(Section 9.3.6), the request target is the host name and port number of the tunnel destination, separated by a colon. ๐ - For
OPTIONS(Section 9.3.7), the request target can be a single asterisk ("*"). โญ
see the respective method definitions for details ๐ these forms MUST NOT be used with other methods ๐ซ
upon receipt of a client's request, a server reconstructs the target URI from the received components in accordance with their local configuration and incoming connection context ๐งฉ this reconstruction is specific to each major protocol version ๐ข for example, Section 3.3 of [HTTP/1.1] defines how a server determines the target URI of an HTTP/1.1 request ๐
Note: Previous specifications defined the recomposed target URI as a distinct concept, the "effective request URI". ๐ต๏ธ
7.2. Host and :authority ๐
the Host header field in a request provides the host and port information from the target URI ๐ this enables the origin server to distinguish among resources while servicing requests for multiple host names ๐๏ธ
in HTTP/2 [HTTP/2] and HTTP/3 [HTTP/3], the Host header field is, in some cases, supplanted by the :authority pseudo-header field of a request's control data ๐
Host = uri-host [ ":" port ] ; Section 4
the target URI's authority information is critical for handling a request ๐จ a user agent MUST generate a Host header field in a request unless it sends that information as an :authority pseudo-header field ๐ a user agent that sends Host SHOULD send it as the first field in the header section of a request ๐ฅ
for example, a GET request to the origin server for <http://www.example.org/pub/WWW/> would begin with:
GET /pub/WWW/ HTTP/1.1
Host: www.example.org
since the host and port information acts as an application-level routing mechanism, it is a frequent target for malware seeking to poison a shared cache or redirect a request to an unintended server ๐ฑ an interception proxy is particularly vulnerable if it relies on the host and port information for redirecting requests to internal servers, or for use as a cache key in a shared cache, without first verifying that the intercepted connection is targeting a valid IP address for that host ๐ฉ
7.3. Routing Inbound Requests ๐ฌ
once the target URI and its origin are determined, a client decides whether a network request is necessary to accomplish the desired semantics and, if so, where that request is to be directed ๐บ๏ธ
7.3.1. To a Cache ๐๏ธ
if the client has a cache [CACHING] and the request can be satisfied by it, then the request is usually directed there first ๐โโ๏ธ
7.3.2. To a Proxy ๐ช
if the request is not satisfied by a cache, then a typical client will check its configuration to determine whether a proxy is to be used to satisfy the request โ๏ธ proxy configuration is implementation-dependent, but is often based on URI prefix matching, selective authority matching, or both ๐ and the proxy itself is usually identified by an "http" or "https" URI ๐
if an "http" or "https" proxy is applicable, the client connects inbound by establishing (or reusing) a connection to that proxy and then sending it an HTTP request message containing a request target that matches the client's target URI ๐จ
7.3.3. To the Origin ๐ก
if no proxy is applicable, a typical client will invoke a handler routine (specific to the target URI's scheme) to obtain access to the identified resource ๐๏ธ how that is accomplished is dependent on the target URI scheme and defined by its associated specification ๐
Section 4.3.2 defines how to obtain access to an "http" resource by establishing (or reusing) an inbound connection to the identified origin server and then sending it an HTTP request message containing a request target that matches the client's target URI ๐ซ
Section 4.3.3 defines how to obtain access to an "https" resource by establishing (or reusing) an inbound secured connection to an origin server that is authoritative for the identified origin and then sending it an HTTP request message containing a request target that matches the client's target URI ๐
7.4. Rejecting Misdirected Requests ๐ โโ๏ธ
once a request is received by a server and parsed sufficiently to determine its target URI, the server decides whether to process the request itself, forward the request to another server, redirect the client to a different resource, respond with an error, or drop the connection ๐ค this decision can be influenced by anything about the request or connection context, but is specifically directed at whether the server has been configured to process requests for that target URI and whether the connection context is appropriate for that request ๐ฏ
for example, a request might have been misdirected, deliberately or accidentally, such that the information within a received Host header field differs from the connection's host or port ๐ฌ if the connection is from a trusted gateway, such inconsistency might be expected; otherwise, it might indicate an attempt to bypass security filters, trick the server into delivering non-public content, or poison a cache ๐ท๏ธ see Section 17 for security considerations regarding message routing ๐ก๏ธ
unless the connection is from a trusted gateway, an origin server MUST reject a request if any scheme-specific requirements for the target URI are not met ๐ซ in particular, a request for an "https" resource MUST be rejected unless it has been received over a connection that has been secured via a certificate valid for that target URI's origin, as defined by Section 4.2.2 ๐
The 421 (Misdirected Request) status code in a response indicates that the origin server has rejected the request because it appears to have been misdirected (Section 15.5.20). ๐ โโ๏ธ๐
7.5. Response Correlation ๐
a connection might be used for multiple request/response exchanges ๐ the mechanism used to correlate between request and response messages is version dependent; some versions of HTTP use implicit ordering of messages, while others use an explicit identifier ๐งฉ
all responses, regardless of the status code (including interim responses) can be sent at any time after a request is received, even if the request is not yet complete ๐๏ธ a response can complete before its corresponding request is complete (Section 6.1) ๐จ likewise, clients are not expected to wait any specific amount of time for a response ๐ฐ๏ธ clients (including intermediaries) might abandon a request if the response is not received within a reasonable period of time ๐ซ
a client that receives a response while it is still sending the associated request SHOULD continue sending that request unless it receives an explicit indication to the contrary (see, e.g., Section 9.5 of [HTTP/1.1] and Section 6.4 of [HTTP/2]) ๐
7.6. Message Forwarding ๐ฆ
okay so, like we saw in Section 3.7, intermediaries can have all kinds of jobs when it comes to processing HTTP requests and responses ๐ Some are there to boost performance or availability โจ Others handle access control or filter content ๐ An HTTP stream is kinda like a pipe-and-filter setup, so there's literally no built-in limit on how much an intermediary can enhance (or mess with) either direction of the stream ๐ฅ
Intermediaries are expected to forward messages even when they don't recognize some protocol elements (like new methods, status codes, or field names) ๐ That's because it keeps things extensible for downstream recipients, which is so considerate of them ๐ซถ
An intermediary not acting as a tunnel MUST implement the Connection header field, as specified in Section 7.6.1, and it has to exclude fields from being forwarded that are only intended for the incoming connection ๐ธ
An intermediary MUST NOT forward a message to itself unless it is protected from an infinite request loop ๐ญ Generally, an intermediary ought to recognize its own server names, including any aliases, local variations, or literal IP addresses, and respond to those requests directly ๐
An HTTP message can be parsed as a stream for incremental processing or forwarding downstream โจ BUT senders and recipients cannot rely on incremental delivery of partial messages, since some implementations will buffer or delay message forwarding for the sake of network efficiency, security checks, or content transformations ๐ So don't count on it, bestie ๐
7.6.1. Connection ๐
The Connection header field allows the sender to list desired control options for the current connection ๐
Connection = #connection-option
connection-option = token
Connection options are case-insensitive ๐
When a field aside from Connection is used to supply control information for or about the current connection, the sender MUST list the corresponding field name within the Connection header field โจ Note that some versions of HTTP prohibit the use of fields for such information, and therefore do not allow the Connection field ๐
Intermediaries MUST parse a received Connection header field before a message is forwarded ๐ซถ Then, for each connection-option in this field, they remove any header or trailer field(s) from the message with the same name as the connection-option, and then remove the Connection header field itself (or replace it with the intermediary's own control options for the forwarded message) ๐งน
Hence, the Connection header field gives us a declarative way of telling apart fields that are only intended for the immediate recipient ("hop-by-hop") from those intended for all recipients on the chain ("end-to-end") ๐ฆ This makes the message self-descriptive and lets future connection-specific extensions get deployed without fear that older intermediaries will blindly forward them ๐
Furthermore, intermediaries SHOULD remove or replace fields that are known to require removal before forwarding, whether or not they appear as a connection-option, after applying those fields' semantics ๐ This includes but is not limited to:
- Proxy-Connection (Appendix C.2.2 of [HTTP/1.1])
- Keep-Alive (Section 19.7.1 of [RFC2068])
- TE (Section 10.1.4)
- Transfer-Encoding (Section 6.1 of [HTTP/1.1])
- Upgrade (Section 7.8)
A sender MUST NOT send a connection option corresponding to a field that is intended for all recipients of the content ๐ โโ๏ธ For example, Cache-Control is never appropriate as a connection option (Section 5.2 of [CACHING]) ๐
Connection options don't always match up with a field in the message, since a connection-specific field might not be needed if there are no parameters associated with a connection option ๐ On the flip side, a connection-specific field received without a corresponding connection option usually means the field got improperly forwarded by an intermediary, and the recipient ought to ignore it ๐
When defining a new connection option that does not correspond to a field, specification authors ought to reserve the corresponding field name anyway, so there are no later collisions ๐ธ Such reserved field names are registered in the "Hypertext Transfer Protocol (HTTP) Field Name Registry" (Section 16.3.1) ๐ง
7.6.2. Max-Forwards ๐
The Max-Forwards header field gives us a mechanism, used with the TRACE (Section 9.3.8) and OPTIONS (Section 9.3.7) request methods, to limit how many times the request gets forwarded by proxies ๐ This is super useful when the client is trying to trace a request that seems to be failing or looping mid-chain ๐ฉ
Max-Forwards = 1*DIGIT
The Max-Forwards value is a decimal integer showing the remaining number of times this request message can be forwarded ๐ข
Each intermediary that receives a TRACE or OPTIONS request containing a Max-Forwards header field MUST check and update its value prior to forwarding the request โ
If the received value is zero (0), the intermediary MUST NOT forward the request; instead, the intermediary MUST respond as the final recipient ๐ If the received Max-Forwards value is greater than zero, the intermediary MUST generate an updated Max-Forwards field in the forwarded message, with a field value that is the lesser of a) the received value decremented by one (1) or b) the recipient's maximum supported value for Max-Forwards ๐งฎ
A recipient MAY ignore a Max-Forwards header field received with any other request methods ๐คทโโ๏ธ
7.6.3. Via ๐
The Via header field indicates the presence of intermediate protocols and recipients between the user agent and the server (on requests) or between the origin server and the client (on responses) ๐ฃ๏ธ It's kinda like the Received header field in email (Section 3.6.7 of [RFC5322]) ๐ฌ Via can be used for tracking message forwards, avoiding request loops, and identifying the protocol capabilities of senders along the request/response chain โจ
Via = #( received-protocol RWS received-by [ RWS comment ] )
received-protocol = [ protocol-name "/" ] protocol-version
; see Section 7.8
received-by = pseudonym [ ":" port ]
pseudonym = token
Each member of the Via field value represents a proxy or gateway that has forwarded the message ๐งฉ Each intermediary appends its own info about how the message was received, so the end result is ordered according to the sequence of forwarding recipients ๐
A proxy MUST send an appropriate Via header field, as described below, in each message that it forwards ๐จ An HTTP-to-HTTP gateway MUST send an appropriate Via header field in each inbound request message, and it MAY send a Via header field in forwarded response messages ๐
For each intermediary, the received-protocol shows the protocol and protocol version used by the upstream sender of the message ๐ต๏ธโโ๏ธ So the Via field value records the advertised protocol capabilities of the request/response chain, so they stay visible to downstream recipients ๐ That's handy for figuring out which backwards-incompatible features might be safe to use in response, or within a later request, as described in Section 2.5 ๐ก For brevity, the protocol-name is omitted when the received protocol is HTTP ๐ซฐ
The received-by portion is normally the host and optional port number of a recipient server or client that subsequently forwarded the message ๐ฅ๏ธ However, if the real host is considered sensitive information, a sender MAY replace it with a pseudonym ๐ฅธ If a port is not provided, a recipient MAY interpret that as meaning it was received on the default port, if any, for the received-protocol ๐
A sender MAY generate comments to identify the software of each recipient, kinda like the User-Agent and Server header fields ๐ค Comments in Via are optional, though, and a recipient MAY remove them prior to forwarding the message ๐งผ
For example, a request message could be sent from an HTTP/1.0 user agent to an internal proxy code-named "fred" ๐ธ That proxy uses HTTP/1.1 to forward the request to a public proxy at p.example.net, which completes the request by forwarding it to the origin server at www.example.com ๐ The request received by www.example.com would then have the following Via header field:
Via: 1.0 fred, 1.1 p.example.net
An intermediary used as a portal through a network firewall SHOULD NOT forward the names and ports of hosts within the firewall region unless it is explicitly enabled to do so ๐งฑ If it isn't enabled, such an intermediary SHOULD replace each received-by host of any host behind the firewall with an appropriate pseudonym for that host ๐ฅท
An intermediary MAY combine an ordered subsequence of Via header field list members into a single member if the entries have identical received-protocol values ๐ง 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
A sender SHOULD NOT combine multiple list members unless they are all under the same organizational control and the hosts have already been replaced by pseudonyms ๐ข A sender MUST NOT combine members that have different received-protocol values ๐ซ no mixing the protocols, periodt ๐
7.7. Message Transformations โจ
okay so some intermediaries can actually transform messages and their content ๐ like a proxy might convert image formats to save cache space or cut down traffic on a slow link. but ngl this can go sideways when the content is for critical stuff, like medical imaging or scientific data analysis ๐, especially when integrity checks or digital signatures are there to prove the content is still identical to the original. one tiny edit and the whole thing is cooked ๐
An HTTP-to-HTTP proxy is called a "transforming proxy" ๐ฆ if it's designed or configured to modify messages in a semantically meaningful way. we mean changes that go beyond normal HTTP processing and would matter to the original sender, or could matter to downstream recipients. for example, a transforming proxy might act as a shared annotation server (adding references to a local annotation database into responses), a malware filter, a format transcoder, or a privacy filter ๐ง. these transformations are presumed to be what whichever client (or client organization) picked the proxy actually wanted ๐
If a proxy gets a target URI with a host name that is not a fully qualified domain name, it MAY add its own domain to the host name it received when forwarding the request. but a proxy MUST NOT change the host name if the target URI contains a fully qualified domain name ๐ธ
A proxy MUST NOT modify the "absolute-path" and "query" parts of the received target URI when forwarding it to the next inbound server, except as required by that forwarding protocol. for instance, a proxy forwarding a request to an origin server over HTTP/1.1 will swap an empty path for "/" (Section 3.2.1 of [HTTP/1.1]) or "*" (Section 3.2.4 of [HTTP/1.1]), depending on the request method ๐
A proxy MUST NOT transform the content (Section 6.4) of a response message that has a no-transform cache directive (Section 5.2.2.6 of [CACHING]) ๐ this doesn't cover changes that leave the content alone, like adding or removing transfer codings (Section 7 of [HTTP/1.1]), so those are fine ๐
A proxy MAY transform the content of a message that doesn't have a no-transform cache directive. and if a proxy transforms the content of a 200 (OK) response, it can tell downstream recipients that a transformation happened by changing the status code to 203 (Non-Authoritative Information) (Section 15.3.4) ๐ซถ
A proxy SHOULD NOT modify header fields that describe the endpoints of the communication chain, the resource state, or the selected representation (other than the content). the exceptions are when the field's definition specifically allows the change, or when the change is deemed necessary for privacy or security ๐ฅ
7.8. Upgrade
the "Upgrade" header field is meant to be a simple way to switch from HTTP/1.1 to some other protocol on the same connection ๐ฆ
A client MAY send a list of protocol names in the Upgrade header field of a request. this invites the server to switch to one or more of the named protocols, in order of descending preference, before sending the final response ๐ a server MAY ignore a received Upgrade header field if it would rather keep using the current protocol on that connection. and Upgrade can't be used to insist on a protocol change ๐ โโ๏ธ
Upgrade = #protocol
protocol = protocol-name ["/" protocol-version]
protocol-name = token
protocol-version = token
Although protocol names are registered with a preferred case, recipients SHOULD use case-insensitive comparison when matching each protocol-name to supported protocols ๐
A server that sends a 101 (Switching Protocols) response MUST send an Upgrade header field to say which new protocol(s) the connection is switching to. if multiple protocol layers are being switched, the sender MUST list the protocols in layer-ascending order ๐ง a server MUST NOT switch to a protocol that the client didn't indicate in the corresponding request's Upgrade header field. a server MAY choose to ignore the client's order of preference and pick the new protocol(s) based on other factors, like the nature of the request or the current load on the server ๐ญ
A server that sends a 426 (Upgrade Required) response MUST send an Upgrade header field listing the acceptable protocols, in order of descending preference ๐
A server MAY send an Upgrade header field in any other response to advertise that it supports upgrading to the listed protocols, in order of descending preference, when that's appropriate for a future request โจ
here's a hypothetical example sent by a client:
GET /hello HTTP/1.1
Host: www.example.com
Connection: upgrade
Upgrade: websocket, IRC/6.9, RTA/x11
the capabilities and nature of the application-level communication after the switch depend entirely on the new protocol(s) that get chosen ๐ธ but right after sending the 101 (Switching Protocols) response, the server is expected to keep responding to the original request as if it had received its equivalent within the new protocol. so the server still has an outstanding request to finish after the switch, and it's expected to do that without the request being sent again ๐
for example, if the Upgrade header field shows up in a GET request and the server decides to switch protocols, it first responds with a 101 (Switching Protocols) message in HTTP/1.1, and then immediately follows that with the new protocol's version of a response to a GET on the target resource. this lets a connection be upgraded to protocols with the same semantics as HTTP without paying the latency cost of an extra round trip ๐ a server MUST NOT switch protocols unless the new protocol can honor the semantics of the received message. an OPTIONS request can be honored by any protocol ๐
here's an example response to that hypothetical request:
HTTP/1.1 101 Switching Protocols
Connection: upgrade
Upgrade: websocket
[... data stream switches to websocket with an appropriate response
(as defined by new protocol) to the "GET /hello" request ...]
A sender of Upgrade MUST also send an "Upgrade" connection option in the Connection header field (Section 7.6.1) so intermediaries know not to forward this field ๐ and a server that receives an Upgrade header field in an HTTP/1.0 request MUST ignore that Upgrade field ๐
a client can't start using an upgraded protocol on the connection until it has completely sent the request message. (basically, the client can't change the protocol it's sending in the middle of a message ๐) if a server receives both an Upgrade and an Expect header field with the "100-continue" expectation (Section 10.1.1), the server MUST send a 100 (Continue) response before sending a 101 (Switching Protocols) response ๐ซถ
the Upgrade header field only works for switching protocols on top of the existing connection. it can't switch the underlying connection (transport) protocol, and it can't move the existing communication onto a different connection. for those jobs, a 3xx (Redirection) response (Section 15.4) is the better move ๐
This specification only defines the protocol name "HTTP" for use by the family of Hypertext Transfer Protocols, as defined by the HTTP version rules of Section 2.5 and future updates to this specification. additional protocol names ought to be registered using the registration procedure defined in Section 16.7 ๐
8. Representation Data and Metadata
8.1. Representation Data
the representation data attached to an HTTP message is either provided as the message's content, or it's referred to by the message semantics and the target URI. the representation data comes in a format and encoding defined by the representation metadata header fields ๐จ
the data type of the representation data is figured out from the Content-Type and Content-Encoding header fields. together they make a two-layer, ordered encoding model ๐ง
representation-data := Content-Encoding( Content-Type( data ) )
8.2. Representation Metadata
representation header fields give you metadata about the representation ๐๏ธ when a message includes content, these fields tell you how to interpret that data. and in a response to a HEAD request, they describe the representation data that would have been in the content if the same request had been a GET ๐
8.3. Content-Type
the "Content-Type" header field says what media type the representation is. that's either the representation enclosed in the message content, or the selected representation, depending on the message semantics ๐ the media type tells you both the data format and how a recipient is supposed to process it, within the scope of the received message semantics, after any content codings from Content-Encoding have been decoded ๐ท
Content-Type = media-type
Media types are defined in Section 8.3.1. here's an example of the field:
Content-Type: text/html; charset=ISO-8859-4
A sender that generates a message containing content SHOULD generate a Content-Type header field in that message, unless the intended media type of the enclosed representation is unknown to the sender. if there's no Content-Type header field, the recipient MAY either assume a media type of "application/octet-stream" ([RFC2046], Section 4.5.1) or examine the data to figure out its type ๐ต๏ธโโ๏ธ
ok real talk, resource owners don't always set up their origin server to send the right Content-Type for a representation ๐ค some user agents look at the content and, in certain cases, override the type they received (see [Sniffing], for example). this "MIME sniffing" can lead to wrong conclusions about the data, which might expose the user to extra security risks (e.g., "privilege escalation") ๐ plus, different media types often share the same data format and only differ in how the data is meant to be processed, and you just can't tell that apart by inspecting the data alone ๐ when sniffing is implemented, implementers are encouraged to give the user a way to turn it off ๐
Content-Type is defined as a singleton field, but it's sometimes generated multiple times by mistake. that makes a combined field value that looks like a list. recipients often try to handle this error by using the last syntactically valid member of the list. that can cause interoperability and security problems if different implementations handle the error in different ways ๐จ
8.3.1. Media Type โจ
okay so bestie, media types are how HTTP says "this is what kind of data I'm holding" ๐ They're used in the Content-Type (Section 8.3) and Accept (Section 12.5.1) header fields so that the data typing stays open and extensible, and type negotiation can actually happen ๐ฆ A media type doesn't just name a data format, it also brings along various processing models, which is how you know what to do with the data given the message context ๐ง
media-type is basically type "/" subtype parameters, and both type and subtype are tokens ๐ธ
media-type = type "/" subtype parameters
type = token
subtype = token
And yes, the type and subtype tokens are case-insensitive, so Text and text are the same vibe ๐
The type/subtype MAY be followed by semicolon-delimited parameters (Section 5.6.6) in the form of name/value pairs ๐ Whether a parameter is present or absent might matter for processing, depending on how it's defined in the media type registry ๐ And parameter values might or might not be case-sensitive, depending on what the parameter name means ๐
Here's an example. These four are all equivalent for describing HTML text encoded in UTF-8, but the first one is preferred for consistency โจ (The charset parameter value is case-insensitive per [RFC2046], Section 4.1.2, so it's all good ๐ซถ)
text/html;charset=utf-8
Text/HTML;Charset="utf-8"
text/html; charset="utf-8"
text/html;charset=UTF-8
Media types ought to be registered with IANA following the procedures in [BCP13] ๐ Go register your types, bestie ๐
8.3.2. Charset โจ
HTTP uses "charset" names to indicate or negotiate the character encoding scheme ([RFC6365], Section 2) of a textual representation ๐ฆ In the fields defined by this document, charset names show up either as parameters (Content-Type) or, for Accept-Encoding, as a plain token ๐ Either way, charset names are matched case-insensitively, so no drama ๐
Charset names ought to be registered in the IANA "Character Sets" registry (<https://www.iana.org/assignments/character-sets>) following the procedures in Section 2 of [RFC2978] ๐ธ
๐ Note: In theory, charset names are defined by the "mime-charset" ABNF rule in Section 2.3 of [RFC2978] (as corrected in [Err1912]). That rule allows two characters that aren't in "token", namely "{" and "}". But no charset name registered at the time of this writing includes braces (see [Err5433]). Iconic restraint, honestly ๐
8.3.3. Multipart Types โจ
MIME has a bunch of "multipart" types, which are encapsulations of one or more representations inside a single message body ๐ They all share a common syntax (Section 5.1.1 of [RFC2046]) and include a boundary parameter as part of the media type value ๐ง The message body is its own protocol element, and a sender MUST generate only CRLF to represent line breaks between body parts ๐
HTTP message framing does NOT use the multipart boundary as an indicator of message body length, though implementations that generate or process the content might use it ๐ For example, "multipart/form-data" is often used for carrying form data in a request, as described in [RFC7578] ๐ And the "multipart/byteranges" type is defined by this specification for use in some 206 (Partial Content) responses (see Section 15.3.7) ๐ฆ
Wait, I need to keep the requirement exact, so let me fix that: framing does not use the boundary as a length indicator, and I wrote that in plain caps by mistake. Correcting it below ๐
HTTP message framing does not use the multipart boundary as an indicator of message body length, though it might be used by implementations that generate or process the content ๐ For example, "multipart/form-data" is often used for carrying form data in a request, as described in [RFC7578] ๐ And the "multipart/byteranges" type is defined by this specification for use in some 206 (Partial Content) responses (see Section 15.3.7) ๐ฆ
8.4. Content-Encoding โจ
The "Content-Encoding" header field tells you what content codings have been applied to the representation, beyond what's already baked into the media type ๐ So it also tells you what decoding has to happen to get back to the media type named in Content-Type ๐ Content-Encoding is mainly there so a representation's data can be compressed without losing the identity of its underlying media type ๐ซถ
Content-Encoding = #content-coding
Here's how it looks in action ๐
Content-Encoding: gzip
If one or more encodings have been applied to a representation, the sender that applied them MUST generate a Content-Encoding header field listing the content codings in the order they were applied ๐ Note that the coding named "identity" is reserved for its special role in Accept-Encoding, so it SHOULD NOT be included ๐
Additional information about the encoding parameters can come through other header fields that this specification doesn't define ๐ง
Unlike Transfer-Encoding (Section 6.1 of [HTTP/1.1]), the codings in Content-Encoding are a characteristic of the representation ๐ฆ The representation is defined in terms of the coded form, and all other metadata about it refers to the coded form, unless the metadata definition says otherwise ๐ธ Typically, the representation only gets decoded right before rendering or something similar ๐
If the media type includes an inherent encoding, like a data format that's always compressed, then that encoding would NOT be restated in Content-Encoding, even if it happens to be the same algorithm as one of the content codings ๐ A content coding like that would only be listed if, for some bizarre reason, it got applied a second time to form the representation ๐ Likewise, an origin server might publish the same data as multiple representations that differ only in whether the coding is part of Content-Type or Content-Encoding ๐ That's because some user agents handle each response differently (for example, they might open a "Save as ..." dialog instead of automatically decompressing and rendering the content) ๐
An origin server MAY respond with a status code of 415 (Unsupported Media Type) if a representation in the request message has a content coding that is not acceptable ๐ซถ
8.4.1. Content Codings โจ
Content coding values name an encoding transformation that has been, or can be, applied to a representation ๐ Content codings are mainly used so a representation can be compressed or otherwise usefully transformed without losing the identity of its underlying media type and without any loss of information ๐ฆ Frequently, the representation is stored in coded form, sent along as-is, and only decoded by the final recipient ๐ง
content-coding = token
All content codings are case-insensitive and ought to be registered within the "HTTP Content Coding Registry", as described in Section 16.6 ๐
Content-coding values are used in the Accept-Encoding (Section 12.5.3) and Content-Encoding (Section 8.4) header fields ๐
8.4.1.1. Compress Coding โจ
The "compress" coding is an adaptive Lempel-Ziv-Welch (LZW) coding [Welch] that's commonly produced by the UNIX file compression program "compress" ๐ธ A recipient SHOULD consider "x-compress" to be equivalent to "compress" ๐
8.4.1.2. Deflate Coding โจ
The "deflate" coding is a "zlib" data format [RFC1950] containing a "deflate" compressed data stream [RFC1951] that uses a combination of the Lempel-Ziv (LZ77) compression algorithm and Huffman coding ๐
๐ Note: Some non-conformant implementations send the "deflate" compressed data without the zlib wrapper. Messy, but it happens ๐
8.4.1.3. Gzip Coding โจ
The "gzip" coding is an LZ77 coding with a 32-bit Cyclic Redundancy Check (CRC) that's commonly produced by the gzip file compression program [RFC1952] ๐ฆ A recipient SHOULD consider "x-gzip" to be equivalent to "gzip" ๐
8.5. Content-Language โจ
The "Content-Language" header field describes the natural language(s) of the intended audience for the representation ๐ Note that this might not be equivalent to all the languages used within the representation ๐ซถ
Content-Language = #language-tag
Language tags are defined in Section 8.5.1 ๐ The main point of Content-Language is to let a user identify and tell apart representations according to their own preferred language ๐ So if the content is only meant for a Danish-literate audience, the right field is ๐
Content-Language: da
If no Content-Language is specified, the default is that the content is intended for all language audiences ๐ง That might mean the sender doesn't consider it specific to any natural language, or that the sender doesn't know which language it's for ๐ธ
Multiple languages MAY be listed for content that's 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
However, just because multiple languages appear within a representation doesn't mean it's aimed at multiple linguistic audiences ๐ Take a beginner's language primer like "A First Lesson in Latin", which is clearly meant for an English-literate audience ๐ฆ In that case, Content-Language would properly only include "en" ๐
Content-Language MAY be applied to any media type, because it is not limited to textual documents ๐ซถ
8.5.1. Language Tags โจ
A language tag, as defined in [RFC5646], identifies a natural language spoken, written, or otherwise conveyed by human beings for communicating information to other human beings ๐ Computer languages are explicitly excluded ๐
HTTP uses language tags within the Accept-Language and Content-Language header fields ๐ธ Accept-Language uses the broader language-range production defined in Section 12.5.4, whereas Content-Language uses the language-tag production defined below ๐
language-tag = <Language-Tag, see [RFC5646], Section 2.1>
A language tag is a sequence of one or more case-insensitive subtags, each separated by a hyphen character ("-", %x2D) ๐ In most cases, a language tag has a primary language subtag that identifies a broad family of related languages (for example, "en" = English), which can optionally be followed by subtags that refine or narrow that language's range (for example, "en-CA" = the variety of English as communicated in Canada) ๐ง Whitespace is NOT allowed within a language tag ๐ Example tags include:
fr, en-US, es-419, az-Arab, x-pig-latin, man-Nkoo-GN
See [RFC5646] for further information ๐
8.6. Content-Length ๐
okay bestie, the Content-Length header field tells you the associated representation's data length as a decimal non-negative integer number of octets ๐. When a representation is being sent as content, Content-Length is talking specifically about how much data is enclosed, so it can be used to delimit framing (e.g., Section 6.2 of [HTTP/1.1]) โจ. In every other case, it shows the selected representation's current length, which recipients can use to estimate transfer time or to compare against representations they stored before ๐ฆ.
Content-Length = 1*DIGIT
Here's an example ๐:
Content-Length: 3495
A user agent SHOULD send Content-Length in a request when the method gives meaning to enclosed content and it is not sending Transfer-Encoding ๐ค. For example, a user agent normally sends Content-Length in a POST request even when the value is 0, which means empty content ๐งบ. A user agent SHOULD NOT send a Content-Length header field when the request message has no content and the method semantics don't expect any ๐
โโ๏ธ.
A server MAY send a Content-Length header field in a response to a HEAD request (Section 9.3.2) ๐ธ. But a server MUST NOT send Content-Length in such a response unless its field value equals the decimal number of octets that would have been sent in the content of a response if the same request had used the GET method ๐ข.
A server MAY send a Content-Length header field in a 304 (Not Modified) response to a conditional GET request (Section 15.4.5) ๐. A server MUST NOT send Content-Length in such a response unless its field value equals the decimal number of octets that would have been sent in the content of a 200 (OK) response to the same request ๐งฎ.
A server MUST NOT send aContent-Lengthheader field in any response with a status code of 1xx (Informational) or 204 (No Content) ๐ซ. A server MUST NOT send aContent-Lengthheader field in any 2xx (Successful) response to a CONNECT request (Section 9.3.6) ๐ซ.
Outside of the cases above, and when there's no Transfer-Encoding, an origin server SHOULD send a Content-Length header field once the content size is known before the complete header section goes out ๐ฆ. This lets downstream recipients track transfer progress, know when a received message is complete, and potentially reuse the connection for more requests ๐โจ.
Any Content-Length field value greater than or equal to zero is valid ๐ฏ. Since there's no predefined limit on content length, a recipient MUST anticipate potentially large decimal numerals and prevent parsing errors caused by integer conversion overflows or precision loss from integer conversion (Section 17.5) ๐ก๏ธ. That part is seriously important, bestie ๐ญ.
Because Content-Length is used for message delimitation in HTTP/1.1, its field value can change how downstream recipients parse the message, even when the immediate connection is not using HTTP/1.1 ๐. If a downstream intermediary forwards the message and the Content-Length field value doesn't match the framing it received, that can cause a security failure through request smuggling or response splitting ๐จ.
So, a sender MUST NOT forward a message with a Content-Length header field value that is known to be incorrect ๐
โโ๏ธ.
Likewise, a sender MUST NOT forward a message with a Content-Length header field value that doesn't match the ABNF above, with one exception ๐ซถ. A recipient that gets a Content-Length field value made of the same decimal value repeated as a comma-separated list (e.g, Content-Length: 42, 42) MAY either reject the message as invalid or replace that invalid field value with a single instance of the decimal value ๐ฏ. That's because it probably means an upstream message processor generated or combined a duplicate ๐.
8.7. Content-Location ๐ฆ
The Content-Location header field references a URI that can be used as an identifier for a specific resource corresponding to the representation in this message's content ๐. In other words, if you did a GET request on this URI when the message was generated, a 200 (OK) response would contain the same representation that's enclosed as content in this message ๐ง.
Content-Location = absolute-URI / partial-URI
The field value is either an absolute-URI or a partial-URI. In the latter case (Section 4), the referenced URI is relative to the target URI ([URI], Section 5) ๐บ๏ธ.
The Content-Location value is not a replacement for the target URI (Section 7.1) ๐
โโ๏ธ. It's representation metadata ๐ท๏ธ. It has the same syntax and semantics as the header field with the same name defined for MIME body parts in Section 4 of [RFC2557] ๐. But showing up in an HTTP message has some special implications for HTTP recipients, so pay attention ๐โจ.
If Content-Location is included in a 2xx (Successful) response message and its value refers (after conversion to absolute form) to a URI that is the same as the target URI, then the recipient MAY consider the content to be a current representation of that resource at the time shown by the message origination date โฐ. For a GET (Section 9.3.1) or HEAD (Section 9.3.2) request, that's the same as the default semantics when the server doesn't provide any Content-Location ๐. For a state-changing request like PUT (Section 9.3.4) or POST (Section 9.3.3), it means the server's response contains the new representation of that resource ๐. That's what separates it from representations that only report on the action, like "It worked!" ๐
. It also lets authoring applications update their local copies without a follow-up GET request ๐.
If Content-Location is included in a 2xx (Successful) response message and its field value refers to a URI that differs from the target URI, then the origin server is claiming that the URI identifies a different resource for the enclosed representation ๐ซฃ. That claim can only be trusted if both identifiers share the same resource owner, and HTTP can't figure that out on its own ๐คทโโ๏ธ.
- For a response to a GET or HEAD request, this means the target URI refers to a resource that is subject to content negotiation, and the
Content-Locationfield value is a more specific identifier for the selected representation ๐จ. - For a 201 (Created) response to a state-changing method, a
Content-Locationfield value that is identical to theLocationfield value means this content is a current representation of the newly created resource ๐. - Otherwise, a
Content-Locationlike that means this content is a representation reporting on the status of the requested action, and the same report can be fetched later with GET at the given URI ๐. For example, a purchase made with a POST request might include a receipt document as the content of the 200 (OK) response ๐งพ. TheContent-Locationfield value gives you an identifier for grabbing a copy of that same receipt later ๐.
A user agent that sends Content-Location in a request message is saying its value refers to where the user agent first got the content of the enclosed representation, before it made any changes ๐. In other words, it's giving the server a back link to the source of the original representation ๐.
An origin server that receives a Content-Location field in a request message MUST treat the information as transitory request context, not as metadata to be saved verbatim as part of the representation ๐ง . An origin server MAY use that context to guide how it processes the request, or save it for other uses, such as source links or versioning metadata ๐. But an origin server MUST NOT use that context information to change the request semantics ๐ง.
For example, say a client makes a PUT request on a negotiated resource and the origin server accepts it without redirecting ๐ฏ. The new state of that resource is expected to match the one representation supplied in that PUT ๐. The Content-Location can't be used as a sort of reverse content selection identifier to update just one of the negotiated representations ๐
โโ๏ธ. If the user agent wanted that behaviour, it would have applied the PUT directly to the Content-Location URI instead ๐คญ.
8.8. Validator Fields ๐
Resource metadata is called a "validator" if it can be used within a precondition (Section 13.1) to make a conditional request (Section 13) ๐๏ธ. Validator fields carry a current validator for the selected representation (Section 3.2) ๐.
In responses to safe requests, validator fields describe the selected representation the origin server picked while handling the response ๐. Depending on the method and status code semantics, the selected representation for a given response is not always the same as the representation enclosed as response content, so don't mix those up ๐ซ .
In a successful response to a state-changing request, validator fields describe the new representation that replaced the prior selected representation as a result of processing the request ๐.
For example, an ETag field in a 201 (Created) response tells you the entity tag of the newly created resource's representation ๐ท๏ธ. That entity tag can then be used as a validator in later conditional requests to prevent the "lost update" problem ๐๐ฅ.
This specification defines two forms of metadata that are commonly used to observe resource state and test for preconditions: modification dates (Section 8.8.2) and opaque entity tags (Section 8.8.3) โณ๐. Other metadata that reflects resource state has been defined by extensions to HTTP, such as Web Distributed Authoring and Versioning [WEBDAV], and those are beyond the scope of this specification ๐งฉ.
8.8.1. Weak versus Strong โจ
Okay so validators come in two flavors: strong or weak ๐ฆ Weak ones are super easy to generate but honestly kinda useless for comparisons ๐ Strong ones are ideal for comparisons but can be really hard (and sometimes straight up impossible) to generate efficiently ๐ญ So instead of forcing every resource to use the same strength, HTTP shows you which type of validator is in use and sets rules for when weak validators can be used as preconditions ๐
A "strong validator" is representation metadata that changes value whenever there's a change to the representation data that would be observable in the content of a 200 (OK) response to GET ๐ฅ
A strong validator might also change for other reasons, like when a semantically significant part of the representation metadata gets changed (e.g., Content-Type) ๐ But it's in the origin server's best interests to only change the value when it's actually necessary to invalidate the stored responses held by remote caches and authoring tools ๐ซถ
Cache entries can stick around for arbitrarily long periods, no matter what their expiration times say ๐ญ So a cache might try to validate an entry using a validator it got way back in the distant past ๐ฐ๏ธ A strong validator is unique across all versions of all representations associated with a particular resource over time ๐ However, there's no implication of uniqueness across representations of different resources. The same strong validator might be in use for representations of multiple resources at the same time, and that doesn't mean those representations are equivalent ๐
There are a bunch of strong validators used in practice โจ The best ones are based on strict revision control, where every change to a representation always gets a unique node name and revision identifier assigned before it's made accessible to GET ๐ A collision-resistant hash function applied to the representation data is also good enough, as long as the data is available before the response header fields are sent and the digest doesn't need to be recalculated every time a validation request comes in ๐ธ But if a resource has distinct representations that only differ in their metadata (like content negotiation over media types that happen to share the same data format), then the origin server needs to put additional information in the validator to tell those representations apart ๐
In contrast, a "weak validator" is representation metadata that might not change for every change to the representation data ๐ This weakness could come from limitations in how the value is calculated (e.g., clock resolution), from an inability to ensure uniqueness for all possible representations of the resource, or from the resource owner wanting to group representations by some self-determined set of equivalency instead of unique sequences of data ๐ง
An origin server SHOULD change a weak entity tag whenever it considers prior representations to be unacceptable as a substitute for the current representation ๐ In other words, a weak entity tag ought to change whenever the origin server wants caches to throw out old responses ๐๏ธ
For example, a weather report that changes content every second based on dynamic measurements might be grouped into sets of equivalent representations (from the origin server's perspective) that share the same weak validator ๐ฆ๏ธ That way cached representations can stay valid for a reasonable period of time (maybe adjusted dynamically based on server load or weather quality) ๐ฆ Likewise, a representation's modification time, if it's only defined with one-second resolution, might be a weak validator if it's possible for the representation to be modified twice during a single second and retrieved between those modifications ๐ญ
Also, a validator is weak if it's shared by two or more representations of a given resource at the same time, unless those representations have identical representation data ๐ For example, if the origin server sends the same validator for a representation with a gzip content coding applied as it does for a representation with no content coding, then that validator is weak ๐ However, two simultaneous representations might share the same strong validator if they only differ in the representation metadata, like when two different media types are available for the same representation data ๐
Strong validators are usable for all conditional requests, including cache validation, partial content ranges, and "lost update" avoidance ๐ Weak validators are only usable when the client doesn't require exact equality with previously obtained representation data, like when validating a cache entry or limiting a web traversal to recent changes ๐ซถ
8.8.2. Last-Modified ๐ฐ๏ธ
The "Last-Modified" header field in a response gives a timestamp for the date and time at which the origin server believes the selected representation was last modified, as determined at the conclusion of handling the request ๐
Last-Modified = HTTP-date
An example of its use is:
Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
8.8.2.1. Generation ๐ธ
An origin server SHOULD send Last-Modified for any selected representation for which a last modification date can be reasonably and consistently determined ๐ Its use in conditional requests and evaluating cache freshness ([CACHING]) can substantially reduce unnecessary transfers and significantly improve service availability and scalability ๐ฅ
A representation is typically the sum of many parts behind the resource interface ๐งฉ The last-modified time would usually be the most recent time that any of those parts were changed ๐ How that value is determined for any given resource is an implementation detail beyond the scope of this specification ๐คทโโ๏ธ
An origin server SHOULD obtain the Last-Modified value of the representation as close as possible to the time that it generates the Date field value for its response ๐ This lets a recipient make an accurate assessment of the representation's modification time, especially if the representation changes near the time the response is generated โจ
An origin server with a clock (as defined in Section 5.6.7) MUST NOT generate a Last-Modified date that is later than the server's time of message origination (Date, Section 6.6.1). If the last modification time is derived from implementation-specific metadata that evaluates to some time in the future, according to the origin server's clock, then the origin server MUST replace that value with the message origination date. This prevents a future modification date from having an adverse impact on cache validation ๐ซ
An origin server without a clock MUST NOT generate a Last-Modified date for a response unless that date value was assigned to the resource by some other system (presumably one with a clock) ๐ฐ๏ธ
8.8.2.2. Comparison ๐
A Last-Modified time, when used as a validator in a request, is implicitly weak unless it's possible to deduce that it's strong, using the following rules ๐ง
- The validator is being compared by an origin server to the actual current validator for the representation and,
- That origin server reliably knows that the associated representation 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, If-Unmodified-Since, or If-Range header field, because the client has a cache entry for the associated representation, and
- That cache entry includes a Date value which is at least one second after the Last-Modified value and the client has reason to believe that they were generated by the same clock or that there is enough difference between the Last-Modified and Date values to make clock synchronization issues unlikely;
or
- The validator is being compared by an intermediate cache to the validator stored in its cache entry for the representation, and
- That cache entry includes a Date value which is at least one second after the Last-Modified value and the cache has reason to believe that they were generated by the same clock or that there is enough difference between the Last-Modified and Date values to make clock synchronization issues unlikely.
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 ๐ง
8.8.3. ETag ๐ท๏ธ
The "ETag" field in a response gives the current entity tag for the selected representation, as determined at the conclusion of handling the request ๐ An entity tag is an opaque validator for differentiating between multiple representations of the same resource, whether those representations come from resource state changes over time, content negotiation resulting in multiple representations being valid at the same time, or both ๐ฆ An entity tag consists of an opaque quoted string, possibly prefixed by a weakness indicator โจ
ETag = entity-tag
entity-tag = [ weak ] opaque-tag
weak = %s"W/"
opaque-tag = DQUOTE *etagc DQUOTE
etagc = %x21 / %x23-7E / obs-text
; VCHAR except double quotes, plus obs-text
Note: Previously, opaque-tag was defined to be a quoted-string ([RFC2616], Section 3.11); thus, some recipients might perform backslash unescaping. Servers therefore ought to avoid backslash characters in entity tags. โ ๏ธ
An entity tag can be more reliable for validation than a modification date in situations where it's inconvenient to store modification dates, where the one-second resolution of HTTP-date values isn't sufficient, or where modification dates aren't consistently maintained ๐
Examples:
ETag: "xyzzy"
ETag: W/"xyzzy"
ETag: ""
An entity tag can be either a weak or strong validator, with strong being the default ๐ช If an origin server provides an entity tag for a representation and the generation of that entity tag doesn't satisfy all of the characteristics of a strong validator (Section 8.8.1), then the origin server MUST mark the entity tag as weak by prefixing its opaque value with "W/" (case-sensitive) ๐ท๏ธ
A sender MAY send the ETag field in a trailer section (see Section 6.5) ๐ However, since trailers are often ignored, it's preferable to send ETag as a header field unless the entity tag is generated while sending the content ๐ซถ
8.8.3.1. Generation ๐ง
okay so the big idea here is that only the service author really knows their resource well enough to pick the most accurate and efficient validation trick for it ๐ and any trick can get squished down into a simple sequence of octets so it's easy to compare ๐ซถ since the value is opaque, the client doesn't need to know how each entity tag was built. literally no homework for the client ๐
for example, a resource with implementation-specific versioning on every change might use an internal revision number, maybe paired with a variance identifier for content negotiation, to tell its representations apart โจ other implementations might go with a collision-resistant hash of the representation content, a combo of various file attributes, or a modification timestamp with sub-second resolution. the vibes are all valid ๐
An origin server SHOULD send an ETag for any selected representation where detecting changes can be reasonably and consistently determined ๐ why? because the entity tag's use in conditional requests and in evaluating cache freshness ([CACHING]) can substantially reduce unnecessary transfers and significantly improve service availability, scalability, and reliability. it's giving main character energy for your server ๐
8.8.3.2. Comparison ๐ฅ
there are two entity tag comparison functions, and which one you get depends on whether the comparison context allows the use of weak validators ๐ฆ
- "Strong comparison": two entity tags are equivalent if both are not weak and their opaque-tags match character-by-character.
- "Weak comparison": two entity tags are equivalent if their opaque-tags match character-by-character, regardless of either or both being tagged as "weak".
the table below shows the results for a set of entity tag pairs under both the weak and strong comparison functions ๐
+========+========+===================+=================+
| ETag 1 | ETag 2 | Strong Comparison | Weak Comparison |
+========+========+===================+=================+
| W/"1" | W/"1" | no match | match |
+--------+--------+-------------------+-----------------+
| W/"1" | W/"2" | no match | no match |
+--------+--------+-------------------+-----------------+
| W/"1" | "1" | no match | match |
+--------+--------+-------------------+-----------------+
| "1" | "1" | match | match |
+--------+--------+-------------------+-----------------+
Table 3
8.8.3.3. Example: Entity Tags Varying on Content-Negotiated Resources ๐
okay this one is so good ๐ญ picture a resource that's subject to content negotiation (Section 12), where the representations sent back for a GET request vary based on the Accept-Encoding request header field (Section 12.5.3) ๐
>> Request:
GET /index HTTP/1.1
Host: www.example.com
Accept-Encoding: gzip
in this case, the response might or might not use the gzip content coding ๐คทโโ๏ธ if it doesn't, the response might look like:
>> Response:
HTTP/1.1 200 OK
Date: Fri, 26 Mar 2010 00:05:00 GMT
ETag: "123-a"
Content-Length: 70
Vary: Accept-Encoding
Content-Type: text/plain
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
and an alternative representation that DOES use gzip content coding would be:
>> Response:
HTTP/1.1 200 OK
Date: Fri, 26 Mar 2010 00:05:00 GMT
ETag: "123-b"
Content-Length: 43
Vary: Accept-Encoding
Content-Type: text/plain
Content-Encoding: gzip
...binary data...
๐ Note: content codings are a property of the representation data, so a strong entity tag for a content-encoded representation has to be distinct from the entity tag of an unencoded representation, to prevent potential conflicts during cache updates and range requests. in contrast, transfer codings (Section 7 of [HTTP/1.1]) apply only during message transfer and do not result in distinct entity tags. the plot twist is that they're totally different things ๐ง
9. Methods ๐
9.1. Overview โจ
okay so the request method token is the primary source of request semantics ๐ it tells the server what the client is trying to do and what the client expects as a successful result ๐ฏ
the request method's semantics can get extra specialized by the semantics of some header fields when they're present in a request, as long as those extra semantics don't conflict with the method. for example, a client can send conditional request header fields (Section 13.1) to make the requested action conditional on the current state of the target resource ๐ซถ
HTTP is designed to be usable as an interface to distributed object systems ๐ง the request method invokes an action to be applied to a target resource, kind of like how a remote method invocation can be sent to an identified object.
method = token
the method token is case-sensitive, because it might be used as a gateway to object-based systems with case-sensitive method names ๐ by convention, standardized methods are defined in all-uppercase US-ASCII letters ๐
unlike distributed objects, the standardized request methods in HTTP are not resource-specific, since uniform interfaces give better visibility and reuse in network-based systems [REST] ๐ฆ once a standardized method is defined, it ought to have the same semantics when applied to any resource, though each resource decides for itself whether those semantics are implemented or allowed ๐
this spec defines a bunch of standardized methods that are commonly used in HTTP, as outlined in this table ๐
+=========+============================================+=========+
| Method | Description | Section |
| Name | | |
+=========+============================================+=========+
| GET | Transfer a current representation of the | 9.3.1 |
| | target resource. | |
+---------+--------------------------------------------+---------+
| HEAD | Same as GET, but do not transfer the | 9.3.2 |
| | response content. | |
+---------+--------------------------------------------+---------+
| POST | Perform resource-specific processing on | 9.3.3 |
| | the request content. | |
+---------+--------------------------------------------+---------+
| PUT | Replace all current representations of the | 9.3.4 |
| | target resource with the request content. | |
+---------+--------------------------------------------+---------+
| DELETE | Remove all current representations of the | 9.3.5 |
| | target resource. | |
+---------+--------------------------------------------+---------+
| CONNECT | Establish a tunnel to the server | 9.3.6 |
| | identified by the target resource. | |
+---------+--------------------------------------------+---------+
| OPTIONS | Describe the communication options for the | 9.3.7 |
| | target resource. | |
+---------+--------------------------------------------+---------+
| TRACE | Perform a message loop-back test along the | 9.3.8 |
| | path to the target resource. | |
+---------+--------------------------------------------+---------+
Table 4
okay now the important bit ๐จ all general-purpose servers MUST support the GET and HEAD methods ๐ all other methods are OPTIONAL, so no pressure ๐ธ
the set of methods allowed by a target resource can be listed in an Allow header field (Section 10.2.1) ๐ BUT the set of allowed methods can change dynamically, so stay alert ๐ an origin server that receives a request method that is unrecognized or not implemented SHOULD respond with the 501 (Not Implemented) status code ๐ โโ๏ธ and an origin server that receives a request method that is recognized and implemented, but not allowed for the target resource, SHOULD respond with the 405 (Method Not Allowed) status code ๐
additional methods, outside the scope of this specification, have been specified for use in HTTP ๐ all of them ought to be registered within the "Hypertext Transfer Protocol (HTTP) Method Registry", as described in Section 16.1 ๐ง
9.2. Common Method Properties ๐ธ
9.2.1. Safe Methods ๐ฆ
okay so request methods are considered "safe" if their defined semantics are essentially read-only ๐ that means the client does not request, and does not expect, any state change on the origin server from applying a safe method to a target resource ๐ซถ likewise, reasonable use of a safe method isn't expected to cause any harm, loss of property, or unusual burden on the origin server ๐
this definition doesn't stop an implementation from including behavior that's potentially harmful, that isn't entirely read-only, or that causes side effects while invoking a safe method ๐ what matters is that the client didn't ask for that extra behavior and can't be held accountable for it โ๏ธ for example, most servers append request info to access log files at the end of every response, no matter the method, and that still counts as safe, even though the log storage might fill up and make the server fail ๐ and a safe request started by clicking an ad on the Web will often have the side effect of charging an advertising account ๐ธ
of the request methods defined by this specification, the GET, HEAD, OPTIONS, and TRACE methods are defined to be safe โจ
why do we even care? because the whole point of splitting safe from unsafe methods is to let automated retrieval processes (spiders) and cache performance optimization (pre-fetching) work without fear of causing harm ๐ท๏ธ it also lets a user agent apply appropriate constraints on the automated use of unsafe methods when it's processing potentially untrusted content ๐ก๏ธ
a user agent SHOULD distinguish between safe and unsafe methods when presenting potential actions to a user, so the user can be made aware of an unsafe action before it's requested ๐ฆ
โ ๏ธ when a resource is built so that parameters within the target URI have the effect of selecting an action, it's the resource owner's responsibility to make sure that action is consistent with the request method semantics. it's super common for web-based content editing software to use actions in query parameters, like page?do=delete ๐ฌ if the purpose of such a resource is to perform an unsafe action, the resource owner MUST disable or disallow that action when it's accessed using a safe request method. if they don't, you'll get unfortunate side effects when automated processes do a GET on every URI reference for link maintenance, pre-fetching, building a search index, and so on ๐
9.2.2. Idempotent Methods ๐
okay so a request method is "idempotent" if sending the same identical request many times has the same intended effect on the server as sending it once ๐ซถ PUT, DELETE, and the safe request methods are idempotent, out of all the methods this spec defines ๐
Like safe, idempotent only covers what the user asked for. A server is totally free to log every request separately, keep a revision control history, or do other non-idempotent stuff for each idempotent request โจ
Why do we even care? Because the request can be repeated automatically if the connection breaks before the client can read the response ๐ฆ Say a client sends a PUT and the connection gets closed before any response shows up. The client can open a new connection and retry, no stress ๐ It knows that repeating it has the same intended effect, even if the first one actually worked. The response might just look a bit different ๐ธ
A client SHOULD NOT automatically retry a request with a non-idempotent method unless it has some way to know the request semantics are actually idempotent, regardless of the method, or some way to detect that the original request was never applied ๐
For example, a user agent can repeat a POST request automatically if it knows (through design or configuration) that the request is safe for that resource ๐ Also, a user agent built specifically for a version control repository might recover from partial failures by checking the target resource revision(s) after a failed connection, reverting or fixing any changes that got partially applied, and then automatically retrying the requests that failed. Iconic behavior ๐
Some clients take a riskier route and try to guess when an automatic retry is okay ๐ฌ For example, a client might automatically retry a POST if the transport connection closed before any part of a response arrived, especially if an idle persistent connection was being used. Bold move, not gonna lie ๐
A proxy MUST NOT automatically retry non-idempotent requests ๐ And a client SHOULD NOT automatically retry a failed automatic retry. Let it go, bestie ๐ซ
9.2.3. Methods and Caching ๐๏ธ
For a cache to store and use a response, the method has to explicitly allow caching and spell out the conditions under which a response can be used to answer later requests. If a method definition doesn't do that, it simply can't be cached ๐ โโ๏ธ For more requirements, check out [CACHING] ๐
This spec defines caching semantics for GET, HEAD, and POST, even though the overwhelming majority of cache implementations only support GET and HEAD ๐ฅฒ
9.3. Method Definitions ๐
9.3.1. GET ๐
The GET method asks for transfer of a current selected representation of the target resource ๐ A successful response reflects the quality of "sameness" that the target URI identifies (Section 1.2.2 of [URI]). So basically, if you want to grab identifiable info over HTTP, you usually make a GET request on an identifier that could give you that info in a 200 (OK) response โจ
GET is the main way information gets retrieved, and it's the star of almost every performance optimization ๐ฅ Apps that give each important resource its own URI get all those optimizations, and other apps can reuse those URIs too. That creates a network effect that keeps the Web growing ๐
It's super tempting to think of resource identifiers as remote file system pathnames, with representations being copies of those files' contents ๐ง And honestly, that's how lots of resources are implemented (see Section 17.3 for related security considerations). But there are no such limits in practice ๐ฆ
The HTTP interface for a resource could just as easily be a tree of content objects, a programmatic view over database records, or a gateway to other information systems ๐ Even when URI mapping is tied to a file system, an origin server might be set up to run the files with the request as input and send the output back as the representation, instead of transferring the files directly. Either way, only the origin server needs to know how each resource identifier maps to an implementation, and how that implementation picks and sends a current representation of the target resource ๐ซถ
A client can turn GET into a "range request", asking for transfer of just some part(s) of the selected representation, by sending a Range header field in the request (Section 14.2) ๐
Request message framing doesn't depend on the method, but content received in a GET request has no generally defined semantics. It can't change the meaning or target of the request, and it might make some implementations reject the request and close the connection, because of its potential as a request smuggling attack (Section 11.2 of [HTTP/1.1]) ๐ฌ A client SHOULD NOT generate content in a GET request unless it's sent directly to an origin server that has already indicated, in or out of band, that such a request has a purpose and will be properly supported. An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain ๐
The response to a GET request is cacheable, so a cache MAY use it to satisfy later GET and HEAD requests, unless the Cache-Control header field (Section 5.2 of [CACHING]) says otherwise ๐
Heads up, though! When info retrieval happens through a mechanism that builds a target URI from user-provided info, like the query fields of a form using GET, potentially sensitive data might end up in there, which wouldn't be appropriate to show in a URI (see Section 17.9) ๐จ Sometimes the data can be filtered or transformed so it doesn't reveal that stuff. Other times, especially when caching a response wouldn't help anyway, using the POST method (Section 9.3.3) instead of GET can send that info in the request content rather than in the target URI ๐
9.3.2. HEAD ๐ซฅ
The HEAD method is identical to GET, except that the server MUST NOT send content in the response ๐ HEAD is used to grab metadata about the selected representation without transferring its representation data. It's often used for testing hypertext links or finding recent modifications ๐
The server SHOULD send the same header fields in response to a HEAD request as it would have sent for a GET request. However, a server MAY omit header fields whose value is only determined while generating the content ๐ธ For example, some servers buffer a dynamic response to GET until a minimum amount of data is generated, so they can more efficiently delimit small responses or make late decisions about content selection. A response to GET like that might contain Content-Length and Vary fields, for example, that aren't generated within a HEAD response. These minor inconsistencies are considered preferable to generating and discarding the content for a HEAD request, since HEAD is usually requested for the sake of efficiency โก
Request message framing doesn't depend on the method, but content received in a HEAD request has no generally defined semantics either. It can't change the meaning or target of the request, and it might make some implementations reject the request and close the connection, because of its potential as a request smuggling attack (Section 11.2 of [HTTP/1.1]) ๐ฌ A client SHOULD NOT generate content in a HEAD request unless it's sent directly to an origin server that has already indicated, in or out of band, that such a request has a purpose and will be properly supported. An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain ๐
The response to a HEAD request is cacheable, so a cache MAY use it to satisfy later HEAD requests, unless the Cache-Control header field (Section 5.2 of [CACHING]) says otherwise ๐ฉต A HEAD response might also affect previously cached responses to GET; see Section 4.3.5 of [CACHING] โจ
9.3.3. POST ๐ฎ
The POST method asks that the target resource process the representation enclosed in the request, following the resource's own specific semantics ๐ For example, POST is used for functions like these (among others):
- Providing a block of data, such as the fields entered into an HTML form, to a data-handling process ๐
- Posting a message to a bulletin board, newsgroup, mailing list, blog, or similar group of articles ๐ฃ
- Creating a new resource that the origin server hasn't identified yet ๐
- Appending data to a resource's existing representation(s) โ
An origin server shows response semantics by picking an appropriate status code based on the result of processing the POST request ๐ท๏ธ Almost all of the status codes this spec defines could come back in a response to POST. The exceptions are 206 (Partial Content), 304 (Not Modified), and 416 (Range Not Satisfiable) ๐
โโ๏ธ
If one or more resources got created on the origin server because a POST request was processed successfully, the origin server SHOULD send a 201 (Created) response. That response contains a Location header field giving an identifier for the primary resource created (Section 10.2.2), plus a representation describing the status of the request while referring to the new resource(s) ๐
Responses to POST requests are only cacheable when they include explicit freshness information (see Section 4.2.1 of [CACHING]) and a Content-Location header field whose value is the same as the POST's target URI (Section 8.7) ๐ง A cached POST response can be reused to satisfy a later GET or HEAD request. But a POST request can't be satisfied by a cached POST response, because POST is potentially unsafe; see Section 4 of [CACHING] ๐ซ
If processing a POST would produce a result equivalent to a representation of an existing resource, an origin server MAY redirect the user agent to that resource by sending a 303 (See Other) response with the existing resource's identifier in the Location field ๐ฆ This gives the user agent a resource identifier and moves the representation over a method that's friendlier to shared caching. The tradeoff is an extra request if the user agent doesn't already have that representation cached ๐ซ
9.3.4. PUT ๐
okay bestie, PUT is the method that says "make this resource look like THIS" ๐ The enclosed representation in the request message content is what the target resource gets created or replaced with. If that works, a GET on the same target later should get back an equivalent representation in a 200 (OK) response โจ But ngl, there's no guarantee you'll see that change, because other user agents might be poking the same resource at the same time, or the origin server might be doing dynamic processing before your GET shows up ๐ญ A success only means your intent was achieved at the moment the origin server processed it ๐ซถ
If the target resource doesn't have a current representation and the PUT creates one, the origin server MUST inform the user agent by sending a 201 (Created) response ๐ธ If it already has a current representation and that gets successfully changed to match the enclosed one, the origin server MUST send either a 200 (OK) or a 204 (No Content) response to show the request finished ๐
An origin server SHOULD verify that the PUT representation fits its configured constraints for the target resource ๐ง For example, if the server works out a resource's representation metadata from the URI, then it needs to make sure whatever shows up in a successful PUT matches that metadata. When a PUT representation doesn't fit the target resource, the origin server SHOULD either make them match, by transforming the representation or changing the resource config, or send back an appropriate error message with enough info to explain why it's unsuitable ๐ฅ The 409 (Conflict) or 415 (Unsupported Media Type) status codes are suggested, and the 415 one is specifically for constraints on Content-Type values ๐
For example, if the target resource is configured to always have a Content-Type of "text/html" and the representation being PUT has a Content-Type of "image/jpeg", the origin server ought to do one of:
a. reconfigure the target resource to reflect the new media type;
b. transform the PUT representation to a format consistent with that of the resource before saving it as the new resource state; or,
c. reject the request with a 415 (Unsupported Media Type) response indicating that the target resource is limited to "text/html", perhaps including a link to a different resource that would be a suitable target for the new representation.
HTTP doesn't define exactly how a PUT affects an origin server's state beyond what the user agent's intent and the origin server's response semantics can express ๐ฆ It also doesn't define what a resource might be, in any sense of that word, beyond the interface HTTP gives you. It doesn't define how resource state is "stored", how that storage might change when resource state changes, or how the origin server turns resource state into representations. Generally speaking, all the implementation details behind the resource interface are intentionally hidden by the server ๐
This extends to how header and trailer fields get stored ๐ง Common header fields like Content-Type will typically be stored and returned on later GET requests, but header and trailer field handling is specific to the resource that got the request. So an origin server SHOULD ignore unrecognized header and trailer fields received in a PUT request (i.e., not save them as part of the resource state) ๐
An origin server MUST NOT send a validator field (Section 8.8), such as an ETag or Last-Modified field, in a successful response to PUT unless the request's representation data was saved without any transformation applied to the content (i.e., the resource's new representation data is identical to the content received in the PUT request) and the validator field value reflects the new representation. This requirement lets a user agent know when the representation it sent (and still keeps in memory) is the result of the PUT, so it doesn't need to be fetched again from the origin server ๐ The new validator(s) in the response can then be used for future conditional requests to prevent accidental overwrites (Section 13.1) โญ
The fundamental difference between POST and PUT is shown by the different intent behind the enclosed representation ๐ The target resource in a POST request is meant to handle the enclosed representation according to the resource's own semantics, whereas the enclosed representation in a PUT request is defined as replacing the state of the target resource. Hence, the intent of PUT is idempotent and visible to intermediaries, even though the exact effect is only known by the origin server ๐ซถ
Proper interpretation of a PUT request assumes the user agent knows which target resource it wants ๐ฏ A service that picks a proper URI on the client's behalf, after receiving a state-changing request, SHOULD be implemented using the POST method rather than PUT. If the origin server won't make the requested PUT state change to the target resource and instead wants it applied to a different resource, such as when the resource has moved to a different URI, then the origin server MUST send an appropriate 3xx (Redirection) response; the user agent MAY then decide for itself whether or not to redirect the request ๐ฆ
A PUT request applied to the target resource can have side effects on other resources ๐ธ For example, an article might have a URI for identifying "the current version" (a resource) that is separate from the URIs identifying each particular version (different resources that at one point shared the same state as the current version resource). A successful PUT on "the current version" URI might therefore create a new version resource in addition to changing the state of the target resource, and might also cause links to be added between the related resources โจ
Some origin servers support using the Content-Range header field (Section 14.4) as a request modifier to do a partial PUT, as described in Section 14.5 ๐
Responses to the PUT method are not cacheable ๐ If a successful PUT request passes through a cache that has one or more stored responses for the target URI, those stored responses will be invalidated (see Section 4.4 of [CACHING]) ๐
9.3.5. DELETE ๐งน
The DELETE method requests that the origin server remove the association between the target resource and its current functionality ๐ค Basically this method is like the "rm" command in UNIX: it expresses a deletion operation on the URI mapping of the origin server, rather than an expectation that the previously associated information gets deleted ๐
If the target resource has one or more current representations, they might or might not be destroyed by the origin server, and the associated storage might or might not be reclaimed. That depends entirely on the nature of the resource and how the origin server implements it (which is beyond the scope of this specification) ๐คทโโ๏ธ Likewise, other implementation aspects of a resource might need to be deactivated or archived as a result of a DELETE, like database or gateway connections. In general, it's assumed that the origin server will only allow DELETE on resources for which it has a prescribed mechanism for doing the deletion ๐
Relatively few resources allow the DELETE method, because its main use is in remote authoring environments where the user has some direction over its effect ๐๏ธ For example, a resource that was previously created using a PUT request, or that was identified via the Location header field after a 201 (Created) response to a POST request, might allow a matching DELETE request to undo those actions ๐ฆ Similarly, custom user agent implementations that do an authoring function, like revision control clients using HTTP for remote operations, might use DELETE on the assumption that the server's URI space has been crafted to match a version repository ๐
If a DELETE method is successfully applied, the origin server SHOULD send:
- a 202 (Accepted) status code if the action will likely succeed but has not yet been enacted,
- a 204 (No Content) status code if the action has been enacted and no further information is to be supplied, or
- a 200 (OK) status code if the action has been enacted and the response message includes a representation describing the status.
Although request message framing is independent of the method used, content received in a DELETE request has no generally defined semantics, cannot alter the meaning or target of the request, and might lead some implementations to reject the request and close the connection because of its potential as a request smuggling attack (Section 11.2 of [HTTP/1.1]) ๐จ A client SHOULD NOT generate content in a DELETE request unless it's made directly to an origin server that has previously indicated, in or out of band, that such a request has a purpose and will be adequately supported. An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain ๐ซ
Responses to the DELETE method are not cacheable ๐ If a successful DELETE request passes through a cache that has one or more stored responses for the target URI, those stored responses will be invalidated (see Section 4.4 of [CACHING]) ๐
9.3.6. CONNECT ๐ฆ
okay so CONNECT is the method that basically says "hey proxy, can you open a tunnel to this destination for me?" ๐ If that works, the connection stops acting like HTTP and just blindly forwards data both ways until someone closes it ๐ซถ. Tunnels are super popular for making an end-to-end virtual connection through one or more proxies, and then you can secure that connection with TLS (Transport Layer Security, [TLS13]) ๐. it's giving secure main character energy ๐
CONNECT has its own special request target that only it uses ๐. It's just the host and port number of the tunnel destination, separated by a colon. There's no default port, so a client MUST send the port number even if the CONNECT request is based on a URI reference whose authority component has an elided port (Section 4.1). For example:
CONNECT server.example.com:80 HTTP/1.1
Host: server.example.com
A server MUST reject a CONNECT request that targets an empty or invalid port number, usually by responding with a 400 (Bad Request) status code ๐ โโ๏ธ
Because CONNECT changes the request/response vibe of an HTTP connection, specific HTTP versions might map its semantics onto the wire format in different ways ๐
CONNECT is meant for requests to a proxy ๐. The recipient can set up the tunnel either by connecting directly to the server named in the request target or, if it's configured to use another proxy, by forwarding the CONNECT request to the next inbound proxy ๐ง. An origin server MAY accept a CONNECT request, but most origin servers don't implement CONNECT, so don't hold your breath ๐
Any 2xx (Successful) response means the sender (and all inbound proxies) will switch to tunnel mode right after the response header section ๐. Data received after that header section comes from the server named in the request target. Any response that isn't a successful one means the tunnel hasn't been formed yet ๐
A tunnel closes when a tunnel intermediary notices that either side has closed its connection. At that point the intermediary MUST attempt to send any outstanding data that came from the closed side to the other side, close both connections, and then discard any leftover data that never got delivered ๐ญ
Proxy authentication might be used to prove you're allowed to create a tunnel ๐. For example:
CONNECT server.example.com:443 HTTP/1.1
Host: server.example.com:443
Proxy-Authorization: basic aGVsbG86d29ybGQ=
โ ๏ธ bestie, this part is serious. Setting up a tunnel to arbitrary servers is risky, especially when the destination is a well-known or reserved TCP port that isn't meant for Web traffic ๐จ. For example, a CONNECT to "example.com:25" would make the proxy connect to the reserved port for SMTP traffic. If that's allowed, it could trick the proxy into relaying spam email ๐ง๐. So proxies that support CONNECT SHOULD restrict its use to a limited set of known ports or a configurable list of safe request targets ๐.
A server MUST NOT send any Transfer-Encoding or Content-Length header fields in a 2xx (Successful) response to CONNECT. And a client MUST ignore any Content-Length or Transfer-Encoding header fields it gets in a successful response to CONNECT ๐ โโ๏ธโจ
A CONNECT request message doesn't have content ๐ซง. What the data sent after the header section of the CONNECT request message means depends on the version of HTTP in use ๐ฆ
Responses to the CONNECT method are not cacheable ๐ซ๐พ
9.3.7. OPTIONS ๐ง
The OPTIONS method asks for info about the communication options available for the target resource, whether that's at the origin server or some intervening intermediary ๐. It lets a client figure out the options and/or requirements tied to a resource, or what a server is capable of, without implying any actual resource action ๐ธ
An OPTIONS request with an asterisk (*) as the request target (Section 7.1) applies to the server in general, not to one specific resource ๐. Since a server's options usually depend on the resource, the * request is only really useful as a "ping" or "no-op" kind of method ๐. It does nothing beyond letting the client test the server's capabilities. For example, you could use it to test a proxy for HTTP/1.1 conformance (or lack thereof) ๐
If the request target isn't an asterisk, the OPTIONS request applies to the options that are available when communicating with that target resource ๐
A server generating a successful response to OPTIONS SHOULD send any header that might indicate optional features it implements and that apply to the target resource (for example, Allow). That includes potential extensions not defined by this specification ๐. The response content, if there is any, might also describe the communication options in a machine or human-readable representation ๐ค. This specification doesn't define a standard format for that representation, but future HTTP extensions might ๐ฎ
A client MAY send a Max-Forwards header field in an OPTIONS request to target a specific recipient in the request chain (see Section 7.6.2) ๐ฏ. A proxy MUST NOT generate a Max-Forwards header field while forwarding a request, unless that request was received with a Max-Forwards field ๐ซ
A client that generates an OPTIONS request containing content MUST send a valid Content-Type header field describing the representation media type ๐. Heads up, though: this specification doesn't define any use for such content ๐
Responses to the OPTIONS method are not cacheable ๐ซ๐พ
9.3.8. TRACE ๐
The TRACE method asks for a remote, application-level loop-back of the request message ๐ช. The final recipient of the request SHOULD reflect the message it received back to the client as the content of a 200 (OK) response, minus some fields described below ๐. The "message/http" format (Section 10.1 of [HTTP/1.1]) is one way to do that โจ. The final recipient is either the origin server or the first server to receive a Max-Forwards value of zero (0) in the request (Section 7.6.2) ๐
A client MUST NOT generate fields in a TRACE request that contain sensitive data the response might disclose. For example, it would be foolish for a user agent to send stored user credentials (Section 11) or cookies [COOKIE] in a TRACE request ๐ โโ๏ธ๐ช. The final recipient SHOULD exclude any request fields that are likely to contain sensitive data when it generates the response content ๐
TRACE lets the client see what's being received at the other end of the request chain, and use that for testing or diagnostics ๐ฉบ. The Via header field (Section 7.6.3) is especially interesting, since it acts as a trace of the request chain ๐ค๏ธ. The Max-Forwards header field lets the client limit how long the request chain gets, which is handy for testing a chain of proxies that's forwarding messages in an infinite loop ๐โพ๏ธ
A client MUST NOT send content in a TRACE request ๐ซ
Responses to the TRACE method are not cacheable ๐ซ๐พ
10. Message Context ๐ท
10.1. Request Context Fields ๐ง
The request header fields below give extra info about the request context ๐ซถ. That includes details about the user, the user agent, and the resource behind the request ๐
10.1.1. Expect
The "Expect" header field in a request indicates a certain set of behaviors (expectations) that need to be supported by the server in order to properly handle this request. ๐ โจ
Expect = #expectation
expectation = token [ "=" ( token / quoted-string ) parameters ]
The Expect field value is case-insensitive. ๐
The only expectation defined by this specification is "100-continue" (with no defined parameters). ๐ฆ
A server that receives an Expect field value containing a member other than 100-continue MAY respond with a 417 (Expectation Failed) status code to indicate that the unexpected expectation cannot be met. ๐
okay so a "100-continue" expectation basically tells the server "hey bestie, I'm about to send a big chunk of content, and I want a 100 (Continue) interim response first, but only if the method, target URI, and header fields aren't already enough for an immediate success, redirect, or error response." ๐ซถ This lets the client pause and check that it's actually worth sending the data before it starts filling the pipes, which is super efficient when the data is huge or when the client expects an error, like when it's sending a state-changing method for the first time without previously verified authentication credentials. ๐ญ๐ฅ
For example, a request that begins with
PUT /somewhere/fun HTTP/1.1
Host: origin.example.com
Content-Type: video/h264
Content-Length: 1234567890987
Expect: 100-continue
lets the origin server immediately respond with an error message, such as 401 (Unauthorized) or 405 (Method Not Allowed), before the client starts sending an unnecessary data transfer. ๐๐
Requirements for clients:
- A client MUST NOT generate a 100-continue expectation in a request that does not include content. ๐ โโ๏ธ
- A client that will wait for a 100 (Continue) response before sending the request content MUST send an Expect header field containing a 100-continue expectation. ๐
- A client that sends a 100-continue expectation is not required to wait for any specific length of time; such a client MAY proceed to send the content even if it has not yet received a response. Furthermore, since 100 (Continue) responses cannot be sent through an HTTP/1.0 intermediary, such a client SHOULD NOT wait for an indefinite period before sending the content. โณโจ
- A client that receives a 417 (Expectation Failed) status code in response to a request containing a 100-continue expectation SHOULD repeat that request without a 100-continue expectation, since the 417 response merely indicates that the response chain does not support expectations (e.g., it passes through an HTTP/1.0 server). ๐๐ธ
Requirements for servers:
- A server that receives a 100-continue expectation in an HTTP/1.0 request MUST ignore that expectation. ๐
- A server MAY omit sending a 100 (Continue) response if it has already received some or all of the content for the corresponding request, or if the framing indicates that there is no content. ๐ง
- A server that sends a 100 (Continue) response MUST ultimately send a final status code, once it receives and processes the request content, unless the connection is closed prematurely. ๐
- A server that responds with a final status code before reading the entire request content SHOULD indicate whether it intends to close the connection (e.g., see Section 9.6 of [HTTP/1.1]) or continue reading the request content. ๐
Upon receiving an HTTP/1.1 (or later) request that has a method, target URI, and complete header section that contains a 100-continue expectation and an indication that request content will follow, an origin server MUST send either:
- an immediate response with a final status code, if that status can be determined by examining just the method, target URI, and header fields, or
- an immediate 100 (Continue) response to encourage the client to send the request content.
The origin server MUST NOT wait for the content before sending the 100 (Continue) response. ๐
Upon receiving an HTTP/1.1 (or later) request that has a method, target URI, and complete header section that contains a 100-continue expectation and indicates a request content will follow, a proxy MUST either:
- send an immediate response with a final status code, if that status can be determined by examining just the method, target URI, and header fields, or
- forward the request toward the origin server by sending a corresponding request-line and header section to the next inbound server.
If the proxy believes (from configuration or past interaction) that the next inbound server only supports HTTP/1.0, the proxy MAY generate an immediate 100 (Continue) response to encourage the client to begin sending the content. ๐
10.1.2. From
The "From" header field contains an Internet email address for a human user who controls the requesting user agent. The address ought to be machine-usable, as defined by "mailbox" in Section 3.4 of [RFC5322]: ๐ฌ
From = mailbox
mailbox = <mailbox, see [RFC5322], Section 3.4>
An example is:
From: spider-admin@example.org
The From header field is rarely sent by non-robotic user agents. A user agent SHOULD NOT send a From header field without explicit configuration by the user, since that might conflict with the user's privacy interests or their site's security policy. ๐
A robotic user agent SHOULD send a valid From header field so that the person responsible for running the robot can be contacted if problems occur on servers, such as if the robot is sending excessive, unwanted, or invalid requests. ๐ค๐
A server SHOULD NOT use the From header field for access control or authentication, since its value is expected to be visible to anyone receiving or observing the request and is often recorded within logfiles and error reports without any expectation of privacy. ๐ โโ๏ธ๐ชต
10.1.3. Referer
The "Referer" [sic] header field allows the user agent to specify a URI reference for the resource from which the target URI was obtained (i.e., the "referrer", though the field name is misspelled). ๐ A user agent MUST NOT include the fragment and userinfo components of the URI reference [URI], if any, when generating the Referer field value. ๐ก๏ธ
Referer = absolute-URI / partial-URI
The field value is either an absolute-URI or a partial-URI. In the latter case (Section 4), the referenced URI is relative to the target URI ([URI], Section 5). ๐งญ
The Referer header field allows servers to generate back-links to other resources for simple analytics, logging, optimized caching, etc. It also allows obsolete or mistyped links to be found for maintenance. Some servers use the Referer header field as a means of denying links from other sites (so-called "deep linking") or restricting cross-site request forgery (CSRF), but not all requests contain it. ๐ต๏ธโโ๏ธ
Example:
Referer: http://www.example.org/hypertext/Overview.html
If the target URI was obtained from a source that does not have its own URI (e.g., input from the user keyboard, or an entry within the user's bookmarks/favorites), the user agent MUST either exclude the Referer header field or send it with a value of "about:blank". ๐
The Referer header field value need not convey the full URI of the referring resource; a user agent MAY truncate parts other than the referring origin. โ๏ธ
The Referer header field has the potential to reveal information about the request context or browsing history of the user, which is a privacy concern if the referring resource's identifier reveals personal information (such as an account name) or a resource that is supposed to be confidential (such as behind a firewall or internal to a secured service). Most general-purpose user agents do not send the Referer header field when the referring resource is a local "file" or "data" URI. A user agent SHOULD NOT send a Referer header field if the referring resource was accessed with a secure protocol and the request target has an origin differing from that of the referring resource, unless the referring resource explicitly allows Referer to be sent. A user agent MUST NOT send a Referer header field in an unsecured HTTP request if the referring resource was accessed with a secure protocol. See Section 17.9 for additional security considerations. ๐จ๐
Some intermediaries have been known to indiscriminately remove Referer header fields from outgoing requests. This has the unfortunate side effect of interfering with protection against CSRF attacks, which can be far more harmful to their users. Intermediaries and user agent extensions that wish to limit information disclosure in Referer ought to restrict their changes to specific edits, such as replacing internal domain names with pseudonyms or truncating the query and/or path components. An intermediary SHOULD NOT modify or delete the Referer header field when the field value shares the same scheme and host as the target URI. ๐ค๐
10.1.4. TE
The "TE" header field describes capabilities of the client with regard to transfer codings and trailer sections. ๐
As described in Section 6.5, a TE field with a "trailers" member sent in a request indicates that the client will not discard trailer fields. ๐ซง
TE is also used within HTTP/1.1 to advise servers about which transfer codings the client is able to accept in a response. As of publication, only HTTP/1.1 uses transfer codings (see Section 7 of [HTTP/1.1]). ๐ฆ
The TE field value is a list of members, with each member (aside from "trailers") consisting of a transfer coding name token with an optional weight indicating the client's relative preference for that transfer coding (Section 12.4.2) and optional parameters for that transfer coding. ๐ธ
TE = #t-codings
t-codings = "trailers" / ( transfer-coding [ weight ] )
transfer-coding = token *( OWS ";" OWS transfer-parameter )
transfer-parameter = token BWS "=" BWS ( token / quoted-string )
A sender of TE MUST also send a "TE" connection option within the Connection header field (Section 7.6.1) to inform intermediaries not to forward this field. ๐โจ
10.1.5. User-Agent โจ
okay so the "User-Agent" header field is basically the little ID card a user agent hands over with each request ๐ชช๐ servers read it to figure out which client caused a weird bug, to tailor responses around a particular client's quirks, and for analytics on which browsers and operating systems are popular ๐๐ธ bestie, a user agent SHOULD send a User-Agent header field in each request unless it's specifically configured not to ๐ซถ
User-Agent = product *( RWS ( product / comment ) )
the field value is one or more product identifiers, each followed by zero or more comments (Section 5.6.5), and together they identify the user agent software and its important subproducts โจ by convention, the product identifiers are listed from most significant to least significant for identifying the software ๐ each product identifier is a name with an optional version ๐
product = token ["/" product-version]
product-version = token
a sender SHOULD keep generated product identifiers limited to what's actually needed to identify the product ๐ and a sender MUST NOT put advertising or other nonessential info inside a product identifier ๐ โโ๏ธ a sender SHOULD NOT put anything in product-version that isn't a version identifier either, because successive versions of the same product name ought to differ only in the product-version part ๐ฆ
Example:
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
a user agent SHOULD NOT generate a User-Agent header field with needlessly fine-grained detail, and SHOULD limit the addition of subproducts by third parties ๐ overly long, detailed User-Agent values make requests slower and raise the risk of someone being identified against their wishes, which is called "fingerprinting" ๐ญ๐ฅ
also, implementations are encouraged NOT to use other implementations' product tokens to claim compatibility with them, because that totally defeats the whole purpose of the field ๐ if a user agent pretends to be a different one, recipients can assume the user actually wants responses tailored for that identified agent, even if those might not work as well for the real one ๐
10.2. Response Context Fields ๐
these response header fields give extra info about the response beyond what the status code already says ๐ง that includes info about the server, the target resource, or related resources ๐
10.2.1. Allow ๐ฆ
the "Allow" header field lists the set of methods the target resource advertises as supported ๐ its whole job is to tell the recipient which request methods are valid for the resource, and nothing more ๐ซถ
Allow = #method
Example of use:
Allow: GET, HEAD, PUT
the actual set of allowed methods is decided by the origin server at the time of each request โฐ an origin server MUST generate an Allow header field in a 405 (Method Not Allowed) response and MAY do so in any other response ๐ an empty Allow field value means the resource allows no methods, which could happen in a 405 response if the resource was temporarily disabled by configuration ๐ธ
a proxy MUST NOT modify the Allow header field ๐ โโ๏ธ it doesn't need to understand every indicated method to handle them under the generic message handling rules, so it can just leave it alone โจ
10.2.2. Location ๐
the "Location" header field shows up in some responses to point at a specific resource related to the response ๐บ๏ธ what the relationship means depends on the combo of request method and status code semantics ๐
Location = URI-reference
the field value is a single URI-reference ๐ when it looks like a relative reference ([URI], Section 4.2), the final value gets computed by resolving it against the target URI ([URI], Section 5) ๐ง
for 201 (Created) responses, the Location value refers to the primary resource created by the request ๐ for 3xx (Redirection) responses, the Location value refers to the preferred target resource to automatically redirect the request to ๐ฆ
if the Location value in a 3xx (Redirection) response doesn't have a fragment component, a user agent MUST process the redirection as if the value inherits the fragment component of the URI reference used to make the target URI (so the redirection inherits the original reference's fragment, if there is one) ๐ซถ
for example, a GET request generated for the URI reference "http://www.example.org/~tim" might get a 303 (See Other) response with this header field:
Location: /People.html#tim
which suggests the user agent redirect to "http://www.example.org/People.html#tim" ๐
likewise, a GET request generated for the URI reference "http://www.example.org/index.html#larry" might get a 301 (Moved Permanently) response with this header field:
Location: http://www.example.net/index.html
which suggests the user agent redirect to "http://www.example.net/index.html#larry", preserving the original fragment identifier ๐
there are situations where a fragment identifier in a Location value wouldn't be appropriate ๐ for example, the Location header field in a 201 (Created) response is supposed to give a URI that's specific to the created resource ๐
Note: some recipients try to recover from Location header fields that aren't valid URI references ๐ ๏ธ this specification doesn't mandate or define that processing, but it does allow it for robustness โจ a Location field value can't hold a list of members, because the comma list separator is a valid data character within a URI-reference ๐ญ if an invalid message is sent with multiple Location field lines, a recipient along the path might combine those field lines into one value ๐ recovering a valid Location field value from that mess is hard and not interoperable across implementations ๐ฅ
Note: the Content-Location header field (Section 8.7) differs from Location because Content-Location refers to the most specific resource corresponding to the enclosed representation ๐ so it's totally possible for a response to contain both the Location and Content-Location header fields ๐
10.2.3. Retry-After โณ
servers send the "Retry-After" header field to say how long the user agent ought to wait before making a follow-up request ๐ฐ๏ธ when it's sent with a 503 (Service Unavailable) response, Retry-After tells the client how long the service is expected to be unavailable ๐ธ when it's sent with any 3xx (Redirection) response, Retry-After gives the minimum time the user agent is asked to wait before issuing the redirected request ๐ง
the Retry-After field value can be either an HTTP-date or a number of seconds to delay after receiving the response ๐
Retry-After = HTTP-date / delay-seconds
a delay-seconds value is a non-negative decimal integer representing time in seconds ๐ฆ
delay-seconds = 1*DIGIT
two examples of its use:
Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
Retry-After: 120
in the latter example, the delay is 2 minutes ๐
10.2.4. Server ๐ฅ๏ธ
the "Server" header field contains info about the software the origin server used to handle the request ๐ป clients often use it to figure out the scope of reported interoperability problems, to work around or tailor requests to avoid particular server limitations, and for analytics on server or operating system use ๐ an origin server MAY generate a Server header field in its responses โจ
Server = product *( RWS ( product / comment ) )
the Server header field value is one or more product identifiers, each followed by zero or more comments (Section 5.6.5), which together identify the origin server software and its significant subproducts ๐ by convention, the product identifiers are listed from most to least significant for identifying the origin server software ๐ซถ each product identifier is a name and optional version, as defined in Section 10.1.5 ๐
Example:
Server: CERN/3.0 libwww/2.17
an origin server SHOULD NOT generate a Server header field with needlessly fine-grained detail, and SHOULD limit the addition of subproducts by third parties ๐ overly long, detailed Server values make responses slower and can reveal internal implementation details that might make it (slightly) easier for attackers to find and exploit known security holes ๐ญ๐ฅ
11. HTTP Authentication ๐
11.1. Authentication Scheme ๐๏ธ
HTTP gives us a general framework for access control and authentication ๐ it's an extensible set of challenge-response authentication schemes, so a server can challenge a client request and a client can provide authentication info back ๐ฆ it uses a case-insensitive token to identify the authentication scheme โจ
auth-scheme = token
aside from the general framework, this document doesn't specify any authentication schemes ๐ new and existing schemes are specified independently and ought to be registered in the "Hypertext Transfer Protocol (HTTP) Authentication Scheme Registry" ๐ for example, the "basic" and "digest" schemes are defined by [RFC7617] and [RFC7616], respectively ๐ธ
11.2. Authentication Parameters ๐
the authentication scheme is followed by any extra info needed to authenticate using that scheme ๐ง that info is either a comma-separated list of parameters or a single sequence of characters that can hold base64-encoded information ๐
token68 = 1*( ALPHA / DIGIT /
"-" / "." / "_" / "~" / "+" / "/" ) *"="
the token68 syntax allows the 66 unreserved URI characters ([URI]), plus a few others, so it can hold a base64, base64url (URL and filename safe alphabet), base32, or base16 (hex) encoding, with or without padding, but excluding whitespace ([RFC4648]) ๐
authentication parameters are name/value pairs, where the name token is matched case-insensitively, and each parameter name MUST only occur once per challenge ๐ซ
auth-param = token BWS "=" BWS ( token / quoted-string )
parameter values can be written either as a "token" or as a "quoted-string" (Section 5.6) ๐ซถ authentication scheme definitions need to accept both notations, for both senders and recipients, so recipients can use generic parsing components no matter which scheme it is โจ
for backwards compatibility, authentication scheme definitions can restrict the format for senders to one of the two variants ๐ฐ๏ธ this can be important when it's known that deployed implementations will fail when they hit one of the two formats ๐
11.3. Challenge and Response ๐
okay so the 401 (Unauthorized) response is how an origin server says "wait, who even are you?" ๐ It's basically a bouncer checking your ID. The server includes a WWW-Authenticate header field with at least one challenge that applies to the resource you asked for.
The 407 (Proxy Authentication Required) response is the same vibe, but it comes from a proxy instead. It challenges the client with a Proxy-Authenticate header field containing at least one challenge that applies to that proxy for the requested resource. ๐ง
challenge = auth-scheme [ 1*SP ( token68 / #auth-param ) ]
Note: Many clients fail to parse a challenge that contains an unknown scheme. A workaround for this problem is to list well-supported schemes (such as "basic") first. ๐ซถ
So a user agent that wants to prove who it is to an origin server (usually after a 401, but not always) can include an Authorization header field in its request. ๐
A client that wants to authenticate with a proxy (usually after a 407, but not always) can do the same thing with a Proxy-Authorization header field. ๐ฆ
11.4. Credentials ๐
The Authorization and Proxy-Authorization field values both hold the client's credentials for the realm of the requested resource. These are based on a challenge that was received in an earlier response, possibly way back in the past. ๐
When the user agent makes these values, it ought to pick the challenge with the most secure auth-scheme that it understands, and get credentials from the user where that makes sense. Sending credentials inside header field values has big security implications for the confidentiality of the underlying connection, as described in Section 17.16.1. This is serious bestie stuff ๐ญ
credentials = auth-scheme [ 1*SP ( token68 / #auth-param ) ]
Now, if a server gets a request for a protected resource and the credentials are missing, invalid (like a wrong password), or only partial (like when the scheme needs more than one round trip), the origin server SHOULD send a 401 (Unauthorized) response. That response has a WWW-Authenticate header field with at least one challenge that applies to the resource, and it can be a new one. ๐ธ
Same energy for proxies: if a request is missing proxy credentials or has invalid or partial ones, a proxy that needs authentication SHOULD generate a 407 (Proxy Authentication Required) response. That response carries a Proxy-Authenticate header field with at least one challenge that applies to the proxy, possibly a new one. โจ
A server that gets valid credentials that still aren't enough to get in ought to respond with the 403 (Forbidden) status code (Section 15.5.4). Valid but not good enough, periodt ๐
HTTP doesn't force applications into this simple challenge-response setup for access authentication. Other mechanisms can be used too, like authentication at the transport level or through message encapsulation, along with extra header fields that carry authentication info. This specification doesn't define any of those additional mechanisms though, so that's a separate story ๐ง
Also, a bunch of custom user authentication mechanisms pass their tokens around using the Set-Cookie and Cookie header fields, which are defined in [COOKIE]. Iykyk ๐
11.5. Establishing a Protection Space (Realm) ๐ฐ
The "realm" authentication parameter is reserved for authentication schemes that want to indicate a scope of protection. It's like drawing a fence around a bunch of resources. ๐
A "protection space" is defined by the origin (see Section 4.3.1) of the server being accessed, combined with the realm value if there is one. Realms let a server split its protected resources into multiple protection spaces, and each one can have its own authentication scheme and/or authorization database. The realm value is a string, usually assigned by the origin server, and it can have extra meaning that depends on the authentication scheme. Also, a single response can have multiple challenges that use the same auth-scheme but have different realms. Wild, right? ๐
The protection space decides where credentials can be applied automatically. If a prior request was authorized, the user agent MAY reuse those same credentials for every other request within that protection space, for however long the authentication scheme, its parameters, and/or user preferences allow (like a configurable inactivity timeout). ๐ฆ
The size of a protection space, and therefore which requests might get credentials applied automatically, isn't always obvious to clients without extra info. An authentication scheme might define parameters that describe how big the protection space is. Unless the authentication scheme specifically allows it, a single protection space cannot extend outside the scope of its server. Boundaries are important, bestie ๐ซถ
For historical reasons, a sender MUST only generate the quoted-string syntax. Recipients might have to support both token and quoted-string syntax to play nicely with existing clients, which have been accepting both notations for a long time. Very reliable of them ๐
11.6. Authenticating Users to Origin Servers ๐งโ๐ป
11.6.1. WWW-Authenticate ๐ชช
The WWW-Authenticate response header field tells you which authentication scheme(s) and parameters apply to the target resource.
WWW-Authenticate = #challenge
A server that generates a 401 (Unauthorized) response MUST send a WWW-Authenticate header field with at least one challenge. A server MAY also generate a WWW-Authenticate header field in other response messages, to show that supplying credentials (or different ones) might change the response. ๐
A proxy that forwards a response MUST NOT modify any WWW-Authenticate header fields in it. Hands off! ๐
โโ๏ธ
User agents should be extra careful when parsing this field value, because it might hold more than one challenge. Each challenge can also contain a comma-separated list of authentication parameters. On top of that, the header field itself can show up multiple times. It's a lot, so take your time ๐
Here's an example:
WWW-Authenticate: Basic realm="simple", Newauth realm="apps",
type=1, title="Login to \"apps\""
This header field has two challenges. One is for the "Basic" scheme with a realm value of "simple", and the other is for the "Newauth" scheme with a realm value of "apps". It also includes two extra parameters, "type" and "title". โจ
Some user agents don't recognize this form, though. So sending a WWW-Authenticate field value with more than one member on the same field line might not be interoperable. Plot twist ๐ญ
Note: The challenge grammar production uses the list syntax as well. Therefore, a sequence of comma, whitespace, and comma can be considered either as applying to the preceding challenge, or to be an empty entry in the list of challenges. In practice, this ambiguity does not affect the semantics of the header field value and thus is harmless. ๐ธ
11.6.2. Authorization ๐๏ธ
The Authorization header field lets a user agent authenticate itself with an origin server, usually (but not always) after it gets a 401 (Unauthorized) response. Its value is made of credentials that hold the user agent's authentication info for the realm of the requested resource. ๐
Authorization = credentials
If a request is authenticated and a realm is specified, the same credentials are presumed valid for all other requests within that realm. This assumes the authentication scheme itself doesn't require otherwise, like credentials that change based on a challenge value or that rely on synchronized clocks. ๐ง
A proxy that forwards a request MUST NOT modify any Authorization header fields in that request. For details and requirements on how HTTP caches handle the Authorization header field, see Section 3.5 of [CACHING]. ๐
11.6.3. Authentication-Info ๐
HTTP authentication schemes can use the Authentication-Info response field to share info after the client's credentials have been accepted. This can include a finalization message from the server, like server authentication. Ooh, mutual vibes ๐ค
The field value is a list of parameters (name/value pairs) that use the "auth-param" syntax from Section 11.3. This specification only describes the generic format. Authentication schemes that use Authentication-Info define the individual parameters themselves. For instance, the "Digest" Authentication Scheme defines multiple parameters in Section 3.5 of [RFC7616]. ๐
Authentication-Info = #auth-param
The Authentication-Info field can show up in any HTTP response, no matter the request method or status code. Its semantics come from the authentication scheme named by the Authorization header field (Section 11.6.2) of the corresponding request. ๐
A proxy that forwards a response is not allowed to modify the field value in any way. Don't touch it ๐ โโ๏ธ
Authentication-Info can be sent as a trailer field (Section 6.5), but only when the authentication scheme explicitly allows it. ๐ฆ
11.7. Authenticating Clients to Proxies ๐ช
11.7.1. Proxy-Authenticate ๐ก๏ธ
The Proxy-Authenticate header field has at least one challenge that shows which authentication scheme(s) and parameters apply to the proxy for this request. A proxy MUST send at least one Proxy-Authenticate header field in each 407 (Proxy Authentication Required) response it generates. ๐
Proxy-Authenticate = #challenge
Unlike WWW-Authenticate, the Proxy-Authenticate header field only applies to the next outbound client on the response chain. That's because only the client that picked a given proxy is likely to have the credentials needed to authenticate. ๐ซถ
But when several proxies sit inside the same administrative domain, like office and regional caching proxies in a big corporate network, credentials are often generated by the user agent and passed down the hierarchy until someone uses them. So in that setup, it'll look like Proxy-Authenticate is being forwarded, because each proxy sends the same challenge set. Looks like forwarding, but it's a vibe check ๐ญ
Note that the parsing considerations for WWW-Authenticate also apply to this header field. See Section 11.6.1 for the details. ๐
11.7.2. Proxy-Authorization ๐
The Proxy-Authorization header field lets the client identify itself (or its user) to a proxy that requires authentication. Its value is made of credentials holding the client's authentication info for the proxy and/or the realm of the requested resource. ๐
Proxy-Authorization = credentials
Unlike Authorization, the Proxy-Authorization header field only applies to the next inbound proxy that asked for authentication with the Proxy-Authenticate header field. When multiple proxies are chained together, the first inbound proxy that was expecting credentials is the one that consumes the Proxy-Authorization header field. ๐ธ
A proxy MAY relay the credentials from the client request to the next proxy, if that's how the proxies cooperatively authenticate a given request. Teamwork makes the dream work ๐ซถ๐ฆ
11.7.3. Proxy-Authentication-Info ๐
Okay bestie, Proxy-Authentication-Info is basically the twin of Authentication-Info ๐ฏโโ๏ธ but it's for proxy auth (see Section 11.3) ๐
. Its meaning comes from whatever auth scheme the Proxy-Authorization header on the matching request used (Section 11.7.2) ๐ฅ:
Proxy-Authentication-Info = #auth-param
BUT, unlike the regular one, this header only applies to the next outbound client on the response chain ๐ญ. Only the client that picked that proxy is likely to have the credentials it needs to do the auth, so it makes sense ๐ง. Now here's the plot twist: when a bunch of proxies live in the same administrative domain (like office and regional caching proxies in a big corporate network ๐ข), it's super common for the user agent to generate credentials and pass them down the hierarchy until something consumes them ๐. So in that setup, it'll look like Proxy-Authentication-Info is getting forwarded, because every proxy sends the same field value ๐.
Proxy-Authentication-Info can be sent as a trailer field (Section 6.5) when the authentication scheme explicitly allows this โจ.
12. Content Negotiation ๐
When responses convey content, whether they're a success or an error, the origin server often has different ways of representing that info ๐. Like, different formats, languages, or encodings ๐ธ. Different users or user agents might also have different capabilities, characteristics, or preferences that could change which representation, out of the ones available, would be best to deliver โจ. That's why HTTP gives us mechanisms for content negotiation ๐ซถ.
This specification defines three patterns of content negotiation that can be made visible within the protocol ๐: "proactive" negotiation, where the server picks the representation based on the user agent's stated preferences; "reactive" negotiation, where the server gives a list of representations for the user agent to choose from; and "request content" negotiation, where the user agent picks the representation for a future request based on the server's stated preferences in past responses ๐ฆ.
There are other patterns too ๐ . "Conditional content" is when the representation is made of multiple parts that get selectively rendered based on user agent parameters. "Active content" is when the representation has a script that makes extra, more specific requests based on user agent characteristics. And "Transparent Content Negotiation" ([RFC2295]) is when an intermediary does the selecting ๐ง. These patterns aren't mutually exclusive, and each one has trade-offs in how applicable and practical it is ๐.
Note that, in all cases, HTTP is not aware of the resource semantics ๐. How consistently an origin server responds to requests over time and across the different dimensions of content negotiation, and therefore how "same" a resource's observed representations stay over time, is decided entirely by whatever entity or algorithm picks or generates those responses ๐.
12.1. Proactive Negotiation ๐ฅ
When the user agent sends content negotiation preferences in a request to encourage an algorithm at the server to pick the preferred representation, it's called "proactive negotiation" (a.k.a., "server-driven negotiation") ๐. Selection is based on the available representations for a response (the dimensions it might vary over, like language, content coding, etc.) compared against various info in the request. That includes both the explicit negotiation header fields below and implicit characteristics, like the client's network address or parts of the User-Agent field ๐.
Proactive negotiation is great when the algorithm for choosing among the available representations is hard to describe to a user agent ๐ง . It's also useful when the server wants to send its "best guess" along with the first response. If that "best guess" is good enough for the user, this skips the round-trip delay of a follow-up request โญ. To improve the server's guess, a user agent MAY send request header fields that describe its preferences ๐.
Proactive negotiation has some serious disadvantages, though ๐ญ:
- It's impossible for the server to accurately figure out what might be "best" for any given user, since that would need complete knowledge of both the user agent's capabilities and the intended use for the response (e.g., does the user want to view it on screen or print it on paper?);
- Having the user agent describe its capabilities in every request can be both super inefficient (since only a small percentage of responses have multiple representations) and a potential risk to the user's privacy ๐;
- It complicates the implementation of an origin server and the algorithms for generating responses to a request; and,
- It limits how reusable responses are for shared caching.
A user agent can't rely on proactive negotiation preferences being consistently honored ๐. The origin server might not implement proactive negotiation for the requested resource, or it might decide that sending a response that doesn't match the user agent's preferences is better than sending a 406 (Not Acceptable) response ๐คทโโ๏ธ.
A Vary header field (Section 12.5.5) is often sent in a response subject to proactive negotiation to show what parts of the request info were used in the selection algorithm ๐ง.
The request header fields Accept, Accept-Charset, Accept-Encoding, and Accept-Language are defined below so a user agent can do proactive negotiation of the response content ๐
. The preferences sent in these fields apply to any content in the response, including representations of the target resource, representations of error or processing status, and potentially even the miscellaneous text strings that might show up within the protocol ๐.
12.2. Reactive Negotiation ๐ฆ
With "reactive negotiation" (a.k.a., "agent-driven negotiation"), the user agent does the selecting of content (no matter the status code) after it gets an initial response ๐ซถ. The mechanism for reactive negotiation can be as simple as a list of references to alternative representations ๐.
If the user agent isn't satisfied by the initial response content, it can make a GET request on one or more of the alternative resources to get a different representation ๐โโ๏ธ. Picking those alternatives might happen automatically (by the user agent) or manually (e.g., the user picks from a hypertext menu) ๐.
A server might choose not to send an initial representation, other than the list of alternatives, and so signal that reactive negotiation by the user agent is preferred โจ. For example, the alternatives listed in responses with the 300 (Multiple Choices) and 406 (Not Acceptable) status codes include info about the available representations, so the user or user agent can react by making a selection ๐.
Reactive negotiation is a win when the response would vary over commonly used dimensions (like type, language, or encoding) ๐ธ, when the origin server can't figure out a user agent's capabilities just by looking at the request ๐, and generally when public caches are used to spread out server load and cut down on network usage ๐.
Reactive negotiation does have downsides ๐ญ. Sending a list of alternatives to the user agent degrades user-perceived latency if it's sent in the header section, and you need a second request to get an alternate representation. Also, this specification doesn't define a mechanism for automatic selection, though it doesn't stop one from being developed later ๐ฎ.
12.3. Request Content Negotiation ๐ธ
When content negotiation preferences are sent in a server's response, the listed preferences are called "request content negotiation" because they're meant to influence which content gets picked for subsequent requests to that resource ๐. For example, the Accept (Section 12.5.1) and Accept-Encoding (Section 12.5.3) header fields can be sent in a response to indicate preferred media types and content codings for subsequent requests to that resource ๐.
Similarly, Section 3.1 of [RFC5789] defines the "Accept-Patch" response header field ๐ง, which lets clients discover which content types are accepted in PATCH requests ๐.
12.4. Content Negotiation Field Features ๐
12.4.1. Absence ๐
For each of the content negotiation fields, a request that doesn't contain the field implies the sender has no preference on that dimension of negotiation โจ.
If a content negotiation header field is present in a request and none of the available representations for the response can be considered acceptable according to it, the origin server can either honor the header field by sending a 406 (Not Acceptable) response, or disregard the header field by treating the response as if it's not subject to content negotiation for that request header field ๐ค. That doesn't mean, though, that the client will actually be able to use the representation ๐.
Note: A user agent sending these header fields makes it easier for a server to identify an individual by virtue of the user agent's request characteristics (Section 17.13). ๐
12.4.2. Quality Values ๐
The content negotiation fields defined by this specification use a common parameter, named "q" (case-insensitive), to assign a relative "weight" to the preference for that associated kind of content ๐. This weight is called a "quality value" (or "qvalue") because the same parameter name is often used in server configurations to assign a weight to the relative quality of the various representations that can be selected for a resource โญ.
The weight is normalized to a real number in the range 0 through 1, where 0.001 is the least preferred and 1 is the most preferred. A value of 0 means "not acceptable". If no "q" parameter is present, the default weight is 1 ๐.
weight = OWS ";" OWS "q=" qvalue
qvalue = ( "0" [ "." 0*3DIGIT ] )
/ ( "1" [ "." 0*3("0") ] )
A sender of qvalue MUST NOT generate more than three digits after the decimal point ๐ โโ๏ธ. User configuration of these values ought to be limited in the same fashion ๐ซถ.
12.4.3. Wildcard Values ๐ฆ
Most of these header fields, where indicated, define a wildcard value ("*") to select unspecified values ๐. If no wildcard is present, values that aren't explicitly mentioned in the field are considered unacceptable ๐ซ. Within Vary, the wildcard value means the variance is unlimited ๐ง.
Note: In practice, using wildcards in content negotiation has limited practical value, because it's seldom useful to say, for example, "I prefer image/* more or less than (some other specific value)". By sending Accept: */*;q=0, clients can explicitly request a 406 (Not Acceptable) response if a more preferred format isn't available. But they still need to be able to handle a different response, since the server is allowed to ignore their preference ๐ญ๐
.
12.5. Content Negotiation Fields ๐
12.5.1. Accept ๐
okay so the Accept header field is how user agents tell the server what kinds of response media types they're into ๐ like, if you only want a tiny specific set of stuff, that's how you say it. it's giving "I'm here for an in-line image and NOTHING else" ๐ผ๏ธ
when a server sends Accept in a response, it's basically dropping a hint about which content types are preferred in the content of a later request to that same resource ๐ง
Accept = #( media-range [ weight ] )
media-range = ( "*/*"
/ ( type "/" "*" )
/ ( type "/" subtype )
) parameters
the asterisk * is how you group media types into ranges ๐ */* means ALL media types and type/* means all the subtypes of that one type. a media-range can also carry media type parameters that apply to that range ๐
each media-range can be followed by optional media type parameters (like charset), and then an optional q parameter for the relative weight (Section 12.4.2) โญ
earlier specs let extra extension parameters show up after the weight, but the accept extension grammar (accept-params, accept-ext) got removed ๐ it was super complicated, nobody was actually using it, and it's way easier to ship stuff through brand new header fields instead. if you're sending weights, senders SHOULD put q last (after all the media-range parameters) ๐ซถ and recipients SHOULD treat any parameter named q as the weight, no matter where it sits in the order โจ
๐จ Note: Using theqparameter name for content negotiation would clash with any media type parameter that has the same name. So the media type registry doesn't allow parameters namedq๐
here's a cute one:
Accept: audio/*; q=0.2, audio/basic
this basically means "I prefer audio/basic, but send me any audio type if it's the best available after an 80% markdown in quality" ๐ง
a more extra example:
Accept: text/plain; q=0.5, text/html,
text/x-dvi; q=0.8, text/x-c
so the vibe here is: text/html and text/x-c are tied for first place ๐ but if neither exists, send the text/x-dvi version, and if THAT doesn't exist either, fall back to text/plain ๐
media ranges can get overridden by more specific media ranges or by specific media types ๐ฆ if more than one range applies to the same type, the most specific one wins. for example:
Accept: text/*, text/plain, text/plain;format=flowed, */*
has this precedence, highest first:
text/plain;format=flowedtext/plaintext/**/*
the quality factor for a type comes from whichever matching media range has the highest precedence ๐ธ check this out:
Accept: text/*;q=0.3, text/plain;q=0.7, text/plain;format=flowed,
text/plain;format=fixed;q=0.4, */*;q=0.5
which ends up giving these values:
+==========================+===============+
| Media Type | Quality Value |
+==========================+===============+
| text/plain;format=flowed | 1 |
+--------------------------+---------------+
| text/plain | 0.7 |
+--------------------------+---------------+
| text/html | 0.3 |
+--------------------------+---------------+
| image/jpeg | 0.5 |
+--------------------------+---------------+
| text/plain;format=fixed | 0.4 |
+--------------------------+---------------+
| text/html;level=3 | 0.7 |
+--------------------------+---------------+
Table 5
๐จ Note: A user agent might come with a default set of quality values for certain media ranges ๐ but unless the user agent is a closed system that can't talk to other rendering agents, that default set ought to be configurable by the user.
12.5.2. Accept-Charset ๐ค
the Accept-Charset header field can be sent by a user agent to show its charset preferences for textual response content ๐ท it lets user agents that understand fancier or special-purpose charsets say so to an origin server that can represent info in those charsets. main character energy ๐
Accept-Charset = #( ( token / "*" ) [ weight ] )
charset names are defined in Section 8.3.2 ๐ a user agent MAY attach a quality value to each charset to show how much the user likes it, as defined in Section 12.4.2 โจ here's a little example:
Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
the special value *, if it shows up in the Accept-Charset field, matches every charset that isn't mentioned elsewhere in the field ๐ฆ
๐จ Note:Accept-Charsetis deprecated, bestie ๐ UTF-8 is basically everywhere now, and sending a long list of preferred charsets just wastes bandwidth, adds latency, and makes passive fingerprinting WAY too easy (Section 17.13). most general-purpose user agents don't sendAccept-Charsetunless they've been specifically configured to ๐
12.5.3. Accept-Encoding ๐๏ธ
the Accept-Encoding header field can be used to show preferences about using content codings (Section 8.4.1) ๐
when a user agent sends it in a request, Accept-Encoding tells the server which content codings are acceptable in a response ๐
when a server sends it in a response, Accept-Encoding tells you which content codings are preferred in the content of a later request to the same resource ๐ง
an "identity" token is used as a synonym for "no encoding", so you can say when no encoding is preferred ๐ซง
Accept-Encoding = #( codings [ weight ] )
codings = content-coding / "identity" / "*"
each codings value MAY be given a quality value (weight) for how much that encoding is loved, as defined in Section 12.4.2 ๐ the asterisk * in an Accept-Encoding field matches any available content coding that isn't explicitly listed in the field โญ
examples, because you know I love a good example ๐
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
so here's how a server decides if a content coding is acceptable for a given representation ๐
- if there's no
Accept-Encodingheader field in the request, the user agent is considered fine with ANY content coding ๐ฅฐ - if the representation has no content coding, it's acceptable by default, UNLESS the
Accept-Encodingheader field specifically excludes it by saying eitheridentity;q=0or*;q=0without a more specific entry foridentity๐ - if the representation's content coding is one of the codings listed in the
Accept-Encodingfield value, it's acceptable UNLESS it comes with a qvalue of 0. (As defined in Section 12.4.2, a qvalue of 0 means "not acceptable" ๐)
a representation could be encoded with multiple content codings ๐ฐ but most codings are just different ways to do the same job (like data compression). when you're picking between multiple codings with the same purpose, the acceptable content coding with the highest non-zero qvalue is the one that gets preferred ๐
an Accept-Encoding header field with an empty field value means the user agent doesn't want any content coding in the response ๐ซ and if a non-empty Accept-Encoding header field is in a request and NONE of the available representations for the response have a content coding that's listed as acceptable, the origin server SHOULD send a response without any content coding, unless the identity coding has been marked as unacceptable ๐
when the Accept-Encoding header field is in a response, it shows what content codings the resource was willing to accept in the associated request ๐ช it gets evaluated the same way as it would in a request โจ
just a heads up: this info is specific to the associated request ๐ the set of supported encodings might be different for other resources on the same server, and it could change over time or depend on other stuff about the request (like the request method) ๐ธ
servers that fail a request because of an unsupported content coding ought to respond with a 415 (Unsupported Media Type) status and include an Accept-Encoding header field in that response ๐ that way clients can tell content coding issues apart from media type issues ๐งฉ so, to avoid mixing those up, servers that fail a request with a 415 status for reasons unrelated to content codings MUST NOT include the Accept-Encoding header field ๐ซ
the most common use of Accept-Encoding is in responses with a 415 (Unsupported Media Type) status code, when a client was optimistically using a content coding ๐ญ but the header field can also tell clients which content codings are supported so they can optimize future interactions ๐ for example, a resource might include it in a 2xx (Successful) response when the request content was big enough to justify a compression coding but the client failed do so ๐๏ธ๐
12.5.4. Accept-Language
The "Accept-Language" header field can be used by user agents to indicate the set of natural languages that are preferred in the response. Language tags are defined in Section 8.5.1.
Accept-Language = #( language-range [ weight ] ) language-range = <language-range, see [RFC4647], Section 2.1>
Each language-range can be given an associated quality value representing an estimate of the user's preference for the languages specified by that range, as defined in Section 12.4.2. For example,
Accept-Language: da, en-gb;q=0.8, en;q=0.7
would mean: "I prefer Danish, but will accept British English and other types of English".
Note that some recipients treat the order in which language tags are listed as an indication of descending priority, particularly for tags that are assigned equal quality values (no value is the same as q=1). However, this behavior cannot be relied upon. For consistency and to maximize interoperability, many user agents assign each language tag a unique quality value while also listing them in order of decreasing quality. Additional discussion of language priority lists can be found in Section 2.3 of [RFC4647].
For matching, Section 3 of [RFC4647] defines several matching schemes. Implementations can offer the most appropriate matching scheme for their requirements. The "Basic Filtering" scheme ([RFC4647], Section 3.3.1) is identical to the matching scheme that was previously defined for HTTP in Section 14.4 of [RFC2616].
It might be contrary to the privacy expectations of the user to send an Accept-Language header field with the complete linguistic preferences of the user in every request (Section 17.13).
Since intelligibility is highly dependent on the individual user, user agents need to allow user control over the linguistic preference (either through configuration of the user agent itself or by defaulting to a user controllable system setting). A user agent that does not provide such control to the user MUST NOT send an Accept- Language header field.
| Note: User agents ought to provide guidance to users when |
|---|
| setting a preference, since users are rarely familiar with the |
| details of language matching as described above. For example, |
| users might assume that on selecting "en-gb", they will be |
| served any kind of English document if British English is not |
| available. A user agent might suggest, in such a case, to add |
| "en" to the list for better matching behavior. |
12.5.5. Vary
The "Vary" header field in a response describes what parts of a request message, aside from the method and target URI, might have influenced the origin server's process for selecting the content of this response.
Vary = #( "*" / field-name )
A Vary field value is either the wildcard member "*" or a list of request field names, known as the selecting header fields, that might have had a role in selecting the representation for this response. Potential selecting header fields are not limited to fields defined by this specification.
A list containing the member "" signals that other aspects of the request might have played a role in selecting the response representation, possibly including aspects outside the message syntax (e.g., the client's network address). A recipient will not be able to determine whether this response is appropriate for a later request without forwarding the request to the origin server. A proxy MUST NOT generate "" in a Vary field value.
For example, a response that contains
Vary: accept-encoding, accept-language
indicates that the origin server might have used the request's Accept-Encoding and Accept-Language header fields (or lack thereof) as determining factors while choosing the content for this response.
A Vary field containing a list of field names has two purposes:
- To inform cache recipients that they MUST NOT use this response to satisfy a later request unless the later request has the same values for the listed header fields as the original request (Section 4.1 of [CACHING]) or reuse of the response has been validated by the origin server. In other words, Vary expands the cache key required to match a new request to the stored cache entry.
- To inform user agent recipients that this response was subject to content negotiation (Section 12) and a different representation might be sent in a subsequent request if other values are provided in the listed header fields (proactive negotiation).
An origin server SHOULD generate a Vary header field on a cacheable response when it wishes that response to be selectively reused for subsequent requests. Generally, that is the case when the response content has been tailored to better fit the preferences expressed by those selecting header fields, such as when an origin server has selected the response's language based on the request's Accept-Language header field.
Vary might be elided when an origin server considers variance in content selection to be less significant than Vary's performance impact on caching, particularly when reuse is already limited by cache response directives (Section 5.2 of [CACHING]).
There is no need to send the Authorization field name in Vary because reuse of that response for a different user is prohibited by the field definition (Section 11.6.2). Likewise, if the response content has been selected or influenced by network region, but the origin server wants the cached response to be reused even if recipients move from one region to another, then there is no need for the origin server to indicate such variance in Vary.
13. Conditional Requests โจ
okay bestie, so a conditional request is an HTTP request with one or more header fields that basically say "only do this IF this precondition checks out first" ๐ Section 13.2 is where you find out when to check preconditions and what order to check them in if there's more than one ๐
Conditional GET requests are the most efficient mechanism for HTTP cache updates [CACHING] ๐ฆ And conditionals can also be used on state-changing methods like PUT and DELETE ๐ This stops the "lost update" problem, which is when one client accidentally overwrites the work of another client that was doing stuff at the same time ๐ญ like the ultimate group project disaster ๐
13.1. Preconditions ๐ธ
okay so preconditions are usually defined based on the state of the target resource as a whole (its current set of values) OR the state as seen in a representation you got earlier (one value from that set) ๐ง If a resource has multiple current representations, each with its own observable state, a precondition will assume that mapping each request to a selected representation (Section 3.2) stays consistent over time โจ Regardless, if the mapping is inconsistent or the server can't select an appropriate representation, then no harm will result when the precondition evaluates to false ๐ซถ
Each precondition below compares a set of validators from earlier representations of the target resource to the current validators for the selected representation (Section 8.8) ๐ So basically these preconditions check whether the resource has changed since the state your client last knew about ๐ What happens after that check depends on the method semantics and the choice of conditional, as defined in Section 13.2 ๐ฅ
Other preconditions, defined by other specs as extension fields, might put conditions on all recipients, on the state of the target resource in general, or on a group of resources ๐ For example, the "If" header field in WebDAV can make a request conditional on lots of different aspects of multiple resources, like locks, if the recipient understands and implements that field ([WEBDAV], Section 10.4) ๐ฆ
Extensibility of preconditions is only possible when the precondition can be safely ignored if unknown (like If-Modified-Since), when deployment can be assumed for a given use case, or when implementation is signaled by some other property of the target resource ๐ This encourages a focus on mutually agreed deployment of common standards ๐ซถโจ
13.1.1. If-Match โจ
okay so the If-Match header field makes the request method conditional on the recipient origin server either having at least one current representation of the target resource, when the field value is "*", or having a current representation of the target resource that has an entity tag matching a member of the list of entity tags provided in the field value. ๐
An origin server MUST use the strong comparison function when comparing entity tags for If-Match (Section 8.8.3.2), since the client intends this precondition to prevent the method from being applied if there have been any changes to the representation data. this is the strict bestie check ๐
If-Match = "*" / #entity-tag
Examples:
If-Match: "xyzzy"
If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-Match: *
If-Match is most often used with state-changing methods (e.g., POST, PUT, DELETE) to prevent accidental overwrites when multiple user agents might be acting in parallel on the same resource (i.e., to prevent the "lost update" problem). ๐ซถ In general, it can be used with any method that involves the selection or modification of a representation, to abort the request if the selected representation's current entity tag is not a member within the If-Match field value. no more messy overwrites, periodt ๐
โโ๏ธ
When an origin server receives a request that selects a representation and that request includes an If-Match header field, the origin server MUST evaluate the If-Match condition per Section 13.2 prior to performing the method.
To evaluate a received If-Match header field:
- If the field value is
"*", the condition is true if the origin server has a current representation for the target resource. - If the field value is a list of entity tags, the condition is true if any of the listed tags match the entity tag of the selected representation.
- Otherwise, the condition is false.
An origin server that evaluates an If-Match condition MUST NOT perform the requested method if the condition evaluates to false. Instead, the origin server MAY indicate that the conditional request failed by responding with a 412 (Precondition Failed) status code. Alternatively, if the request is a state-changing operation that appears to have already been applied to the selected representation, the origin server MAY respond with a 2xx (Successful) status code (i.e., the change requested by the user agent has already succeeded, but the user agent might not be aware of it, perhaps because the prior response was lost or an equivalent change was made by some other user agent). ๐
Allowing an origin server to send a success response when a change request appears to have already been applied is more efficient for many authoring use cases, but comes with some risk if multiple user agents are making change requests that are very similar but not cooperative. ngl this is a lot of nuance ๐ฅน For example, multiple user agents writing to a common resource as a semaphore (e.g., a nonatomic increment) are likely to collide and potentially lose important state transitions. For those kinds of resources, an origin server is better off being stringent in sending 412 for every failed precondition on an unsafe method. In other cases, excluding the ETag field from a success response might encourage the user agent to perform a GET as its next request to eliminate confusion about the resource's current state. ๐ง
A client MAY send an If-Match header field in a GET request to indicate that it would prefer a 412 (Precondition Failed) response if the selected representation does not match. However, this is only useful in range requests (Section 14) for completing a previously received partial representation when there is no desire for a new representation. If-Range (Section 13.1.5) is better suited for range requests when the client prefers to receive a new representation. ๐ฆ
A cache or intermediary MAY ignore If-Match because its interoperability features are only necessary for an origin server. ๐
Note that anIf-Matchheader field with a list value containing"*"and other values (including other instances of"*") is syntactically invalid (therefore not allowed to be generated) and furthermore is unlikely to be interoperable. ๐ซ
13.1.2. If-None-Match ๐ฆ
the If-None-Match header field makes the request method conditional on a recipient cache or origin server either not having any current representation of the target resource, when the field value is "*", or having a selected representation with an entity tag that does not match any of those listed in the field value. ๐
A recipient MUST use the weak comparison function when comparing entity tags for If-None-Match (Section 8.8.3.2), since weak entity tags can be used for cache validation even if there have been changes to the representation data. โจ basically the chill comparison for this one ๐
If-None-Match = "*" / #entity-tag
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: *
If-None-Match is primarily used in conditional GET requests to enable efficient updates of cached information with a minimum amount of transaction overhead. When a client desires to update one or more stored responses that have entity tags, the client SHOULD generate an If-None-Match header field containing a list of those entity tags when making a GET request. This allows recipient servers to send a 304 (Not Modified) response to indicate when one of those stored responses matches the selected representation. ๐
If-None-Match can also be used with a value of "*" to prevent an unsafe request method (e.g., PUT) from inadvertently modifying an existing representation of the target resource when the client believes that the resource does not have a current representation (Section 9.2.1). This is a variation on the "lost update" problem that might arise if more than one client attempts to create an initial representation for the target resource. ๐
When an origin server receives a request that selects a representation and that request includes an If-None-Match header field, the origin server MUST evaluate the If-None-Match condition per Section 13.2 prior to performing the method.
To evaluate a received If-None-Match header field:
- If the field value is
"*", the condition is false if the origin server has a current representation for the target resource. - If the field value is a list of entity tags, the condition is false if one of the listed tags matches the entity tag of the selected representation.
- Otherwise, the condition is true.
An origin server that evaluates an If-None-Match condition MUST NOT perform the requested method if the condition evaluates to false. Instead, the origin server MUST respond with either a) the 304 (Not Modified) status code if the request method is GET or HEAD or b) the 412 (Precondition Failed) status code for all other request methods. ๐
Requirements on cache handling of a received If-None-Match header field are defined in Section 4.3.2 of [CACHING]. ๐๏ธ
Note that anIf-None-Matchheader field with a list value containing"*"and other values (including other instances of"*") is syntactically invalid (therefore not allowed to be generated) and furthermore is unlikely to be interoperable. ๐ซ
13.1.3. If-Modified-Since ๐ธ
the If-Modified-Since header field makes a GET or HEAD request method conditional on the selected representation's modification date being more recent than the date provided in the field value. Transfer of the selected representation's data is avoided if that data has not changed. it's giving "don't resend what they already have" ๐
If-Modified-Since = HTTP-date
An example of the field is:
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
A recipient MUST ignore If-Modified-Since if the request contains an If-None-Match header field. The condition in If-None-Match is considered to be a more accurate replacement for the condition in If-Modified-Since, and the two are only combined for the sake of interoperating with older intermediaries that might not implement If-None-Match. ๐งธ
A recipient MUST ignore the If-Modified-Since header field if the received field value is not a valid HTTP-date, the field value has more than one member, or if the request method is neither GET nor HEAD.
A recipient MUST ignore the If-Modified-Since header field if the resource does not have a modification date available.
A recipient MUST interpret an If-Modified-Since field value's timestamp in terms of the origin server's clock. โฐ
If-Modified-Since is typically used for two distinct purposes: 1) to allow efficient updates of a cached representation that does not have an entity tag and 2) to limit the scope of a web traversal to resources that have recently changed. two jobs, one header, iconic ๐ฏโโ๏ธ
When used for cache updates, a cache will typically use the value of the cached message's Last-Modified header field to generate the field value of If-Modified-Since. This behavior is most interoperable for cases where clocks are poorly synchronized or when the server has chosen to only honor exact timestamp matches (due to a problem with Last-Modified dates that appear to go "back in time" when the origin server's clock is corrected or a representation is restored from an archived backup). However, caches occasionally generate the field value based on other data, such as the Date header field of the cached message or the clock time at which the message was received, particularly when the cached message does not contain a Last-Modified header field. ๐ฐ๏ธ
When used for limiting the scope of retrieval to a recent time window, a user agent will generate an If-Modified-Since field value based on either its own clock or a Date header field received from the server in a prior response. Origin servers that choose an exact timestamp match based on the selected representation's Last-Modified header field will not be able to help the user agent limit its data transfers to only those changed during the specified window. ๐ช
When an origin server receives a request that selects a representation and that request includes an If-Modified-Since header field without an If-None-Match header field, the origin server SHOULD evaluate the If-Modified-Since condition per Section 13.2 prior to performing the method.
To evaluate a received If-Modified-Since header field:
- If the selected representation's last modification date is earlier or equal to the date provided in the field value, the condition is false.
- Otherwise, the condition is true.
An origin server that evaluates an If-Modified-Since condition SHOULD NOT perform the requested method if the condition evaluates to false. Instead, the origin server SHOULD generate a 304 (Not Modified) response, including only those metadata that are useful for identifying or updating a previously cached response. ๐ญ
Requirements on cache handling of a received If-Modified-Since header field are defined in Section 4.3.2 of [CACHING]. ๐
13.1.4. If-Unmodified-Since โจ
okay so the If-Unmodified-Since header field makes the request method conditional on the selected representation's last modification date being earlier than or equal to the date in the field value ๐ฐ๏ธ it's basically If-Match's cousin ๐ and it shows up when the user agent doesn't have an entity tag for the representation ๐ฆ
If-Unmodified-Since = HTTP-date
an example looks like this ๐ธ
If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
ok so, a recipient MUST ignore If-Unmodified-Since if the request has an If-Match header field ๐ If-Match is the more accurate version of this check, so the two only get combined so they can play nicely with older intermediaries that might not understand If-Match yet ๐ซถ
a recipient MUST ignore the If-Unmodified-Since header field if the field value isn't a valid HTTP-date, and that includes when it looks like a list of dates ๐
a recipient MUST ignore the If-Unmodified-Since header field if the resource doesn't have a modification date available ๐
a recipient MUST interpret the timestamp in an If-Unmodified-Since field value using the origin server's clock โฐ
If-Unmodified-Since is mostly used with state-changing methods (like POST, PUT, and DELETE) ๐ฅ it stops accidental overwrites when several user agents might be working on the same resource at once, especially when the resource doesn't give its representations entity tags. This is how you dodge the "lost update" problem ๐ญ In general, it can go with any method that selects or modifies a representation, so the request gets aborted if the selected representation's last modification date has changed since the date in the If-Unmodified-Since field value ๐
when an origin server gets a request that selects a representation and that request has an If-Unmodified-Since header field but no If-Match header field, the origin server MUST evaluate the If-Unmodified-Since condition per Section 13.2 before performing the method ๐
to evaluate a received If-Unmodified-Since header field:
- If the selected representation's last modification date is earlier than or equal to the date provided in the field value, the condition is true.
- Otherwise, the condition is false.
an origin server that evaluates an If-Unmodified-Since condition MUST NOT perform the requested method if the condition evaluates to false ๐ โโ๏ธ instead, the origin server MAY indicate that the conditional request failed by responding with a 412 (Precondition Failed) status code. Or, if the request is a state-changing operation that already seems to have been applied to the selected representation, the origin server MAY respond with a 2xx (Successful) status code. That means the change the user agent asked for already succeeded, even if the user agent doesn't know it ๐ฅน maybe the earlier response got lost, or some other user agent made an equivalent change
letting an origin server send a success response when a change request already seems applied is way more efficient for lots of authoring use cases ๐ but it's risky if multiple user agents are sending change requests that are super similar but not cooperative ๐ in those cases the origin server is better off being strict and sending 412 for every failed precondition on an unsafe method ๐ซก
a client MAY send an If-Unmodified-Since header field in a GET request to say it would prefer a 412 (Precondition Failed) response if the selected representation has been modified ๐ง but honestly this is only useful in range requests (Section 14) for finishing a partial representation the client already received, when it doesn't want a new representation. If-Range (Section 13.1.5) is the better pick for range requests when the client wants a new representation ๐
a cache or intermediary MAY ignore If-Unmodified-Since, because its interoperability features are only needed for an origin server ๐งธ
13.1.5. If-Range
the If-Range header field is a special conditional request mechanism ๐ฆ it's similar to If-Match and If-Unmodified-Since, but it tells the recipient to ignore the Range header field if the validator doesn't match. That way the new selected representation gets sent instead of a 412 (Precondition Failed) response โจ
here's the situation ๐ฅบ if a client has a partial copy of a representation and wants an up-to-date copy of the whole thing, it could use the Range header field with a conditional GET (using either or both of If-Unmodified-Since and If-Match). But if the precondition fails because the representation changed, the client would then have to make a second request to get the entire current representation ๐ฉ
the If-Range header field lets the client "short-circuit" that second request ๐โโ๏ธ informally, it means: if the representation hasn't changed, send me the part(s) I asked for in Range; otherwise, send me the entire representation ๐
If-Range = entity-tag / HTTP-date
you can tell a valid entity-tag from a valid HTTP-date by checking whether the first three characters include a DQUOTE ๐
a client MUST NOT generate an If-Range header field in a request that doesn't contain a Range header field ๐ซ a server MUST ignore an If-Range header field received in a request that doesn't contain a Range header field. An origin server MUST ignore an If-Range header field received in a request for a target resource that doesn't support Range requests ๐
a client MUST NOT generate an If-Range header field containing an entity tag that is marked as weak ๐ a client MUST NOT generate an If-Range header field containing an HTTP-date unless the client has no entity tag for the corresponding representation AND the date is a strong validator in the sense defined by Section 8.8.2.2 โ ๏ธ
a server that receives an If-Range header field on a Range request MUST evaluate the condition per Section 13.2 before performing the method ๐ซถ
to evaluate a received If-Range header field containing an HTTP-date:
- If the HTTP-date validator provided is not a strong validator in the sense defined by Section 8.8.2.2, the condition is false.
- If the HTTP-date validator provided exactly matches the Last-Modified field value for the selected representation, the condition is true.
- Otherwise, the condition is false.
to evaluate a received If-Range header field containing an entity-tag:
- If the entity-tag validator provided exactly matches the ETag field value for the selected representation using the strong comparison function (Section 8.8.3.2), the condition is true.
- Otherwise, the condition is false.
a recipient of an If-Range header field MUST ignore the Range header field if the If-Range condition evaluates to false ๐ otherwise, the recipient SHOULD process the Range header field as requested ๐
quick reminder bestie ๐ฃ the If-Range comparison is an exact match, even when the validator is an HTTP-date. That makes it different from the "earlier than or equal to" comparison used for an If-Unmodified-Since conditional ๐ โจ
13.2. Evaluation of Preconditions
13.2.1. When to Evaluate
except when excluded below, a recipient cache or origin server MUST evaluate received request preconditions after it has successfully done its normal request checks, and just before it would process the request content (if there is any) or perform the action tied to the request method โณ a server MUST ignore all received preconditions if its response to the same request without those conditions, before processing the request content, would have been a status code other than a 2xx (Successful) or 412 (Precondition Failed). Basically, redirects and failures that can be spotted before any big processing happens take priority over evaluating preconditions ๐
a server that is not the origin server for the target resource and can't act as a cache for requests on that target resource MUST NOT evaluate the conditional request header fields defined by this specification ๐ โโ๏ธ and it MUST forward them if the request gets forwarded, since the generating client wants a server that can provide a current representation to evaluate them ๐ธ likewise, a server MUST ignore the conditional request header fields defined by this specification when they come with a request method that doesn't involve selecting or modifying a selected representation, like CONNECT, OPTIONS, or TRACE ๐ง
protocol extensions can change the conditions under which preconditions get evaluated, or what happens when they are evaluated ๐ for example, the immutable cache directive (defined by [RFC8246]) tells caches to skip forwarding conditional requests when they hold a fresh response ๐ฆ
even though conditional request header fields can be used with the HEAD method (so HEAD's semantics match GET's), there's no point in sending a conditional HEAD ๐ a successful response is around the same size as a 304 (Not Modified) response, and it's way more useful than a 412 (Precondition Failed) response ๐
13.2.2. Precedence of Preconditions โจ
okay so what happens when a request shows up with, like, more than one conditional header field? ๐ The ORDER they get checked in suddenly matters SO much bestie ๐ญ The fields defined in this doc are consistently implemented in one single logical order (it's giving organization ๐ ). The reasoning is that "lost update" preconditions have stricter requirements than cache validation, a validated cache is more efficient than a partial response, and entity tags are presumed to be more accurate than date validators. So the lost-update stuff goes first, then the cache checks, then the partial responses ๐ซถ
A recipient cache or origin server MUST evaluate the request preconditions defined by this specification in the following order:
- When recipient is the origin server and If-Match is present, evaluate the If-Match precondition:
- if true, continue to step 3
- if false, respond 412 (Precondition Failed) unless it can be determined that the state-changing request has already succeeded (see Section 13.1.1)
- When recipient is the origin server, If-Match is not present, and If-Unmodified-Since is present, evaluate the If-Unmodified-Since precondition:
- if true, continue to step 3
- if false, respond 412 (Precondition Failed) unless it can be determined that the state-changing request has already succeeded (see Section 13.1.4)
- When If-None-Match is present, evaluate the If-None-Match precondition:
- if true, continue to step 5
- if false for GET/HEAD, respond 304 (Not Modified)
- if false for other methods, respond 412 (Precondition Failed)
- When the method is GET or HEAD, If-None-Match is not present, and If-Modified-Since is present, evaluate the If-Modified-Since precondition:
- if true, continue to step 5
- if false, respond 304 (Not Modified)
- When the method is GET and both Range and If-Range are present, evaluate the If-Range precondition:
- if true and the Range is applicable to the selected representation, respond 206 (Partial Content)
- otherwise, ignore the Range header field and respond 200 (OK)
- Otherwise,
- perform the requested method and respond according to its success or failure.
Any extension to HTTP that defines additional conditional request header fields ought to define the order for evaluating such fields in relation to those defined in this document and other conditionals that might be found in practice. ๐ง Future extensions, take note! ๐
14. Range Requests โจ
Clients often encounter interrupted data transfers as a result of canceled requests or dropped connections ๐ฉ When a client has stored a partial representation, it is desirable to request the remainder of that representation in a subsequent request rather than transfer the entire representation. Likewise, devices with limited local storage might benefit from being able to request only a subset of a larger representation, such as a single page of a very large document, or the dimensions of an embedded image ๐ผ๏ธ
Range requests are an OPTIONAL feature of HTTP, designed so that recipients not implementing this feature (or not supporting it for the target resource) can respond as if it is a normal GET request without impacting interoperability ๐ฆ Partial responses are indicated by a distinct status code so they are not mistaken for full responses by caches that might not implement the feature. The whole design is so considerate, I'm obsessed ๐ฅน
14.1. Range Units
Representation data can be partitioned into subranges when there are addressable structural units inherent to that data's content coding or media type. For example, octet (a.k.a. byte) boundaries are a structural unit common to all representation data, allowing partitions of the data to be identified as a range of bytes at some offset from the start or end of that data ๐
This general notion of a "range unit" is used in the Accept-Ranges (Section 14.3) response header field to advertise support for range requests, the Range (Section 14.2) request header field to delineate the parts of a representation that are requested, and the Content-Range (Section 14.4) header field to describe which part of a representation is being transferred ๐ฆ
range-unit = token
All range unit names are case-insensitive and ought to be registered within the "HTTP Range Unit Registry", as defined in Section 16.5.1. ๐๏ธ
Range units are intended to be extensible, as described in Section 16.5. โจ
14.1.1. Range Specifiers
Ranges are expressed in terms of a range unit paired with a set of range specifiers. The range unit name determines what kinds of range-spec are applicable to its own specifiers. Hence, the following grammar is generic: each range unit is expected to specify requirements on when int-range, suffix-range, and other-range are allowed. It's giving flexible ๐
A range request can specify a single range or a set of ranges within a single representation.
ranges-specifier = range-unit "=" range-set
range-set = 1#range-spec
range-spec = int-range
/ suffix-range
/ other-range
An int-range is a range expressed as two non-negative integers or as one non-negative integer through to the end of the representation data. The range unit specifies what the integers mean (e.g., they might indicate unit offsets from the beginning, inclusive numbered parts, etc.) ๐ข
int-range = first-pos "-" [ last-pos ]
first-pos = 1*DIGIT
last-pos = 1*DIGIT
An int-range is invalid if the last-pos value is present and less than the first-pos. ๐ซ
A suffix-range is a range expressed as a suffix of the representation data with the provided non-negative integer maximum length (in range units). In other words, the last N units of the representation data. ๐
suffix-range = "-" suffix-length
suffix-length = 1*DIGIT
To provide for extensibility, the other-range rule is a mostly unconstrained grammar that allows application-specific or future range units to define additional range specifiers ๐
other-range = 1*( %x21-2B / %x2D-7E )
; 1*(VCHAR excluding comma)
A ranges-specifier is invalid if it contains any range-spec that is invalid or undefined for the indicated range-unit. ๐
A valid ranges-specifier is "satisfiable" if it contains at least one range-spec that is satisfiable, as defined by the indicated range-unit. Otherwise, the ranges-specifier is "unsatisfiable". ๐ Big "rip" energy for the unsatisfiable ones.
14.1.2. Byte Ranges
The "bytes" range unit is used to express subranges of a representation data's octet sequence. Each byte range is expressed as an integer range at some offset, relative to either the beginning (int-range) or end (suffix-range) of the representation data. Byte ranges do not use the other-range specifier. ๐ง
The first-pos value in a bytes int-range gives the offset of the first byte in a range. The last-pos value gives the offset of the last byte in the range; that is, the byte positions specified are inclusive. Byte offsets start at zero. Zero-indexed era, no cap ๐ค
If the representation data has a content coding applied, each byte range is calculated with respect to the encoded sequence of bytes, not the sequence of underlying bytes that would be obtained after decoding. ๐
Examples of bytes range specifiers:
- The first 500 bytes (byte offsets 0-499, inclusive):
bytes=0-499
- The second 500 bytes (byte offsets 500-999, inclusive):
bytes=500-999
A client can limit the number of bytes requested without knowing the size of the selected representation. If the last-pos value is absent, or if the value is greater than or equal to the current length of the representation data, the byte range is interpreted as the remainder of the representation (i.e., the server replaces the value of last-pos with a value that is one less than the current length of the selected representation). ๐ซถ Lowkey the best feature ever.
A client can refer to the last N bytes (N > 0) of the selected representation using a suffix-range. If the selected representation is shorter than the specified suffix-length, the entire representation is used. ๐ธ
Additional examples, assuming a representation of length 10000:
- 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
- The first, middle, and last 1000 bytes:
bytes= 0-999, 4500-5499, -1000
- Other valid (but not canonical) specifications of the second 500 bytes (byte offsets 500-999, inclusive):
bytes=500-600,601-999
bytes=500-700,601-999
For a GET request, a valid bytes range-spec is satisfiable if it is either:
- an int-range with a first-pos that is less than the current length of the selected representation or
- a suffix-range with a non-zero suffix-length.
When a selected representation has zero length, the only satisfiable form of range-spec in a GET request is a suffix-range with a non-zero suffix-length. ๐ซ
In the byte-range syntax, first-pos, last-pos, and suffix-length are expressed as decimal number of octets. Since there is no predefined limit to the length of content, recipients MUST anticipate potentially large decimal numerals and prevent parsing errors due to integer conversion overflows. ๐ข๐ฅ Big numbers deserve big respect, bestie ๐
14.2. Range ๐
okay so the "Range" header field ๐ is what a GET request uses to ask for only a piece (or a few pieces) of the selected representation data (Section 8.1), instead of the whole thing. it's giving "send me just the good part" ๐ฆ
Range = ranges-specifier
A server MAY ignore the Range header field. ๐ still, origin servers and intermediate caches ought to support byte ranges when they can, since byte ranges make it efficient to recover from transfers that partially failed and to grab just a chunk of a huge representation. โจ
A server MUST ignore a Range header field it gets with a request method it doesn't recognize, or with one that has no range handling defined. ๐ For this spec, GET is the only method with range handling defined, so that's the only one that gets to play. ๐
An origin server MUST ignore a Range header field that has a range unit it doesn't understand. ๐ญ A proxy MAY throw away a Range header field with a range unit it doesn't understand. ๐ง
A server that supports range requests MAY ignore or reject a Range header field in any of these situations: the ranges-specifier is invalid (Section 14.1.1), it has more than two overlapping ranges, or it's a pile of tiny ranges that aren't in ascending order. ๐ these are signs of either a broken client or a deliberate denial-of-service attack (Section 17.15), so the server is allowed to say "nope" ๐ซ. A client SHOULD NOT request multiple ranges that are inherently less efficient to process and transfer than one single range covering the same data. ๐ซถ
A server that supports range requests MAY ignore a Range header field when the selected representation has no content (i.e., the selected representation's data is of zero length). ๐ธ
A client asking for multiple ranges SHOULD list them in ascending order (the order they'd usually show up in a complete representation) unless there's a specific reason to ask for a later part first. ๐ for example, a user agent working through a big representation with an internal catalog of parts might need to grab later parts first, especially when the representation is pages stored in reverse order and the user agent wants to transfer one page at a time. that's a whole vibe ๐
The Range header field gets evaluated after the precondition header fields from Section 13.1 have been evaluated, and only if the result without the Range header field would be a 200 (OK) response. ๐ in other words, Range is ignored when a conditional GET would end up as a 304 (Not Modified) response. ๐
The If-Range header field (Section 13.1.5) can be used as a precondition for applying the Range header field. ๐ฅ
If all of the preconditions are true, the server supports the Range header field for the target resource, the received Range field-value contains a valid ranges-specifier with a range-unit supported for that target resource, and that ranges-specifier is satisfiable with respect to the selected representation, then the server SHOULD send a 206 (Partial Content) response. ๐ the content in that response has one or more partial representations that match the satisfiable range-spec(s) that were requested. โจ
The above does not mean a server will send every requested range. ๐ sometimes it can only manage (or only do efficiently) a portion of the ranges first, and then it expects the client to re-request the rest later if they're still wanted (see Section 15.3.7). ๐
If all of the preconditions are true, the server supports the Range header field for the target resource, the received Range field-value contains a valid ranges-specifier, and either the range-unit isn't supported for that target resource or the ranges-specifier is unsatisfiable with respect to the selected representation, then the server SHOULD send a 416 (Range Not Satisfiable) response. ๐ not it, bestie.
14.3. Accept-Ranges ๐ฆ
the "Accept-Ranges" field in a response tells you whether an upstream server supports range requests for the target resource. ๐
Accept-Ranges = acceptable-ranges
acceptable-ranges = 1#range-unit
for example, a server that supports byte-range requests (Section 14.1.2) can send this field:
Accept-Ranges: bytes
which says it supports byte range requests for that target resource, and basically encourages the client to keep using them for future partial requests on the same request path. ๐ง range units are defined in Section 14.1. โจ
A client MAY generate range requests even if it hasn't received an Accept-Ranges field. ๐ the info is just advice, there to improve performance and cut down on unnecessary network transfers. ๐ซถ
but the other way around is a big no. ๐ซ a client MUST NOT assume that getting an Accept-Ranges field means future range requests will return partial responses. ๐ญ the content might change, the server might only do range requests at certain times or under certain conditions, or a different intermediary might handle the next request. chaos, I know ๐
A server that doesn't support any kind of range request for the target resource MAY send this:
Accept-Ranges: none
to tell the client not to bother trying a range request on the same request path. ๐ โโ๏ธ the range unit "none" is reserved for exactly this purpose. ๐
The Accept-Ranges field MAY be sent in a trailer section, but it's preferred as a header field, because the info is especially useful for restarting large transfers that failed partway through the content (before the trailer section gets received). ๐
14.4. Content-Range ๐ธ
the "Content-Range" header field gets sent in a single-part 206 (Partial Content) response to say which partial range of the selected representation is enclosed as the message content. ๐ it's also sent in each part of a multipart 206 response to show the range inside each body part (Section 14.6), and in 416 (Range Not Satisfiable) responses to give info about the selected representation. ๐ฅ
Content-Range = range-unit SP
( range-resp / unsatisfied-range )
range-resp = incl-range "/" ( complete-length / "*" )
incl-range = first-pos "-" last-pos
unsatisfied-range = "*/" complete-length
complete-length = 1*DIGIT
if a 206 (Partial Content) response has a Content-Range header field with a range unit (Section 14.1) that the recipient doesn't understand, the recipient MUST NOT try to recombine it with a stored representation. ๐ โโ๏ธ a proxy that gets a message like that SHOULD forward it downstream. ๐ง
Content-Range might also be sent as a request modifier to ask for a partial PUT, as described in Section 14.5, based on private agreements between the client and origin server. ๐คซ a server MUST ignore a Content-Range header field received in a request with a method that doesn't define Content-Range support. ๐
for byte ranges, a sender SHOULD indicate the complete length of the representation the range came from, unless that complete length is unknown or hard to figure out. ๐ฆ an asterisk character ("*") in place of the complete-length means the representation length was unknown when the header field got generated. ๐
here's an example for when the sender knows the complete length of the selected representation is 1234 bytes:
Content-Range: bytes 42-1233/1234
and this second one is for when the complete length is unknown:
Content-Range: bytes 42-1233/*
a Content-Range field value is invalid if it has a range-resp where the last-pos value is less than its first-pos value, or a complete-length value that's less than or equal to its last-pos value. ๐ the recipient of an invalid Content-Range MUST NOT try to recombine the received content with a stored representation. ๐ซ
a server generating a 416 (Range Not Satisfiable) response to a byte-range request SHOULD send a Content-Range header field with an unsatisfied-range value, like in this example:
Content-Range: bytes */1234
the complete-length in a 416 response tells you the current length of the selected representation. โจ
The Content-Range header field has no meaning for status codes that don't explicitly describe its semantics. ๐ for this spec, only the 206 (Partial Content) and 416 (Range Not Satisfiable) status codes give Content-Range a meaning. ๐
these are examples of Content-Range values where the selected representation has 1234 bytes total: ๐
- The first 500 bytes:
Content-Range: bytes 0-499/1234
- The second 500 bytes:
Content-Range: bytes 500-999/1234
- All except for the first 500 bytes:
Content-Range: bytes 500-1233/1234
- The last 500 bytes:
Content-Range: bytes 734-1233/1234
14.5. Partial PUT ๐ง
some origin servers support PUT of a partial representation when the user agent sends a Content-Range header field (Section 14.4) in the request. ๐ซถ but that support is inconsistent and depends on private agreements with user agents, so it's a bit of a mixed bag. ๐ generally, it asks that the state of the target resource be partly replaced with the enclosed content, at an offset and length given by the Content-Range value, where the offset is relative to the current selected representation. ๐
An origin server SHOULD respond with a 400 (Bad Request) status code if it receives Content-Range on a PUT for a target resource that doesn't support partial PUT requests. ๐ญ
Partial PUT is not backwards compatible with the original definition of PUT. ๐ it might end up writing the content as a complete replacement for the current representation, so be careful out there ๐จ
partial resource updates are also possible by targeting a separately identified resource whose state overlaps or extends a portion of the larger resource, or by using a different method that's specifically defined for partial updates (for example, the PATCH method defined in [RFC5789]). ๐ธโจ
14.6. Media Type multipart/byteranges ๐
okay so when a 206 (Partial Content) response is carrying the content of multiple ranges, each range gets sent as its own body part inside a multipart message body ([RFC2046], Section 5.1). The media type for that is multipart/byteranges ๐
The multipart/byteranges media type holds one or more body parts, and every part has its own Content-Type and Content-Range fields ๐ง. There's a boundary parameter that is required, and it's the string that separates each body part from the next ๐ธ
Implementation Notes โจ
- Additional CRLFs might precede the first boundary string in the body.
- Although [RFC2046] lets the boundary string be quoted, some existing implementations mishandle a quoted boundary string ๐
- A bunch of clients and servers were coded against an early draft of the byteranges spec, which used a media type of
multipart/x-byteranges. That one is almost compatible with this type, but not quite ๐
Now, despite the name, multipart/byteranges isn't only for byte ranges! ๐ฆ Here's an example using an exampleunit range unit:
HTTP/1.1 206 Partial Content
Date: Tue, 14 Nov 1995 06:25:24 GMT
Last-Modified: Tue, 14 July 04:58:08 GMT
Content-Length: 2331785
Content-Type: multipart/byteranges; boundary=THIS_STRING_SEPARATES
--THIS_STRING_SEPARATES
Content-Type: video/example
Content-Range: exampleunit 1.2-4.3/25
...the first range...
--THIS_STRING_SEPARATES
Content-Type: video/example
Content-Range: exampleunit 11.2-14.3/25
...the second range
--THIS_STRING_SEPARATES--
The registration form for the multipart/byteranges media type is below, copied as-is ๐
Type name: multipart
Subtype name: byteranges
Required parameters: boundary
Optional parameters: N/A
Encoding considerations: only "7bit", "8bit", or "binary" are
permitted
Security considerations: see Section 17
Interoperability considerations: N/A
Published specification: RFC 9110 (see Section 14.6)
Applications that use this media type: HTTP components supporting
multiple ranges in a single request
Fragment identifier considerations: N/A
Additional information: Deprecated alias names for this type: N/A
Magic number(s): N/A
File extension(s): N/A
Macintosh file type code(s): N/A
Person and email address to contact for further information: See Aut
hors' Addresses section.
Intended usage: COMMON
Restrictions on usage: N/A
Author: See Authors' Addresses section.
Change controller: IESG
15. Status Codes โจ
The status code of a response is a three-digit integer code ๐ข that describes the result of the request and the semantics of the response. That includes whether the request was successful and what content is enclosed (if any) ๐ฆ All valid status codes are within the range of 100 to 599, inclusive ๐
The first digit of the status code defines the class of response ๐ The last two digits don't have any categorization role at all. There are five values for the first digit:
1xx(Informational): The request was received, continuing process2xx(Successful): The request was successfully received, understood, and accepted3xx(Redirection): Further action needs to be taken in order to complete the request4xx(Client Error): The request contains bad syntax or cannot be fulfilled5xx(Server Error): The server failed to fulfill an apparently valid request
HTTP status codes are extensible ๐ A client is not required to understand the meaning of all registered status codes, though such understanding is obviously desirable. However, a client MUST understand the class of any status code, as indicated by the first digit, and treat an unrecognized status code as being equivalent to the x00 status code of that class.
For example, if a client receives an unrecognized status code of 471, it can see from the first digit that something went wrong with its request, so it can treat the response as if it had received a 400 (Bad Request) status code. The response message will usually contain a representation that explains the status ๐ซถ
Values outside the range 100..599 are invalid. Implementations often use three-digit integer values outside of that range (i.e., 600..999) for internal communication of non-HTTP status (e.g., library errors) ๐ A client that receives a response with an invalid status code SHOULD process the response as if it had a 5xx (Server Error) status code.
A single request can have multiple associated responses: zero or more "interim" (non-final) responses with status codes in the "informational" (1xx) range, followed by exactly one "final" response with a status code in one of the other ranges โจ It's giving relay race ๐โโ๏ธ
15.1. Overview of Status Codes ๐ฆ
The status codes listed below are defined in this specification. The reason phrases listed here are only recommendations ๐ They can be replaced by local equivalents or left out altogether without affecting the protocol, so no stress!
Responses with status codes that are defined as heuristically cacheable (e.g., 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, and 501 in this specification) can be reused by a cache with heuristic expiration, unless otherwise indicated by the method definition or explicit cache controls [CACHING]. All other status codes are not heuristically cacheable ๐
Additional status codes, outside the scope of this specification, have been specified for use in HTTP. All such status codes ought to be registered within the "Hypertext Transfer Protocol (HTTP) Status Code Registry", as described in Section 16.2 ๐
15.2. Informational 1xx ๐ธ
The 1xx (Informational) class of status code indicates an interim response for communicating connection status or request progress. This happens prior to completing the requested action and sending a final response โญ Since HTTP/1.0 did not define any 1xx status codes, a server MUST NOT send a 1xx response to an HTTP/1.0 client ๐
โโ๏ธ
A 1xx response is terminated by the end of the header section, so it cannot contain content or trailers ๐
A client MUST be able to parse one or more 1xx responses received prior to a final response, even if the client doesn't expect one. A user agent MAY ignore unexpected 1xx responses ๐ง
A proxy MUST forward 1xx responses unless the proxy itself requested the generation of the 1xx response. For example, if a proxy adds an Expect: 100-continue header field when it forwards a request, then it need not forward the corresponding 100 (Continue) response(s) ๐
15.2.1. 100 Continue ๐
The 100 (Continue) status code indicates that the initial part of a request has been received and has not yet been rejected by the server ๐ซถ The server intends to send a final response after the request has been fully received and acted upon.
When the request contains an Expect header field that includes a 100-continue expectation, the 100 response indicates that the server wishes to receive the request content, as described in Section 10.1.1. The client ought to continue sending the request and discard the 100 response โจ
If the request did not contain an Expect header field containing the 100-continue expectation, the client can simply discard this interim response ๐
15.2.2. 101 Switching Protocols ๐ฆ
The 101 (Switching Protocols) status code indicates that the server understands and is willing to comply with the client's request, via the Upgrade header field (Section 7.8), for a change in the application protocol being used on this connection ๐ The server MUST generate an Upgrade header field in the response that indicates which protocol(s) will be in effect after this response.
It is assumed that the server will only agree to switch protocols when it's advantageous to do so ๐ For example, switching to a newer version of HTTP might be advantageous over older versions, and switching to a real-time, synchronous protocol might be advantageous when delivering resources that use such features ๐ฅ
15.3. Successful 2xx ๐
The 2xx (Successful) class of status code indicates that the client's request was successfully received, understood, and accepted โจ
15.3.1. 200 OK ๐
The 200 (OK) status code indicates that the request has succeeded ๐ The content sent in a 200 response depends on the request method. For the methods defined by this specification, the intended meaning of the content can be summarized as:
+================+============================================+
| Request Method | Response content is a representation of: |
+================+============================================+
| GET | the target resource |
+----------------+--------------------------------------------+
| HEAD | the target resource, like GET, but without |
| | transferring the representation data |
+----------------+--------------------------------------------+
| POST | the status of, or results obtained from, |
| | the action |
+----------------+--------------------------------------------+
| PUT, DELETE | the status of the action |
+----------------+--------------------------------------------+
| OPTIONS | communication options for the target |
| | resource |
+----------------+--------------------------------------------+
| TRACE | the request message as received by the |
| | server returning the trace |
+----------------+--------------------------------------------+
Table 6
Aside from responses to CONNECT, a 200 response is expected to contain message content, unless the message framing explicitly indicates that the content has zero length ๐ฆ If some aspect of the request indicates a preference for no content upon success, the origin server ought to send a 204 (No Content) response instead. For CONNECT, there is no content, because the successful result is a tunnel, which begins immediately after the 200 response header section ๐
A 200 response is heuristically cacheable; i.e., unless otherwise indicated by the method definition or explicit cache controls (see Section 4.2.2 of [CACHING]) ๐พ
In 200 responses to GET or HEAD, an origin server SHOULD send any available validator fields (Section 8.8) for the selected representation, with both a strong entity tag and a Last-Modified date being preferred ๐ท๏ธ
In 200 responses to state-changing methods, any validator fields (Section 8.8) sent in the response convey the current validators for the new representation formed as a result of successfully applying the request semantics. Note that the PUT method (Section 9.3.4) has additional requirements that might preclude sending such validators ๐
15.3.2. 201 Created โจ
okay bestie, so the 201 (Created) status code means the request got fulfilled AND it made one or more brand new resources ๐๐ธ literally a whole new thing exists now, iconic. The main resource that got created is pointed to either by a Location header field in the response or, if there isn't one, by the target URI. no cap, that's the whole vibe check ๐
The 201 response usually describes and links to whatever got created ๐ง Any validator fields (Section 8.8) sent back convey the current validators for the brand new representation the request made. ngl this is so cute ๐ฆ BUT the PUT method (Section 9.3.4) has extra requirements that might mean you can't send those validators at all, so not me being like "wait, the PUT rules are different" ๐ check Section 9.3.4 before you assume.
15.3.3. 202 Accepted ๐
okay so the 202 (Accepted) status code says the request got accepted for processing, but the processing is NOT finished yet ๐ญ The request might or might not eventually get acted upon, because it could be disallowed once processing actually happens. And there's no facility in HTTP for re-sending a status code from an asynchronous operation, so don't wait for a follow-up code to show up ๐
The 202 response is intentionally noncommittal, and honestly that's the whole point ๐ It lets a server accept a request for some other process (like a batch job that only runs once a day ๐) without making the user agent's connection stick around until the process is done. The representation sent with this response ought to describe the request's current status and point to (or embed) a status monitor that can give the user an estimate of when the request will be fulfilled โญ that's the glow-up ๐ซถ
15.3.4. 203 Non-Authoritative Information โจ
the 203 (Non-Authoritative Information) status code means the request was successful, but the enclosed content got modified from what the origin server's 200 (OK) response had, by a transforming proxy (Section 7.7) ๐ฆ This code lets the proxy tell recipients that a transformation happened, since that knowledge might change later decisions about the content. For example, future cache validation requests for the content might only apply along the same request path (through the same proxies) ๐ง
A 203 response is heuristically cacheable, i.e., unless the method definition or explicit cache controls say otherwise (see Section 4.2.2 of [CACHING]) ๐
15.3.5. 204 No Content ๐ธ
the 204 (No Content) status code says the server successfully fulfilled the request and there's no additional content to send in the response content ๐ Metadata in the response header fields refers to the target resource and its selected representation after the requested action got applied ๐ฅ
For example, if a 204 status code comes back from a PUT request and the response has an ETag field, then the PUT worked, and the ETag field value is the entity tag for the new representation of that target resource ๐ very aesthetic
The 204 response lets a server say the action got applied to the target resource, while implying the user agent doesn't need to leave its current "document view" (if it has one) ๐ The server assumes the user agent will show some kind of success indication to its user, following its own interface, and apply any new or updated metadata to its active representation ๐
For example, a 204 status code is commonly used with document editing interfaces for a "save" action, so the document being saved stays available for editing ๐ It's also frequently used with interfaces that expect automated data transfers to be prevalent, like in distributed version control systems ๐ค
A 204 response is terminated by the end of the header section; it cannot contain content or trailers. no content, no trailers, nothing ๐ โโ๏ธ
A 204 response is heuristically cacheable, i.e., unless the method definition or explicit cache controls say otherwise (see Section 4.2.2 of [CACHING]) ๐ฆ
15.3.6. 205 Reset Content ๐ง
the 205 (Reset Content) status code means the server fulfilled the request and wants the user agent to reset the "document view" that caused the request to be sent back to its original state as received from the origin server ๐ This is built for a super common data entry situation: the user gets content that supports data entry (a form, notepad, canvas, etc.), types or manipulates stuff in there, submits it in a request, and then the entry mechanism resets so they can easily start another input ๐
Since the 205 status code implies no additional content will be provided, a server MUST NOT generate content in a 205 response. ๐ซ no content allowed, bestie, seriously ๐ญ
15.3.7. 206 Partial Content ๐
the 206 (Partial Content) status code means the server is successfully fulfilling a range request for the target resource by transferring one or more parts of the selected representation โจ so it's giving "here's your piece, not the whole thing" ๐ฐ
A server that supports range requests (Section 14) will usually try to satisfy all of the requested ranges, since sending less data will likely lead to another client request for the rest ๐ BUT a server might want to send only a subset for its own reasons, like temporary unavailability, cache efficiency, load balancing, etc. ๐ซถ Since a 206 response is self-descriptive, the client can still understand a response that only partially satisfies its range request ๐ฆ
A client MUST inspect a 206 response's Content-Type and Content-Range field(s) to figure out what parts are enclosed and whether more requests are needed ๐ non-negotiable, bestie ๐
A server that generates a 206 response MUST generate the following header fields, in addition to the ones required in the subsections below, if the field would have been sent in a 200 (OK) response to the same request: Date, Cache-Control, ETag, Expires, Content-Location, and Vary ๐
A Content-Length header field in a 206 response shows the number of octets in the content of this message, which is usually NOT the complete length of the selected representation ๐ง Each Content-Range header field includes info about the selected representation's complete length ๐
A sender that generates a 206 response to a request with an If-Range header field SHOULD NOT generate other representation header fields beyond the ones required, because the client already has a prior response containing those header fields ๐ Otherwise, a sender MUST generate all of the representation header fields that would have been sent in a 200 (OK) response to the same request ๐
A 206 response is heuristically cacheable, i.e., unless explicit cache controls say otherwise (see Section 4.2.2 of [CACHING]) ๐ธ
15.3.7.1. Single Part ๐ฆ
if a single part is being transferred, the server generating the 206 response MUST generate a Content-Range header field describing what range of the selected representation is enclosed, plus content consisting of that range ๐ฏ 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
... 26012 bytes of partial image data ...
15.3.7.2. Multiple Parts ๐ง
if multiple parts are being transferred, the server generating the 206 response MUST generate "multipart/byteranges" content, as defined in Section 14.6, plus a Content-Type header field containing the "multipart/byteranges" media type and its required boundary parameter ๐ To avoid confusion with single-part responses, a server MUST NOT generate a Content-Range header field in the HTTP header section of a multiple part response (this field gets sent in each part instead) ๐ โโ๏ธ
Within the header area of each body part in the multipart content, the server MUST generate a Content-Range header field corresponding to the range being enclosed in that body part ๐ If the selected representation would have had a Content-Type header field in a 200 (OK) response, the server SHOULD generate that same Content-Type header field in the header area of each body part ๐ 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-Length: 1741
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--
When multiple ranges are requested, a server MAY coalesce any of the ranges that overlap, or that are separated by a gap smaller than the overhead of sending multiple parts, regardless of the order in which the corresponding range-spec appeared in the received Range header field ๐งฉ Since the typical overhead between each part of a "multipart/byteranges" is around 80 bytes, depending on the selected representation's media type and the chosen boundary parameter length, it can be less efficient to transfer many small disjoint parts than to transfer the entire selected representation ๐ฆ
A server MUST NOT generate a multipart response to a request for a single range, since a client that doesn't request multiple parts might not support multipart responses ๐ซ HOWEVER, a server MAY generate a "multipart/byteranges" response with only a single body part if multiple ranges were requested and only one range was found to be satisfiable or only one range remained after coalescing ๐ A client that cannot process a "multipart/byteranges" response MUST NOT generate a request that asks for multiple ranges ๐
A server that generates a multipart response SHOULD send the parts in the same order that the corresponding range-spec appeared in the received Range header field, excluding those ranges that were deemed unsatisfiable or that were coalesced into other ranges ๐ A client that receives a multipart response MUST inspect the Content-Range header field present in each body part to determine which range is contained in that body part ๐ a client can't rely on getting the same ranges it requested, or in the same order it requested them ๐ซ
15.3.7.3. Combining Parts ๐งฉ
okay so a response might only carry a subrange of a representation if the connection closed too early ๐ญ or if the request used one or more Range specifications. after a few of these, a client might've collected several ranges of the same representation. they can only be safely combined if they all share the same strong validator (Section 8.8.1). no cap, that's the vibe check ๐
A client that has received multiple partial responses to GET requests on a target resource MAY combine those responses into a larger continuous range if they share the same strong validator. โจ
If the most recent response is an incomplete 200 (OK) response, then the header fields of that response are used for any combined response and replace those of the matching stored responses. ๐ธ
If the most recent response is a 206 (Partial Content) response and at least one of the matching stored responses is a 200 (OK), then the combined response header fields consist of the most recent 200 response's header fields. ๐ If all of the matching stored responses are 206 responses, then the stored response with the most recent header fields is used as the source of header fields for the combined response. the plot twist is that the client MUST use other header fields provided in the new response, aside from Content-Range, to replace all instances of the corresponding header fields in the stored response. ๐ฅ
The combined response content is the union of partial content ranges within the new response and all of the matching stored responses. if that union covers the entire range of the representation, then the client MUST process the combined response as if it were a complete 200 (OK) response, including a Content-Length header field that reflects the complete length. ๐ Otherwise, the client MUST process the set of continuous ranges as one of the following: an incomplete 200 (OK) response if the combined response is a prefix of the representation, a single 206 (Partial Content) response containing multipart/byteranges content, or multiple 206 (Partial Content) responses, each with one continuous range that is indicated by a Content-Range header field. ๐ง
15.4. Redirection 3xx ๐ฆ
The 3xx (Redirection) class of status code indicates that further action needs to be taken by the user agent in order to fulfill the request. there are several types of redirects, bestie:
- Redirects that indicate this resource might be available at a different URI, as provided by the
Locationheader field, as in the status codes 301 (Moved Permanently), 302 (Found), 307 (Temporary Redirect), and 308 (Permanent Redirect). - Redirection that offers a choice among matching resources capable of representing this resource, as in the 300 (Multiple Choices) status code.
- Redirection to a different resource, identified by the
Locationheader field, that can represent an indirect response to the request, as in the 303 (See Other) status code. - Redirection to a previously stored result, as in the 304 (Not Modified) status code.
Note: In HTTP/1.0, the status codes 301 (Moved Permanently) and 302 (Found) were originally defined as method-preserving ([HTTP/1.0], Section 9.3) to match their implementation at CERN; 303 (See Other) was defined for a redirection that changed its method to GET. however, early user agents split on whether to redirect POST requests as POST (according to then-current specification) or as GET (the safer alternative when redirected to a different site). prevailing practice eventually converged on changing the method to GET. 307 (Temporary Redirect) and 308 (Permanent Redirect) [RFC7538] were later added to unambiguously indicate method-preserving redirects, and status codes 301 and 302 have been adjusted to allow a POST request to be redirected as GET. ๐
If a Location header field (Section 10.2.2) is provided, the user agent MAY automatically redirect its request to the URI referenced by the Location field value, even if the specific status code is not understood. automatic redirection needs to be done with care for methods not known to be safe, as defined in Section 9.2.1, since the user might not wish to redirect an unsafe request. โ ๏ธ
When automatically following a redirected request, the user agent SHOULD resend the original request message with the following modifications:
- Replace the target URI with the URI referenced by the redirection response's
Locationheader field value after resolving it relative to the original request's target URI. - Remove header fields that were automatically generated by the implementation, replacing them with updated values as appropriate to the new request. This includes:
- Connection-specific header fields (see Section 7.6.1),
- Header fields specific to the client's proxy configuration, including (but not limited to)
Proxy-Authorization, - Origin-specific header fields (if any), including (but not limited to)
Host, - Validating header fields that were added by the implementation's cache (e.g.,
If-None-Match,If-Modified-Since), and - Resource-specific header fields, including (but not limited to)
Referer,Origin,Authorization, andCookie.
- Consider removing header fields that were not automatically generated by the implementation (i.e., those present in the request because they were added by the calling context) where there are security implications; this includes but is not limited to
AuthorizationandCookie. ๐ - Change the request method according to the redirecting status code's semantics, if applicable.
- If the request method has been changed to GET or HEAD, remove content-specific header fields, including (but not limited to)
Content-Encoding,Content-Language,Content-Location,Content-Type,Content-Length,Digest,Last-Modified. ๐งน
A client SHOULD detect and intervene in cyclical redirections (i.e., "infinite" redirection loops). ๐
Note: An earlier version of this specification recommended a maximum of five redirections ([RFC2068], Section 10.3). content developers need to be aware that some clients might implement such a fixed limitation. ๐
15.4.1. 300 Multiple Choices ๐ธ
The 300 (Multiple Choices) status code indicates that the target resource has more than one representation, each with its own more specific identifier. information about the alternatives is being provided so that the user (or user agent) can select a preferred representation by redirecting its request to one or more of those identifiers. in other words, the server desires that the user agent engage in reactive negotiation to select the most appropriate representation(s) for its needs (Section 12). ๐ง
If the server has a preferred choice, the server SHOULD generate a Location header field containing a preferred choice's URI reference. the user agent MAY use the Location field value for automatic redirection. ๐ฏ
For request methods other than HEAD, the server SHOULD generate content in the 300 response containing a list of representation metadata and URI reference(s) from which the user or user agent can choose the one most preferred. the user agent MAY make a selection from that list automatically if it understands the provided media type. a specific format for automatic selection is not defined by this specification because HTTP tries to remain orthogonal to the definition of its content. in practice, the representation is provided in some easily parsed format believed to be acceptable to the user agent, as determined by shared design or content negotiation, or in some commonly accepted hypertext format. ๐
A 300 response is heuristically cacheable; i.e., unless otherwise indicated by the method definition or explicit cache controls (see Section 4.2.2 of [CACHING]). ๐พ
Note: The original proposal for the 300 status code defined the URI header field as providing a list of alternative representations, such that it would be usable for 200, 300, and 406 responses and be transferred in responses to the HEAD method. however, lack of deployment and disagreement over syntax led to both URI and Alternates (a subsequent proposal) being dropped from this specification. it is possible to communicate the list as a Link header field value [RFC8288] whose members have a relationship of "alternate", though deployment is a chicken-and-egg problem. ๐ฅ
15.4.2. 301 Moved Permanently ๐ฆ
The 301 (Moved Permanently) status code indicates that the target resource has been assigned a new permanent URI, and any future references to this resource ought to use one of the enclosed URIs. the server is suggesting that a user agent with link-editing capability can permanently replace references to the target URI with one of the new references sent by the server. however, this suggestion is usually ignored unless the user agent is actively editing references (e.g., engaged in authoring content), the connection is secured, and the origin server is a trusted authority for the content being edited. ๐ค
The server SHOULD generate a Location header field in the response containing a preferred URI reference for the new permanent URI. the user agent MAY use the Location field value for automatic redirection. the server's response content usually contains a short hypertext note with a hyperlink to the new URI(s). ๐
Note: For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request. If this behavior is undesired, the 308 (Permanent Redirect) status code can be used instead. ๐
A 301 response is heuristically cacheable; i.e., unless otherwise indicated by the method definition or explicit cache controls (see Section 4.2.2 of [CACHING]). ๐
15.4.3. 302 Found ๐
The 302 (Found) status code indicates that the target resource resides temporarily under a different URI. since the redirection might be altered on occasion, the client ought to continue to use the target URI for future requests. ๐
The server SHOULD generate a Location header field in the response containing a URI reference for the different URI. the user agent MAY use the Location field value for automatic redirection. the server's response content usually contains a short hypertext note with a hyperlink to the different URI(s). โจ
Note: For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request. If this behavior is undesired, the 307 (Temporary Redirect) status code can be used instead. ๐ซถ
15.4.4. 303 See Other โจ
okay so 303 (See Other) is the server going "not me, go check over there ๐๐
" ๐ It tells the user agent to redirect to a different resource, the one whose URI is in the Location header field, so it's kind of an indirect answer to what you originally asked for. The user agent can then make a retrieval request on that URI (a GET or HEAD request if we're talking HTTP), which might also get redirected, and show whatever comes back as the answer to the original request ๐ฆ Also ngl, the new URI in Location is not considered equivalent to the target URI, so don't mix them up ๐
This status code works with any HTTP method ๐ It's mainly used so a POST can redirect the user agent to a different resource, because that gives the POST response info as a resource you can separately identify, bookmark, and cache. main character energy for POST responses ๐
A 303 response to a GET request means the origin server doesn't have a representation of the target resource that it can transfer over HTTP ๐ญ BUT the Location value points to a resource that describes the target resource, so a retrieval request on that other resource might give a representation that's useful to recipients, without implying it represents the original target resource. Note that what can be represented, which representations are adequate, and what counts as a useful description are all outside the scope of HTTP ๐ง
Except for responses to a HEAD request, the representation of a 303 response ought to contain a short hypertext note with a hyperlink to the same URI reference provided in the Location header field ๐ซถ
15.4.5. 304 Not Modified ๐ธ
The 304 (Not Modified) status code says a conditional GET or HEAD request came in and would have gotten a 200 (OK) response, if the condition hadn't evaluated to false ๐ In other words, there's no need to send the representation again, because the client already has a valid one. So the server redirects the client to use its stored copy as if it were the content of a 200 (OK) response. iykyk ๐
The server generating a 304 response MUST generate any of the following header fields that would have been sent in a 200 (OK) response to the same request:
Content-Location,Date,ETag, andVaryCache-ControlandExpires(see [CACHING])
Since the whole goal of a 304 is to minimize info transfer when the recipient already has cached representations, a sender SHOULD NOT generate representation metadata other than the fields listed above, unless that metadata exists to guide cache updates (e.g., Last-Modified might be useful if the response does not have an ETag field) โจ
Requirements on a cache that receives a 304 response are defined in Section 4.3.4 of [CACHING]. If the conditional request came from an outbound client, like a user agent with its own cache sending a conditional GET to a shared proxy, then the proxy SHOULD forward the 304 response to that client ๐ซถ
A 304 response is terminated by the end of the header section. It cannot contain content or trailers ๐ซ
15.4.6. 305 Use Proxy ๐ฅ
The 305 (Use Proxy) status code was defined in a previous version of this specification and is now deprecated (Appendix B of [RFC7231]). bye bye ๐
15.4.7. 306 (Unused) ๐ซฅ
The 306 status code was defined in a previous version of this specification, it's no longer used, and the code is reserved.
15.4.8. 307 Temporary Redirect ๐
The 307 (Temporary Redirect) status code means the target resource lives temporarily under a different URI. The user agent MUST NOT change the request method if it performs an automatic redirection to that URI ๐ Since the redirection can change over time, the client ought to keep using the original target URI for future requests.
The server SHOULD generate a Location header field in the response containing a URI reference for the different URI. The user agent MAY use the Location field value for automatic redirection. The server's response content usually contains a short hypertext note with a hyperlink to the different URI(s) ๐
15.4.9. 308 Permanent Redirect ๐ฆ
The 308 (Permanent Redirect) status code means the target resource has been assigned a new permanent URI, and any future references to this resource ought to use one of the enclosed URIs. The server is suggesting that a user agent with link-editing capability can permanently replace references to the target URI with one of the new references sent by the server. However, this suggestion is usually ignored unless the user agent is actively editing references (e.g., engaged in authoring content), the connection is secured, and the origin server is a trusted authority for the content being edited ๐
The server SHOULD generate a Location header field in the response containing a preferred URI reference for the new permanent URI. The user agent MAY use the Location field value for automatic redirection. The server's response content usually contains a short hypertext note with a hyperlink to the new URI(s).
A 308 response is heuristically cacheable; i.e., unless otherwise indicated by the method definition or explicit cache controls (see Section 4.2.2 of [CACHING]).
Note: This status code is much younger (June 2014) than its sibling codes and thus might not be recognized everywhere. See Section 4 of [RFC7538] for deployment considerations.
15.5. Client Error 4xx ๐
The 4xx (Client Error) class of status code indicates that the client seems to have erred. Except when responding to a HEAD request, the server SHOULD send a representation 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 representation to the user ๐
15.5.1. 400 Bad Request ๐
The 400 (Bad Request) status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
15.5.2. 401 Unauthorized ๐
The 401 (Unauthorized) status code indicates that the request has not been applied because it lacks valid authentication credentials for the target resource. The server generating a 401 response MUST send a WWW-Authenticate header field (Section 11.6.1) containing at least one challenge applicable to the target resource.
If the request included authentication credentials, then the 401 response indicates that authorization has been refused for those credentials. The user agent MAY repeat the request with a new or replaced Authorization header field (Section 11.6.2). If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user agent SHOULD present the enclosed representation to the user, since it usually contains relevant diagnostic information.
15.5.3. 402 Payment Required ๐ธ
The 402 (Payment Required) status code is reserved for future use.
15.5.4. 403 Forbidden ๐ซ
The 403 (Forbidden) status code indicates that the server understood the request but refuses to fulfill it. A server that wishes to make public why the request has been forbidden can describe that reason in the response content (if any).
If authentication credentials were provided in the request, the server considers them insufficient to grant access. The client SHOULD NOT automatically repeat the request with the same credentials. The client MAY repeat the request with new or different credentials. However, a request might be forbidden for reasons unrelated to the credentials.
An origin server that wishes to "hide" the current existence of a forbidden target resource MAY instead respond with a status code of 404 (Not Found).
15.5.5. 404 Not Found ๐ต๏ธ
The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists. A 404 status code does not indicate whether this lack of representation is temporary or permanent; the 410 (Gone) status code is preferred over 404 if the origin server knows, presumably through some configurable means, that the condition is likely to be permanent.
A 404 response is heuristically cacheable; i.e., unless otherwise indicated by the method definition or explicit cache controls (see Section 4.2.2 of [CACHING]).
15.5.6. 405 Method Not Allowed ๐ท
The 405 (Method Not Allowed) status code indicates that the method received in the request-line is known by the origin server but not supported by the target resource. The origin server MUST generate an Allow header field in a 405 response containing a list of the target resource's currently supported methods.
A 405 response is heuristically cacheable; i.e., unless otherwise indicated by the method definition or explicit cache controls (see Section 4.2.2 of [CACHING]).
15.5.7. 406 Not Acceptable ๐ โโ๏ธ
The 406 (Not Acceptable) status code indicates that the target resource does not have a current representation that would be acceptable to the user agent, according to the proactive negotiation header fields received in the request (Section 12.1), and the server is unwilling to supply a default representation.
The server SHOULD generate content containing a list of available representation characteristics and corresponding resource identifiers from which the user or user agent can choose the one most appropriate. A user agent MAY automatically select the most appropriate choice from that list. However, this specification does not define any standard for such automatic selection, as described in Section 15.4.1.
15.5.8. 407 Proxy Authentication Required ๐ก๏ธ
The 407 (Proxy Authentication Required) status code is similar to 401 (Unauthorized), but it indicates that the client needs to authenticate itself in order to use a proxy for this request. The proxy MUST send a Proxy-Authenticate header field (Section 11.7.1) containing a challenge applicable to that proxy for the request. The client MAY repeat the request with a new or replaced Proxy-Authorization header field (Section 11.7.2).
15.5.9. 408 Request Timeout โฐ
The 408 (Request Timeout) status code indicates that the server did not receive a complete request message within the time that it was prepared to wait.
If the client has an outstanding request in transit, it MAY repeat that request. If the current connection is not usable (e.g., as it would be in HTTP/1.1 because request delimitation is lost), a new connection will be used.
15.5.10. 409 Conflict ๐
okay bestie, 409 is the "hold up, someone else already changed this" code ๐ The request couldn't be completed because it clashes with the current state of the target resource. The good news is that the user might be able to fix the clash and send the request again ๐ซถ So the server SHOULD generate content that includes enough info for the user to figure out where the clash came from โจ
Conflicts usually happen with a PUT request ๐ Say versioning is in use and the representation being PUT has changes that clash with an earlier request from a third party. The origin server might send a 409 to say it can't finish the request ๐ In that case the response body would probably help merge the differences using the revision history, which is so helpful ๐
15.5.11. 410 Gone ๐ฆ
410 means the target resource is no longer available on the origin server, and this is likely permanent ๐ If the origin server doesn't know, or has no way of figuring out, whether the situation is permanent, it ought to use 404 (Not Found) instead ๐ธ
A 410 is basically the server saying "I did this on purpose, please stop linking to it" ๐ง It's mostly there to help with web maintenance. This is super common for limited-time promos and for pages belonging to people who aren't with the origin server's site anymore ๐ญ You don't have to mark every permanently gone resource as "gone," and you don't have to keep that mark forever. That's up to the server owner ๐
A 410 response is heuristically cacheable, meaning unless the method definition or explicit cache controls say otherwise (see Section 4.2.2 of [CACHING]) โจ
15.5.12. 411 Length Required ๐
411 means the server won't accept the request without a defined Content-Length (Section 8.6) ๐
โโ๏ธ The client MAY send the request again if it adds a valid Content-Length header field with the length of the request content ๐
15.5.13. 412 Precondition Failed ๐
412 means one or more conditions in the request header fields evaluated to false when the server tested them (Section 13) ๐ฅ This status lets the client set preconditions on the current resource state (its current representations and metadata) so the request method doesn't get applied if the target resource is in a state it didn't expect ๐ Iconic self-protection ๐ค
15.5.14. 413 Content Too Large ๐
413 means the server is refusing to process the request because the request content is bigger than what the server is willing or able to handle ๐ญ The server MAY end the request if the protocol version in use allows it. If not, the server MAY close the connection ๐ซฃ
If the problem is temporary, the server SHOULD generate a Retry-After header field to say it's temporary and after what time the client MAY try again โญ
15.5.15. 414 URI Too Long ๐ง
414 means the server is refusing to service the request because the target URI is longer than the server is willing to interpret ๐ This is a rare one ๐ It mostly shows up when a client accidentally turned a POST into a GET with a ton of query info, when the client got stuck in an infinite redirect loop (like a redirected URI prefix that points to a suffix of itself), or when the server is under attack from someone trying to exploit security holes ๐จ
A 414 response is heuristically cacheable too, unless the method definition or explicit cache controls say otherwise (see Section 4.2.2 of [CACHING]) ๐ฆ
15.5.16. 415 Unsupported Media Type ๐
415 means the origin server is refusing to handle the request because the content is in a format this method doesn't support on the target resource ๐ โโ๏ธ
The format problem might come from the request's Content-Type or Content-Encoding, or from the server inspecting the data directly ๐
If the issue is an unsupported content coding, the Accept-Encoding response header field (Section 12.5.3) ought to be used to say which content codings (if any) would have been accepted in the request ๐
If the issue is an unsupported media type instead, the Accept response header field (Section 12.5.1) can be used to show which media types would have been accepted ๐ธ
15.5.17. 416 Range Not Satisfiable ๐
416 means the set of ranges in the request's Range header field (Section 14.2) got rejected. Either none of the requested ranges can be satisfied, or the client asked for way too many small or overlapping ranges (a potential denial of service attack, yikes) ๐ฑ
Each range unit defines what its own range sets need to be satisfiable. For example, Section 14.1.2 explains what makes a bytes range set satisfiable ๐
A server that sends a 416 to a byte-range request SHOULD generate a Content-Range header field that specifies the current length of the selected representation (Section 14.4) โจ
For example:
HTTP/1.1 416 Range Not Satisfiable
Date: Fri, 20 Jan 2012 15:41:54 GMT
Content-Range: bytes */47022
Note: Servers are free to ignore Range, so lots of implementations just send the whole selected representation in a 200 (OK) response ๐ซ Partly because most clients can handle a 200 to finish the task (just less efficiently), and partly because clients might keep making an invalid range request until they've got a complete representation. So clients can't count on getting a 416 (Range Not Satisfiable) response, even when it's the most appropriate one ๐ฅฒ
15.5.18. 417 Expectation Failed ๐ฆ
417 means the expectation given in the request's Expect header field (Section 10.1.1) couldn't be met by at least one of the inbound servers ๐
15.5.19. 418 (Unused) ๐
[RFC2324] was an April 1 RFC that poked fun at all the ways HTTP got misused ๐คก One of those misuses was an application-specific 418 status code, which got used as a joke so often that it's basically unusable for anything else now ๐
So the 418 status code is reserved in the IANA HTTP Status Code Registry ๐ That means it can't be assigned to other applications right now. If future circumstances need it (like running out of 4NN status codes), it can be reassigned to another use ๐ง
15.5.20. 421 Misdirected Request ๐
421 means the request was aimed at a server that can't or won't give an authoritative response for the target URI ๐งญ An origin server (or a gateway acting on its behalf) sends 421 to reject a target URI that doesn't match an origin the server has been configured for (Section 4.3.1), or that doesn't match the connection context the request came in on (Section 7.4) ๐ซฃ
A client that gets a 421 (Misdirected Request) response MAY retry the request, whether or not the request method is idempotent, over a different connection. That could be a fresh connection specific to the target resource's origin, or an alternative service [ALTSVC] ๐
A proxy MUST NOT generate a 421 response ๐ โโ๏ธ (proxies, know your place ๐ค)
15.5.21. 422 Unprocessable Content ๐
422 means the server gets the content type of the request content (so a 415 (Unsupported Media Type) would be the wrong call), and the syntax of the request content is correct, but it couldn't process the instructions inside ๐ง For example, this can be sent when XML request content is well-formed (syntactically correct) but has semantically wrong XML instructions ๐ธ
15.5.22. 426 Upgrade Required โญ
426 means the server won't do the request using the current protocol, but it might be willing to do it after the client upgrades to a different protocol ๐ The server MUST send an Upgrade header field in a 426 response to say which protocol(s) are required (Section 7.8) ๐
Example:
HTTP/1.1 426 Upgrade Required
Upgrade: HTTP/3.0
Connection: Upgrade
Content-Length: 53
Content-Type: text/plain
This service requires use of the HTTP/3.0 protocol.
15.6. Server Error 5xx ๐ฅ
The 5xx (Server Error) class of status code means the server knows it messed up or can't perform the requested method ๐ฌ Except when responding to a HEAD request, the server SHOULD send a representation that explains the error situation and whether it's a temporary or permanent condition ๐ A user agent SHOULD display any included representation to the user ๐ These status codes apply to any request method ๐
15.6.1. 500 Internal Server Error ๐ฅ
500 means the server ran into an unexpected condition that stopped it from fulfilling the request ๐ซ
15.6.2. 501 Not Implemented ๐ธ
501 means 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 ๐ โโ๏ธ
A 501 response is heuristically cacheable too, unless the method definition or explicit cache controls say otherwise (see Section 4.2.2 of [CACHING]) ๐ฆ
15.6.3. 502 Bad Gateway ๐
502 means the server, while acting as a gateway or proxy, got an invalid response from an inbound server it accessed while trying to fulfill the request ๐
15.6.4. 503 Service Unavailable ๐
503 means the server can't handle the request right now because of a temporary overload or scheduled maintenance, which will probably clear up after some delay โณ The server MAY send a Retry-After header field (Section 10.2.3) to suggest how long the client should wait before retrying the request โญ
Note: Getting a 503 doesn't mean the server has to use it when it's overloaded ๐ Some servers might just refuse the connection instead.
15.6.5. 504 Gateway Timeout ๐ง
504 means the server, while acting as a gateway or proxy, didn't get a timely response from an upstream server it needed to reach in order to complete the request โ Rip ๐ญ
15.6.6. 505 HTTP Version Not Supported ๐
okay bestie, this one is the "wrong version, sorry not sorry" code ๐ The 505 (HTTP Version Not Supported) status code means the server does not support, or refuses to support, the major version of HTTP that was used in the request message. The server is basically saying it can't or won't finish the request using the same major version as the client, as described in Section 2.5, and the only thing it's sending back is this error message ๐
The server SHOULD generate a representation for the 505 response that describes why that version is not supported and what other protocols are supported by that server. ๐ซถ
16. Extending HTTP โจ
HTTP has a bunch of built-in extension points so new capabilities can slide in without a whole new version. That includes methods, status codes, field names, and more extensibility points inside certain fields, like authentication schemes and cache directives (see Cache-Control extensions in Section 5.2.3 of [CACHING]). Since HTTP's semantics aren't versioned, these extension points are persistent. The protocol version in use doesn't change what they mean ๐ฆ
Version-independent extensions are discouraged from relying on or talking to the specific version of the protocol in use. When that can't be avoided, they need careful thought about how they'll interoperate across versions ๐ง
Specific versions of HTTP can also have their own extensibility points, like transfer codings in HTTP/1.1 (Section 6.1 of [HTTP/1.1]) and HTTP/2 SETTINGS or frame types ([HTTP/2]). These extension points are specific to the version of the protocol they occur within ๐ธ
Version-specific extensions cannot override or modify the semantics of a version-independent mechanism or extension point (like a method or header field) without explicitly being allowed by that protocol element. For example, the CONNECT method (Section 9.3.6) allows this ๐
These guidelines make sure the protocol operates correctly and predictably, even when parts of the path implement different versions of HTTP. no chaos allowed ๐
16.1. Method Extensibility ๐
16.1.1. Method Registry
The "Hypertext Transfer Protocol (HTTP) Method Registry", maintained by IANA at https://www.iana.org/assignments/http-methods, registers method names ๐
HTTP method registrations MUST include the following fields:
- Method Name (see Section 9)
- Safe ("yes" or "no", see Section 9.2.1)
- Idempotent ("yes" or "no", see Section 9.2.2)
- Pointer to specification text
Values to be added to this namespace require IETF Review (see [RFC8126], Section 4.8). ๐
16.1.2. Considerations for New Methods
Standardized methods are generic. That means they can potentially apply to any resource, not just one particular media type, kind of resource, or application. So it's preferred that new methods get registered in a document that isn't specific to a single application or data format, since orthogonal technologies deserve orthogonal specification ๐
Message parsing (Section 6) needs to be independent of method semantics (aside from responses to HEAD). That's why definitions of new methods cannot change the parsing algorithm or prohibit the presence of content on either the request or the response message. A definition of a new method can say that only zero-length content is allowed, by requiring a Content-Length header field with a value of "0" ๐
Likewise, new methods cannot use the special host:port and asterisk forms of request target that are allowed for CONNECT and OPTIONS, respectively (Section 7.1). A full URI in absolute form is needed for the target URI. That means either the request target gets sent in absolute form, or the target URI gets rebuilt from the request context the same way it is for other methods ๐งฉ
A new method definition needs to say whether it is safe (Section 9.2.1), idempotent (Section 9.2.2), and cacheable (Section 9.2.3). It also needs to cover what semantics go with the request content (if any), and what refinements the method makes to header field or status code semantics. If the new method is cacheable, its definition ought to describe how, and under what conditions, a cache can store a response and use it to satisfy a subsequent request. The new method ought to describe whether it can be made conditional (Section 13.1) and, if so, how a server responds when the condition is false. And if the new method might have some use for partial response semantics (Section 14.2), it ought to document that too ๐
๐จ Note: Avoid defining a method name that starts with "M-", since that prefix might be misinterpreted as having the semantics assigned to it by [RFC2774].
16.2. Status Code Extensibility ๐
16.2.1. Status Code Registry
The "Hypertext Transfer Protocol (HTTP) Status Code Registry", maintained by IANA at https://www.iana.org/assignments/http-status-codes, registers status code numbers ๐ข
A registration MUST include the following fields:
- Status Code (3 digits)
- Short Description
- Pointer to specification text
Values to be added to the HTTP status code namespace require IETF Review (see [RFC8126], Section 4.8). โจ
16.2.2. Considerations for New Status Codes
When it's necessary to express semantics for a response that aren't defined by current status codes, a new status code can be registered. Status codes are generic too. They can potentially apply to any resource, not just one particular media type, kind of resource, or application of HTTP. So it's preferred that new status codes get registered in a document that isn't specific to a single application ๐
New status codes are required to fall under one of the categories defined in Section 15. To let existing parsers process the response message, new status codes cannot disallow content, although they can mandate a zero-length content ๐งธ
Proposals for new status codes that aren't widely deployed yet ought to avoid allocating a specific number until there is clear consensus that it will be registered. Instead, early drafts can use a notation like "4NN", or "3N0" .. "3N9", to show the class of the proposed status code(s) without using up a number too early ๐ฃ
The definition of a new status code ought to explain the request conditions that would cause a response containing that status code (for example, combinations of request header fields and/or method(s)). It should also cover any dependencies on response header fields (for example, which fields are required, which fields can modify the semantics, and which field semantics get further refined when used with the new status code) ๐
By default, a status code applies only to the request corresponding to the response it occurs within. If a status code applies to a larger scope of applicability (for example, all requests to the resource in question or all requests to a server), this must be explicitly specified. When doing so, it should be noted that not all clients can be expected to consistently apply a larger scope, because they might not understand the new status code. scope drama, but make it clear ๐
The definition of a new final status code ought to specify whether or not it is heuristically cacheable. Any response with a final status code can be cached if the response has explicit freshness information. A status code defined as heuristically cacheable is allowed to be cached without explicit freshness information. And the definition of a status code can place constraints upon cache behavior if the must-understand cache directive is used. See [CACHING] for more information ๐ฆ
Finally, the definition of a new status code ought to indicate whether the content has any implied association with an identified resource (Section 6.4.2). ๐ซถ
16.3. Field Extensibility ๐ง
HTTP's most widely used extensibility point is the definition of new header and trailer fields. Main character energy ๐
New fields can be defined so that, when a recipient understands them, they override or enhance the interpretation of previously defined fields, define preconditions on request evaluation, or refine the meaning of responses ๐ช
However, defining a field doesn't guarantee that it gets deployed or recognized by recipients. Most fields are designed with the expectation that a recipient can safely ignore (but forward downstream) any field it doesn't recognize. In other cases, the sender's ability to understand a given field might be shown by its prior communication, like the protocol version or the fields it sent in earlier messages, or by its use of a specific media type. Direct inspection of support might also be possible through an OPTIONS request, or by interacting with a defined well-known URI [RFC8615], if that inspection is defined along with the field being introduced ๐
16.3.1. Field Name Registry
The "Hypertext Transfer Protocol (HTTP) Field Name Registry" defines the namespace for HTTP field names ๐๏ธ
Any party can request registration of an HTTP field. See Section 16.3.2 for considerations to take into account when creating a new HTTP field ๐
The "Hypertext Transfer Protocol (HTTP) Field Name Registry" is located at https://www.iana.org/assignments/http-fields/. You can request registration by following the instructions there, or by sending an email to the "ietf-http-wg@w3.org" mailing list ๐ง
Field names are registered on the advice of a designated expert (appointed by the IESG or their delegate). Fields with the status 'permanent' are Specification Required ([RFC8126], Section 4.6). ๐ง
Registration requests consist of the following information:
- Field name: The requested field name. It MUST conform to the field-name syntax defined in Section 5.1, and it SHOULD be restricted to just letters, digits, and hyphen (
'-') characters, with the first character being a letter. ๐ค - Status:
"permanent","provisional","deprecated", or"obsoleted". ๐ฆ - Specification document(s): Reference to the document that specifies the field, preferably including a URI that can be used to retrieve a copy of the document. Optional but encouraged for provisional registrations. An indication of the relevant section(s) can also be included, but it's not required. ๐
And optionally:
- Comments: Additional information, such as about reserved entries. ๐๏ธ
The expert(s) can define additional fields to be collected in the registry, in consultation with the community. ๐ค
Standards-defined names have a status of "permanent". Other names can also be registered as permanent if the expert(s) finds that they are in use, in consultation with the community. Other names should be registered as "provisional". ๐ท
Provisional entries can be removed by the expert(s) if, in consultation with the community, the expert(s) find that they are not in use. The expert(s) can change a provisional entry's status to permanent at any time. โณ
Note that names can be registered by third parties (including the expert(s)) if the expert(s) determines that an unregistered name is widely deployed and not likely to be registered in a timely manner otherwise. that's the tea ๐ซ
16.3.2. Considerations for New Fields โจ
Okay bestie, HTTP header and trailer fields are the extension point for the whole protocol ๐ฆ People totally use them in an ad hoc way, but fields meant for wider use need careful docs so everyone can actually interoperate. Main character energy only works if everyone's on the same page ๐
Authors writing specs for new fields are advised to think through and, where it makes sense, document these things:
- Under what conditions the field can be used. For example, only in responses or requests, in all messages, or only on responses to a particular request method.
- Whether the field's semantics get refined by context, like use with certain request methods or status codes.
- The scope of applicability for the info it carries. By default, a field only applies to the message it's attached to ๐ But some response fields are meant to apply to all representations of a resource, the resource itself, or an even broader scope. If a spec expands the scope of a response field, it'll need to think carefully about content negotiation, how long the info applies, and (in some cases) multi-tenant server deployments ๐
- Under what conditions intermediaries are allowed to insert, delete, or modify the field's value.
- If the field is allowed in trailers. By default it won't be (see Section 6.5.1).
- Whether it's appropriate, or even required, to list the field name in the Connection header field. That's the case if the field is meant to be hop-by-hop (see Section 7.6.1) ๐
- Whether the field brings any extra security considerations, like disclosing privacy-related data ๐
Request header fields have a few extra things to document if the default behavior isn't right for them:
- Whether it's appropriate to list the field name in a Vary response header field. For example, when the request header field is used by an origin server's content selection algorithm (see Section 12.5.5) ๐ง
- Whether the field is meant to be stored when it's received in a PUT request (see Section 9.3.4).
- Whether the field ought to be removed when a request gets automatically redirected because of security concerns (see Section 15.4) ๐
16.3.2.1. Considerations for New Field Names ๐ท๏ธ
Authors writing specs for new fields are advised to pick a name that's short but still descriptive. Short names avoid pointless data over the wire, and descriptive names avoid confusion and "squatting" on names that might have broader uses later ๐
So limited-use fields (like a header that's confined to one application or use case) are encouraged to use a name that includes that use, or an abbreviation of it, as a prefix. For example, if the Foo Application needs a Description field, it might use Foo-Desc. Description is way too generic, and Foo-Description is needlessly long ๐ญ
The field-name syntax is defined to allow any token character, but in practice some implementations limit which characters they accept in field names. To be interoperable, new field names SHOULD constrain themselves to alphanumeric characters, "-", and ".", and SHOULD begin with a letter. For example, the underscore ("_") character can be problematic when it gets passed through non-HTTP gateway interfaces (see Section 17.10) โ ๏ธ
Field names ought not be prefixed with "X-". See [BCP178] for more info ๐ธ
Other prefixes show up in HTTP field names sometimes. For example, Accept- is used in lots of content negotiation headers, and Content- is used the way Section 6.4 explains. These prefixes are only there to help you recognize what a field is for. They don't trigger any automatic processing โจ
16.3.2.2. Considerations for New Field Values ๐ง
A huge part of defining a new HTTP field is specifying its field value syntax: what senders should generate, and how recipients should figure out the semantics from what they receive ๐ฅ
Authors are encouraged (but not required) to use either the ABNF rules in this specification or the ones in [RFC8941] to define the syntax of new field values ๐
Authors are advised to think carefully about how combining multiple field lines will affect their field (see Section 5.3). Senders might accidentally send multiple values, and both intermediaries and HTTP libraries can combine them automatically. So this applies to all field values, even when only a single value is expected ๐
That's why authors are advised to delimit or encode values that contain commas. For example, use the quoted-string rule of Section 5.6.4, the String data type of [RFC8941], or a field-specific encoding. This makes sure commas inside the field data don't get mixed up with the commas that separate list values ๐ซถ
For example, the Content-Type field value only allows commas inside quoted strings, so it can be reliably parsed even when multiple values are present โ The Location field value is a counter-example that should not be emulated ๐ โโ๏ธ URIs can include commas, so you can't reliably tell a single value that has a comma apart from two values.
Authors of fields with a singleton value (see Section 5.5) are also advised to document how to handle messages where multiple members are present. A sensible default would be to ignore the field, but that might not always be the right choice ๐คทโโ๏ธ
16.4. Authentication Scheme Extensibility ๐
16.4.1. Authentication Scheme Registry ๐
The "Hypertext Transfer Protocol (HTTP) Authentication Scheme Registry" defines the namespace for the authentication schemes used in challenges and credentials. It's maintained at https://www.iana.org/assignments/http-authschemes.
Registrations MUST include the following fields:
- Authentication Scheme Name
- Pointer to specification text
- Notes (optional)
Values added to this namespace require IETF Review (see [RFC8126], Section 4.8) ๐
16.4.2. Considerations for New Authentication Schemes ๐ชช
There are some aspects of the HTTP Authentication framework that put constraints on how new authentication schemes can work, so pay attention bestie:
- HTTP authentication is presumed to be stateless. All of the info needed to authenticate a request MUST be provided in the request itself, instead of depending on the server remembering earlier requests ๐ง Authentication based on, or bound to, the underlying connection is outside the scope of this specification, and it's inherently flawed unless steps are taken to make sure nobody except the authenticated user can use that connection (see Section 3.3). Not me trusting a connection ๐
- The authentication parameter "realm" is reserved for defining protection spaces as described in Section 11.5. New schemes MUST NOT use it in a way that's incompatible with that definition ๐ซ
- The
token68notation was introduced for compatibility with existing authentication schemes, and it can only be used once per challenge or credential. So new schemes ought to use theauth-paramsyntax instead, because otherwise future extensions would be impossible ๐ค - The parsing of challenges and credentials is defined by this specification and can't be modified by new authentication schemes. When the
auth-paramsyntax is used, all parameters ought to support both token and quoted-string syntax, and syntactical constraints ought to be defined on the field value after parsing (i.e., quoted-string processing). This is necessary so recipients can use a generic parser that applies to all authentication schemes ๐งฉ
Note: The fact that the value syntax for the "realm" parameter is restricted to quoted-string was a bad design choice, and it's not to be repeated for new parameters. Iconic regret moment ๐
- Definitions of new schemes ought to define how unknown extension parameters get treated. In general, a "must-ignore" rule is preferable to a "must-understand" rule, because otherwise it'll be hard to introduce new parameters when legacy recipients are around ๐ฆ It's also good to describe the policy for defining new parameters, like "update the specification" or "use this registry" ๐
- Authentication schemes need to document whether they're usable in origin-server authentication (i.e., using
WWW-Authenticate), in proxy authentication (i.e., usingProxy-Authenticate), or both ๐ - The credentials carried in an
Authorizationheader field are specific to the user agent. So, within the scope of the request they appear in, they have the same effect on HTTP caches as the "private" cache response directive (Section 5.2.2.7 of [CACHING]) ๐
Therefore, new authentication schemes that choose not to carry credentials in the Authorization header field (e.g., by using a newly defined header field) will need to explicitly disallow caching, by mandating the use of cache response directives (e.g., "private") ๐ท
- Schemes using
Authentication-Info,Proxy-Authentication-Info, or any other authentication-related response header field need to consider and document the related security considerations (see Section 17.16.4). Don't skip this one, it's serious ๐จ
16.5. Range Unit Extensibility ๐
16.5.1. Range Unit Registry ๐๏ธ
The "HTTP Range Unit Registry" defines the namespace for the range unit names and refers to their corresponding specifications. It's maintained at https://www.iana.org/assignments/http-parameters.
Registration of an HTTP Range Unit MUST include the following fields:
- Name
- Description
- Pointer to specification text
Values added to this namespace require IETF Review (see [RFC8126], Section 4.8) ๐
16.5.2. Considerations for New Range Units ๐ฐ
Other range units, like format-specific boundaries such as pages, sections, records, rows, or time, could be usable in HTTP for application-specific purposes. But they aren't commonly used in practice ๐ค Anyone implementing alternative range units ought to think about how they'd work with content codings and general-purpose intermediaries ๐ฆ
16.6. Content Coding Extensibility ๐๏ธ
16.6.1. Content Coding Registry ๐งพ
The "HTTP Content Coding Registry" is maintained by IANA at https://www.iana.org/assignments/http-parameters/, and it registers content-coding names ๐
Content coding registrations MUST include the following fields:
- Name
- Description
- Pointer to specification text
Names of content codings MUST NOT overlap with names of transfer codings (per the "HTTP Transfer Coding Registry" located at https://www.iana.org/assignments/http-parameters/), unless the encoding transformation is identical. That's the case for the compression codings defined in Section 8.4.1 ๐
Values added to this namespace require IETF Review (see Section 4.8 of [RFC8126]) and MUST conform to the purpose of content coding defined in Section 8.4.1 โ
16.6.2. Considerations for New Content Codings ๐
New content codings ought to be self-descriptive whenever possible, with optional parameters discoverable within the coding format itself. That's better than relying on external metadata that might get lost in transit ๐
16.7. Upgrade Token Registry โจ
okay so bestie, this registry is the official little guest list for the Upgrade header field ๐ It's the namespace for protocol-name tokens, the names people use to say "hey, switch me over to this protocol" ๐ฆ You can find it at https://www.iana.org/assignments/http-upgrade-tokens ๐
Every registered protocol name gets contact info and, optionally, a set of specs that explains how the connection gets handled after the upgrade happens ๐ธ It's giving organized, no cap ๐
Registrations are First Come First Served (see Section 4.4 of [RFC8126]), and the rules are lowkey strict ๐ญ
- A protocol-name token, once registered, stays registered forever. Forever means forever bestie ๐
- A protocol-name token is case-insensitive, but it gets registered with a preferred case that senders are supposed to generate ๐
- The registration MUST name a responsible party for the registration. No ghosting allowed ๐
- The registration MUST name a point of contact ๐ซถ
- The registration MAY name a set of specifications associated with that token. Those specs don't have to be publicly available, which is kinda iconic for private projects ๐
- The registration SHOULD name a set of expected "protocol-version" tokens associated with that token at the time of registration โจ
- The responsible party MAY change the registration at any time. IANA keeps a record of all those changes and makes them available upon request, so the receipts are always there ๐ง
- The IESG MAY reassign responsibility for a protocol token. This will normally only happen when a responsible party can't be contacted, so it's the last-resort glow-up ๐
17. Security Considerations ๐ฅ
okay this section is giving serious protective energy, and it's meant to inform developers, information providers, and users about known security concerns relevant to HTTP semantics and using it to move information across the Internet ๐ Caching considerations live in Section 7 of [CACHING], and HTTP/1.1 message syntax and parsing considerations live in Section 11 of [HTTP/1.1] ๐ฆ
The list below is not exhaustive ๐ Most security concerns with HTTP semantics are about securing server-side apps (the code behind the HTTP interface), securing how user agents process content they receive over HTTP, or just using the Internet safely in general, rather than the protocol itself ๐ธ URI security considerations, which are fundamental to HTTP, are in Section 7 of [URI] โจ Various organizations keep topical info and links to current research on Web application security (e.g., [OWASP]) ๐ซถ
17.1. Establishing Authority ๐
HTTP depends on the idea of an "authoritative response": a response that the origin server named in the target URI has determined (or directed to be made) is the most appropriate response for that request, given the state of the target resource when the response was generated ๐ฅ
When a registered name is used in the authority component, the "http" URI scheme (Section 4.2.1) relies on the user's local name resolution service to figure out where authoritative responses can be found ๐ญ That means any attack on a user's network host table, cached names, or name resolution libraries becomes a way in for attacking authority for "http" URIs ๐ Same vibe with the user's choice of Domain Name Service (DNS) server and the hierarchy of servers it gets resolution results from, since those could mess with the authenticity of address mappings ๐ DNS Security Extensions (DNSSEC, [RFC4033]) are one way to improve authenticity, and so are the various ways of making DNS requests over more secure transfer protocols ๐ง
Also, once an IP address is obtained, establishing authority for an "http" URI is vulnerable to attacks on Internet Protocol routing ๐
The "https" scheme (Section 4.2.2) is meant to prevent (or at least reveal) lots of these authority attacks, as long as the negotiated connection is secured and the client properly checks that the communicating server's identity matches the target URI's authority component (Section 4.3.4) ๐ Doing that check correctly can be genuinely tricky (see [Georgiev]) ๐ญ
Authority for a given origin server can be delegated through protocol extensions, for example [ALTSVC] ๐ฆ And the set of servers a connection is considered authoritative for can be changed with a protocol extension like [RFC8336] โจ
Giving a response from a non-authoritative source, like a shared proxy cache, is often useful for performance and availability ๐ธ It only works, though, to the extent that the source can be trusted or the untrusted response can be safely used ๐
Unfortunately, communicating authority to users can be hard ๐ For example, "phishing" attacks the user's perception of authority, where similar branding in hypertext can mislead that perception, possibly with help from userinfo hiding the authority component (see Section 4.2.1) ๐ User agents can reduce the impact of phishing by letting users easily inspect a target URI before taking action, by prominently distinguishing (or rejecting) userinfo when it's present, and by not sending stored credentials and cookies when the referring document comes from an unknown or untrusted source ๐ซถ
17.2. Risks of Intermediaries ๐ง
HTTP intermediaries are inherently in a spot where on-path attacks are possible ๐ญ If the systems the intermediaries run on get compromised, that can cause serious security and privacy problems ๐ Intermediaries might have access to security-related information, personal info about individual users and organizations, and proprietary info belonging to users and content providers ๐ฅ A compromised intermediary, or one that was implemented or configured without regard to security and privacy, might get used for a wide range of potential attacks ๐
Intermediaries with a shared cache are especially vulnerable to cache poisoning attacks, as described in Section 7 of [CACHING] ๐
Implementers need to think about the privacy and security implications of their design and coding decisions, and of the configuration options they give to operators (especially the default configuration) ๐
Intermediaries are no more trustworthy than the people and policies they operate under, and HTTP cannot solve that problem for them ๐
17.3. Attacks Based on File and Path Names ๐
Origin servers often use their local file system to manage the mapping from target URI to resource representations ๐ธ Most file systems aren't designed to guard against malicious file or path names ๐ญ So an origin server needs to avoid accessing names that have special significance to the system when mapping the target resource to files, folders, or directories ๐
For example, UNIX, Microsoft Windows, and other operating systems use ".." as a path component to mean one directory level above the current one, and they use specially named paths or file names to send data to system devices ๐ Other storage systems might have similar naming conventions too โจ Local storage systems also have an annoying tendency to prefer user-friendliness over security when handling invalid or unexpected characters, recomposing decomposed characters, and case-normalizing case-insensitive names ๐
Attacks based on these special names tend to focus on either denial-of-service (e.g., telling the server to read from a COM port) or disclosure of configuration and source files that aren't meant to be served ๐ฅ
17.4. Attacks Based on Command, Code, or Query Injection ๐
Origin servers often use parameters within the URI to identify system services, select database entries, or choose a data source ๐ฆ However, data received in a request can't be trusted ๐ญ An attacker could build any of the request data elements (method, target URI, header fields, or content) to contain data that might be misread as a command, code, or query when passed through a command invocation, language interpreter, or database interface ๐
For example, SQL injection is a super common attack where extra query language gets inserted into some part of the target URI or header fields (e.g., Host, Referer, etc.) ๐ If the received data is used directly within a SELECT statement, the query language might get interpreted as a database command instead of a simple string value ๐ This type of implementation vulnerability is extremely common, even though it's really easy to prevent ๐ค
In general, resource implementations ought to avoid using request data in contexts that get processed or interpreted as instructions ๐ซถ Parameters ought to be compared to fixed strings and acted upon based on that comparison, rather than passed through an interface that isn't prepared for untrusted data ๐ Received data that isn't based on fixed parameters ought to be carefully filtered or encoded so it doesn't get misinterpreted ๐
Similar considerations apply to request data when it's stored and processed later, like in log files, monitoring tools, or a data format that allows embedded scripts ๐ง
17.5. Attacks via Protocol Element Length ๐
Because HTTP uses mostly textual, character-delimited fields, parsers are often vulnerable to attacks that send very long (or very slow) streams of data ๐ญ This is especially true when an implementation expects a protocol element with no predefined length (Section 2.3) ๐
To promote interoperability, specific recommendations are made for minimum size limits on fields (Section 5.4) โจ These are minimum recommendations, chosen to be supportable even by implementations with limited resources, and it's expected that most implementations will choose substantially higher limits ๐
A server can reject a message that has a target URI that's too long (Section 15.5.15) or request content that's too large (Section 15.5.14) ๐ธ Additional status codes related to capacity limits have been defined by extensions to HTTP [RFC6585] ๐ฆ
Recipients ought to carefully limit how far they process other protocol elements, including (but not limited to) request methods, response status phrases, field names, numeric values, and chunk lengths ๐ฅ Failing to limit that processing can lead to arbitrary code execution through buffer or arithmetic overflows, and increased vulnerability to denial-of-service attacks ๐ฑ
17.6. Attacks Using Shared-Dictionary Compression ๐๏ธ
Some attacks on encrypted protocols use the size differences created by dynamic compression to reveal confidential information, for example [BREACH] ๐ These attacks rely on creating redundancy between attacker-controlled content and the confidential information, so a dynamic compression algorithm using the same dictionary for both will compress more efficiently when the attacker-controlled content matches parts of the confidential content ๐
HTTP messages can be compressed in a number of ways, including TLS compression, content codings, transfer codings, and other extension or version-specific mechanisms ๐
The most effective mitigation for this risk is to disable compression on sensitive data, or to strictly separate sensitive data from attacker-controlled data so they can't share the same compression dictionary ๐ซถ With careful design, a compression scheme can be built so it isn't considered exploitable in limited use cases, such as HPACK ([HPACK]) โจ
17.7. Disclosure of Personal Information ๐
Okay so clients are literally privy to SO much personal info ๐ญ There's the stuff the user types in to interact with resources (their name, location, mail address, passwords, encryption keys, etc.), and there's info about their browsing activity over time (history, bookmarks, etc.) ๐ Implementations need to prevent unintentional disclosure of personal information, bestie. This one is a big deal ๐
17.8. Privacy of Server Log Information ๐ฆ
A server is in the position to save personal data about a user's requests over time, which might identify their reading patterns or subjects of interest ๐ Lowkey scary, right? Log info gathered at an intermediary is especially spicy because it often contains a history of user agent interaction across a multitude of sites, and that can be traced back to individual users ๐
HTTP log information is confidential in nature, and its handling is often constrained by laws and regulations โ๏ธ Log information needs to be securely stored, and appropriate guidelines need to be followed for its analysis. Anonymizing personal info within individual entries helps, but it is generally not sufficient to stop real log traces from being re-identified based on correlation with other access characteristics. As such, access traces keyed to a specific client are unsafe to publish, even if the key is pseudonymous. Not safe, no cap ๐ โโ๏ธ
To minimize the risk of theft or accidental publication, log information ought to be purged of personally identifiable information, including user identifiers, IP addresses, and user-provided query parameters, as soon as that information is no longer necessary to support operational needs for security, auditing, or fraud control ๐งนโจ
17.9. Disclosure of Sensitive Information in URIs ๐ธ
URIs are intended to be shared, not secured, even when they identify secure resources. Main character energy for URIs is "I'm public, deal with it" ๐โโ๏ธ They get shown on displays, added to templates when a page is printed, and stored in a variety of unprotected bookmark lists. Many servers, proxies, and user agents log or display the target URI in places where third parties might see it. It is therefore unwise to put anything sensitive, personally identifiable, or risky to disclose inside a URI ๐ซ
When an application uses client-side mechanisms to build a target URI out of user-provided info, such as the query fields of a form using GET, potentially sensitive data might end up in there that would not be appropriate to disclose within a URI ๐ฌ POST is often preferred in those cases because it usually doesn't construct a URI. Instead, a POST of a form sends the potentially sensitive data in the request content ๐ฆ However, this hinders caching, and it uses an unsafe method for what would otherwise be a safe request. Alternative workarounds include transforming the user-provided data before constructing the URI, or filtering the data so only common, non-sensitive values get included ๐ง Likewise, redirecting the result of a query to a different (server-generated) URI can remove potentially sensitive data from later links and provide a cacheable response for later reuse โจ
Since the Referer header field tells a target site about the context that resulted in a request, it has the potential to reveal info about the user's immediate browsing history, plus any personal info that might be found in the referring resource's URI ๐ Limitations on the Referer header field are described in Section 10.1.3 to address some of its security considerations ๐ก๏ธ
17.10. Application Handling of Field Names ๐ง
Servers often use non-HTTP gateway interfaces and frameworks to process a received request and produce content for the response. For historical reasons, these interfaces often pass received field names as external variable names, using a name mapping suitable for environment variables ๐ฐ๏ธ
For example, the Common Gateway Interface (CGI) mapping of protocol-specific meta-variables, defined by Section 4.1.18 of [RFC3875], is applied to received header fields that don't correspond to one of CGI's standard variables. The mapping consists of prepending HTTP_ to each name and changing all instances of hyphen (-) to underscore (_). This same mapping has been inherited by many other application frameworks, so moving apps from one platform to the next is easier ๐
In CGI, a received Content-Length field would be passed as the meta-variable CONTENT_LENGTH, with a string value matching the received field's value. In contrast, a received Content_Length header field would be passed as the protocol-specific meta-variable HTTP_CONTENT_LENGTH. That might cause some confusion if an application mistakenly reads the protocol-specific meta-variable instead of the default one ๐ตโ๐ซ (This historical practice is why Section 16.3.2.1 discourages the creation of new field names that contain an underscore ๐)
Unfortunately, mapping field names to different interface names can lead to security vulnerabilities if the mapping is incomplete or ambiguous ๐จ For example, if an attacker sent a field named Transfer_Encoding, a naive interface might map that to the same variable name as the Transfer-Encoding field. That could result in a potential request smuggling vulnerability (Section 11.2 of [HTTP/1.1]). Yikes, bestie ๐
To mitigate the associated risks, implementations that perform such mappings are advised to make the mapping unambiguous and complete for the full range of potential octets received as a name. That includes the octets that the HTTP grammar discourages or forbids. For example, a field with an unusual name character might result in the request being blocked, the specific field being removed, or the name being passed with a different prefix to tell it apart from other fields ๐
17.11. Disclosure of Fragment after Redirects ๐งฉ
Fragment identifiers used within URI references are not sent in requests, but implementers ought to be aware that they will be visible to the user agent and to any extensions or scripts running as a result of the response ๐๏ธ In particular, when a redirect occurs and the original request's fragment identifier is inherited by the new reference in Location (Section 10.2.2), this might have the effect of disclosing one site's fragment to another site ๐ฑ If the first site uses personal information in fragments, it ought to make sure that redirects to other sites include a (possibly empty) fragment component, which blocks that inheritance ๐ซถ
17.12. Disclosure of Product Information ๐ต๏ธโโ๏ธ
The User-Agent (Section 10.1.5), Via (Section 7.6.3), and Server (Section 10.2.4) header fields often reveal info about the respective sender's software systems ๐ฅ๏ธ In theory, this can make it easier for an attacker to exploit known security holes. In practice, attackers tend to try all potential holes regardless of the apparent software versions being used ๐คทโโ๏ธ
Proxies that serve as a portal through a network firewall ought to take special precautions regarding the transfer of header information that might identify hosts behind the firewall ๐งฑ The Via header field lets intermediaries swap sensitive machine names for pseudonyms ๐ญ
17.13. Browser Fingerprinting ๐ฆ
Browser fingerprinting is a set of techniques for identifying a specific user agent over time through its unique set of characteristics ๐ These characteristics might include info about how it uses the underlying transport protocol, its feature capabilities, and its scripting environment. Of particular interest here is the set of unique characteristics that might be communicated via HTTP. Fingerprinting is considered a privacy concern because it enables tracking of a user agent's behavior over time ([Bujlow]) without the corresponding controls that the user might have over other forms of data collection (e.g., cookies) ๐ช Many general-purpose user agents (i.e., Web browsers) have taken steps to reduce their fingerprints ๐
A number of request header fields might reveal info to servers that is unique enough to enable fingerprinting ๐ซฃ The From header field is the most obvious one, though From is expected to only be sent when the user wants to self-identify ๐โโ๏ธ Likewise, Cookie header fields are deliberately designed to enable re-identification, so fingerprinting concerns only apply to situations where cookies are disabled or restricted by the user agent's configuration ๐ญ
The User-Agent header field might contain enough info to uniquely identify a specific device, usually when combined with other characteristics. That's especially true if the user agent sends excessive details about the user's system or extensions ๐ฑ However, the source of unique info that users expect least is proactive negotiation (Section 12.1), including the Accept, Accept-Charset, Accept-Encoding, and Accept-Language header fields. Plot twist, bestie ๐ญ๐
Beyond fingerprinting, detailed use of the Accept-Language header field can reveal info the user might consider private. For example, understanding a given language set might be strongly correlated to membership in a particular ethnic group ๐ An approach that limits this loss of privacy would be for a user agent to omit sending Accept-Language except to sites that have been explicitly permitted. That permission might come from interaction after detecting a Vary header field that indicates language negotiation might be useful ๐ฌ
In environments where proxies are used to enhance privacy, user agents ought to be conservative about sending proactive negotiation header fields ๐ก๏ธ General-purpose user agents that offer a high degree of header field configurability ought to inform users about the loss of privacy that might result if too much detail is provided ๐ข As an extreme privacy measure, proxies could filter the proactive negotiation header fields in relayed requests ๐งผ
17.14. Validator Retention ๐
The validators defined by this specification are not intended to ensure the validity of a representation, guard against malicious changes, or detect on-path attacks. At best, they enable more efficient cache updates and optimistic concurrent writes when all participants are behaving nicely ๐ฅฐ At worst, the conditions will fail and the client will receive a response that is no more harmful than an HTTP exchange without conditional requests ๐ค
An entity tag can be abused in ways that create privacy risks ๐ณ For example, a site might deliberately construct a semantically invalid entity tag that is unique to the user or user agent. It could send that tag in a cacheable response with a long freshness time, then read it back in later conditional requests to re-identify that user or user agent ๐ต๏ธโโ๏ธ Such an identifying tag would become a persistent identifier for as long as the user agent kept the original cache entry. User agents that cache representations ought to make sure the cache is cleared or replaced whenever the user does privacy-maintaining things, like clearing stored cookies or switching to a private browsing mode ๐งน๐ซง
17.15. Denial-of-Service Attacks Using Range ๐
okay bestie, unconstrained multiple range requests are a whole vibe for attackers ๐ญ asking for a ton of overlapping ranges of the same data costs the attacker basically nothing, but the server has to burn time, memory, and bandwidth serving it all in pieces. so servers ought to ignore, coalesce, or reject egregious range requests โจ like anything asking for more than two overlapping ranges, or a pile of tiny ranges in one set, especially if they're out of order for no apparent reason ๐ and multipart range requests are not designed for random access, so don't treat them like that ๐ซถ
17.16. Authentication Considerations ๐
okay so authentication is a security consideration in its entirety ๐ this list is not exhaustive (sorry not sorry). also it only covers the authentication framework in general, not every single scheme, because specific schemes should be documented in the specs that define them ๐ if you want the current research and common pitfalls for using auth schemes in the wild, go check out the Web application security stuff from [OWASP] ๐ธ
17.16.1. Confidentiality of Credentials ๐คซ
the HTTP authentication framework does not define one single mechanism for keeping credentials confidential ๐ โโ๏ธ instead, each auth scheme decides how credentials get encoded before they're sent. that's flexible for future schemes, but it's not enough for existing schemes that give zero confidentiality on their own, or that don't really protect against replay attacks ๐ญ also, if the server expects credentials specific to each individual user, the exchange itself identifies that user, even if the credential contents stay secret ๐
HTTP leans on the security of the underlying transport- or session-level connection to keep fields confidential ๐ so services that rely on individual user auth MUST... no wait, they require a secured connection before exchanging credentials (Section 4.2.2) ๐
17.16.2. Credentials and Idle Clients ๐ซ
existing HTTP clients and user agents typically hold onto auth info forever ngl ๐ HTTP has no way for the origin server to tell clients to toss those cached credentials, since the protocol doesn't know how the user agent gets or manages them ๐ if a scheme wants to expire or revoke credentials, it can spell that out in its own definition ๐ฆ
credential caching can mess with the app's security model in a few ways (but this list isn't everything, babe):
- clients that have been idle for a long time, after which the server might want to make the client re-prompt the user for credentials ๐ค
- apps with a session-ending indicator (like a "logout" or "commit" button on a page), after which the server side "knows" the client has no further reason to keep the credentials ๐
user agents that cache credentials are encouraged to provide an easy-to-reach way to discard them under user control ๐ that's the main character move โจ
17.16.3. Protection Spaces ๐ฐ
auth schemes that only use the "realm" mechanism to set up a protection space will expose credentials to every resource on an origin server ๐ฑ clients that already made authenticated requests to one resource can reuse those same credentials on other resources on the same origin server. which means a different resource can literally harvest auth credentials meant for others ๐
this is especially concerning when an origin server hosts resources for multiple parties under the same origin (Section 11.5) ๐ฉ possible mitigations include restricting direct access to auth credentials (aka not making the content of the Authorization request header field available) ๐, and separating protection spaces by giving each party a different host name (or port number) ๐ง
17.16.4. Additional Response Fields ๐จ
adding info to responses sent over an unencrypted channel can affect security and privacy, so be careful ๐ just the presence of the Authentication-Info and Proxy-Authentication-Info header fields tells everyone HTTP authentication is in use ๐ and extra info could leak through the contents of the authentication-scheme specific parameters, so those definitions will have to take that into account ๐ซถ
18. IANA Considerations ๐๏ธ
the change controller for the following registrations is: "IETF (iesg@ietf.org) - Internet Engineering Task Force" ๐ธ
18.1. URI Scheme Registration ๐
IANA has updated the "Uniform Resource Identifier (URI) Schemes" registry [BCP35] at https://www.iana.org/assignments/uri-schemes/ with the permanent schemes listed in Table 2 in Section 4.2 โจ
18.2. Method Registration ๐งพ
IANA has updated the "Hypertext Transfer Protocol (HTTP) Method Registry" at https://www.iana.org/assignments/http-methods with the registration procedure of Section 16.1.1 and the method names summarized in the following table ๐
+=========+======+============+=========+
| Method | Safe | Idempotent | Section |
+=========+======+============+=========+
| CONNECT | no | no | 9.3.6 |
+---------+------+------------+---------+
| DELETE | no | yes | 9.3.5 |
+---------+------+------------+---------+
| GET | yes | yes | 9.3.1 |
+---------+------+------------+---------+
| HEAD | yes | yes | 9.3.2 |
+---------+------+------------+---------+
| OPTIONS | yes | yes | 9.3.7 |
+---------+------+------------+---------+
| POST | no | no | 9.3.3 |
+---------+------+------------+---------+
| PUT | no | yes | 9.3.4 |
+---------+------+------------+---------+
| TRACE | yes | yes | 9.3.8 |
+---------+------+------------+---------+
| * | no | no | 18.2 |
+---------+------+------------+---------+
Table 7
the method name "" is reserved because using "" as a method name would conflict with its usage as a wildcard in some fields (e.g., Access-Control-Request-Method) ๐
18.3. Status Code Registration
IANA has updated the "Hypertext Transfer Protocol (HTTP) Status Code Registry" at <https://www.iana.org/assignments/http-status-codes> with the registration procedure of Section 16.2.1 and the status code values summarized in the following table. ๐ โจ So IANA went in and gave the status code registry a glow-up, using the registration procedure from Section 16.2.1, and everything in the table below is now officially on the list. ๐
Here's the whole status code lineup, bestie. ๐ Each one has its own section number so you can jump straight to the good stuff:
+=======+===============================+=========+
| Value | Description | Section |
+=======+===============================+=========+
| 100 | Continue | 15.2.1 |
+-------+-------------------------------+---------+
| 101 | Switching Protocols | 15.2.2 |
+-------+-------------------------------+---------+
| 200 | OK | 15.3.1 |
+-------+-------------------------------+---------+
| 201 | Created | 15.3.2 |
+-------+-------------------------------+---------+
| 202 | Accepted | 15.3.3 |
+-------+-------------------------------+---------+
| 203 | Non-Authoritative Information | 15.3.4 |
+-------+-------------------------------+---------+
| 204 | No Content | 15.3.5 |
+-------+-------------------------------+---------+
| 205 | Reset Content | 15.3.6 |
+-------+-------------------------------+---------+
| 206 | Partial Content | 15.3.7 |
+-------+-------------------------------+---------+
| 300 | Multiple Choices | 15.4.1 |
+-------+-------------------------------+---------+
| 301 | Moved Permanently | 15.4.2 |
+-------+-------------------------------+---------+
| 302 | Found | 15.4.3 |
+-------+-------------------------------+---------+
| 303 | See Other | 15.4.4 |
+-------+-------------------------------+---------+
| 304 | Not Modified | 15.4.5 |
+-------+-------------------------------+---------+
| 305 | Use Proxy | 15.4.6 |
+-------+-------------------------------+---------+
| 306 | (Unused) | 15.4.7 |
+-------+-------------------------------+---------+
| 307 | Temporary Redirect | 15.4.8 |
+-------+-------------------------------+---------+
| 308 | Permanent Redirect | 15.4.9 |
+-------+-------------------------------+---------+
| 400 | Bad Request | 15.5.1 |
+-------+-------------------------------+---------+
| 401 | Unauthorized | 15.5.2 |
+-------+-------------------------------+---------+
| 402 | Payment Required | 15.5.3 |
+-------+-------------------------------+---------+
| 403 | Forbidden | 15.5.4 |
+-------+-------------------------------+---------+
| 404 | Not Found | 15.5.5 |
+-------+-------------------------------+---------+
| 405 | Method Not Allowed | 15.5.6 |
+-------+-------------------------------+---------+
| 406 | Not Acceptable | 15.5.7 |
+-------+-------------------------------+---------+
| 407 | Proxy Authentication Required | 15.5.8 |
+-------+-------------------------------+---------+
| 408 | Request Timeout | 15.5.9 |
+-------+-------------------------------+---------+
| 409 | Conflict | 15.5.10 |
+-------+-------------------------------+---------+
| 410 | Gone | 15.5.11 |
+-------+-------------------------------+---------+
| 411 | Length Required | 15.5.12 |
+-------+-------------------------------+---------+
| 412 | Precondition Failed | 15.5.13 |
+-------+-------------------------------+---------+
| 413 | Content Too Large | 15.5.14 |
+-------+-------------------------------+---------+
| 414 | URI Too Long | 15.5.15 |
+-------+-------------------------------+---------+
| 415 | Unsupported Media Type | 15.5.16 |
+-------+-------------------------------+---------+
| 416 | Range Not Satisfiable | 15.5.17 |
+-------+-------------------------------+---------+
| 417 | Expectation Failed | 15.5.18 |
+-------+-------------------------------+---------+
| 418 | (Unused) | 15.5.19 |
+-------+-------------------------------+---------+
| 421 | Misdirected Request | 15.5.20 |
+-------+-------------------------------+---------+
| 422 | Unprocessable Content | 15.5.21 |
+-------+-------------------------------+---------+
| 426 | Upgrade Required | 15.5.22 |
+-------+-------------------------------+---------+
| 500 | Internal Server Error | 15.6.1 |
+-------+-------------------------------+---------+
| 501 | Not Implemented | 15.6.2 |
+-------+-------------------------------+---------+
| 502 | Bad Gateway | 15.6.3 |
+-------+-------------------------------+---------+
| 503 | Service Unavailable | 15.6.4 |
+-------+-------------------------------+---------+
| 504 | Gateway Timeout | 15.6.5 |
+-------+-------------------------------+---------+
| 505 | HTTP Version Not Supported | 15.6.6 |
+-------+-------------------------------+---------+
Table 8
18.4. Field Name Registration โจ
okay bestie, so this section is basically the IANA paperwork for header field names ๐ It says this spec updates the HTTP parts of the old registration rules from [RFC3864] ๐ Like, the old procedures for HTTP are retired, and HTTP field definitions get their own shiny new home ๐ก
IANA made a new registry called "Hypertext Transfer Protocol (HTTP) Field Name Registry" as outlined in Section 16.3.1 ๐ฆ
IANA moved every entry with the protocol 'http' out of the "Permanent Message Header Field Names" and "Provisional Message Header Field Names" registries (see <https://www.iana.org/assignments/message-headers/>) and into the new one, with these changes ๐ธ
- The 'Applicable Protocol' field got omitted. Bye bye ๐
- Entries that were 'standard', 'experimental', 'reserved', or 'informational' became 'permanent' ๐
- Provisional entries with no status became 'provisional' โจ
- Permanent entries with no status (after confirming the registration document didn't define one) became 'provisional' ๐ The expert(s) can change the status if there's evidence another one fits better ๐ง
IANA added a note to the old "Permanent Message Header Field Names" and "Provisional Message Header Field Names" registries saying HTTP field name registrations have moved ๐
Note HTTP field name registrations have been moved to [https://www.iana.org/assignments/http-fields] per [RFC9110].
IANA also updated the new "Hypertext Transfer Protocol (HTTP) Field Name Registry" with the field names in the table below ๐
+===========================+============+=========+============+
| Field Name | Status | Section | Comments |
+===========================+============+=========+============+
| Accept | permanent | 12.5.1 | |
+---------------------------+------------+---------+------------+
| Accept-Charset | deprecated | 12.5.2 | |
+---------------------------+------------+---------+------------+
| Accept-Encoding | permanent | 12.5.3 | |
+---------------------------+------------+---------+------------+
| Accept-Language | permanent | 12.5.4 | |
+---------------------------+------------+---------+------------+
| Accept-Ranges | permanent | 14.3 | |
+---------------------------+------------+---------+------------+
| Allow | permanent | 10.2.1 | |
+---------------------------+------------+---------+------------+
| Authentication-Info | permanent | 11.6.3 | |
+---------------------------+------------+---------+------------+
| Authorization | permanent | 11.6.2 | |
+---------------------------+------------+---------+------------+
| Connection | permanent | 7.6.1 | |
+---------------------------+------------+---------+------------+
| Content-Encoding | permanent | 8.4 | |
+---------------------------+------------+---------+------------+
| Content-Language | permanent | 8.5 | |
+---------------------------+------------+---------+------------+
| Content-Length | permanent | 8.6 | |
+---------------------------+------------+---------+------------+
| Content-Location | permanent | 8.7 | |
+---------------------------+------------+---------+------------+
| Content-Range | permanent | 14.4 | |
+---------------------------+------------+---------+------------+
| Content-Type | permanent | 8.3 | |
+---------------------------+------------+---------+------------+
| Date | permanent | 6.6.1 | |
+---------------------------+------------+---------+------------+
| ETag | permanent | 8.8.3 | |
+---------------------------+------------+---------+------------+
| Expect | permanent | 10.1.1 | |
+---------------------------+------------+---------+------------+
| From | permanent | 10.1.2 | |
+---------------------------+------------+---------+------------+
| Host | permanent | 7.2 | |
+---------------------------+------------+---------+------------+
| If-Match | permanent | 13.1.1 | |
+---------------------------+------------+---------+------------+
| If-Modified-Since | permanent | 13.1.3 | |
+---------------------------+------------+---------+------------+
| If-None-Match | permanent | 13.1.2 | |
+---------------------------+------------+---------+------------+
| If-Range | permanent | 13.1.5 | |
+---------------------------+------------+---------+------------+
| If-Unmodified-Since | permanent | 13.1.4 | |
+---------------------------+------------+---------+------------+
| Last-Modified | permanent | 8.8.2 | |
+---------------------------+------------+---------+------------+
| Location | permanent | 10.2.2 | |
+---------------------------+------------+---------+------------+
| Max-Forwards | permanent | 7.6.2 | |
+---------------------------+------------+---------+------------+
| Proxy-Authenticate | permanent | 11.7.1 | |
+---------------------------+------------+---------+------------+
| Proxy-Authentication-Info | permanent | 11.7.3 | |
+---------------------------+------------+---------+------------+
| Proxy-Authorization | permanent | 11.7.2 | |
+---------------------------+------------+---------+------------+
| Range | permanent | 14.2 | |
+---------------------------+------------+---------+------------+
| Referer | permanent | 10.1.3 | |
+---------------------------+------------+---------+------------+
| Retry-After | permanent | 10.2.3 | |
+---------------------------+------------+---------+------------+
| Server | permanent | 10.2.4 | |
+---------------------------+------------+---------+------------+
| TE | permanent | 10.1.4 | |
+---------------------------+------------+---------+------------+
| Trailer | permanent | 6.6.2 | |
+---------------------------+------------+---------+------------+
| Upgrade | permanent | 7.8 | |
+---------------------------+------------+---------+------------+
| User-Agent | permanent | 10.1.5 | |
+---------------------------+------------+---------+------------+
| Vary | permanent | 12.5.5 | |
+---------------------------+------------+---------+------------+
| Via | permanent | 7.6.3 | |
+---------------------------+------------+---------+------------+
| WWW-Authenticate | permanent | 11.6.1 | |
+---------------------------+------------+---------+------------+
| * | permanent | 12.5.5 | (reserved) |
+---------------------------+------------+---------+------------+
Table 9 ๐ฉต
The field name "*" is reserved because using that name as an HTTP header field might clash with its special meaning in the Vary header field (Section 12.5.5) ๐
IANA also updated the "Content-MD5" entry in the new registry to have a status of 'obsoleted' ๐ฅ It points to Section 14.15 of [RFC2616] (for the definition of the header field) and Appendix B of [RFC7231] (which removed the field definition from the updated spec) ๐
18.5. Authentication Scheme Registration ๐
IANA updated the "Hypertext Transfer Protocol (HTTP) Authentication Scheme Registry" at <https://www.iana.org/assignments/http-authschemes> with the registration procedure of Section 16.4.1 ๐ No authentication schemes are defined in this document, so this one is just a quick stop ๐ฆ
18.6. Content Coding Registration ๐๏ธ
IANA updated the "HTTP Content Coding Registry" at <https://www.iana.org/assignments/http-parameters/> with the registration procedure of Section 16.6.1 and the content coding names in the table below ๐
+============+===========================================+=========+
| Name | Description | Section |
+============+===========================================+=========+
| compress | UNIX "compress" data format [Welch] | 8.4.1.1 |
+------------+-------------------------------------------+---------+
| deflate | "deflate" compressed data ([RFC1951]) | 8.4.1.2 |
| | inside the "zlib" data format ([RFC1950]) | |
+------------+-------------------------------------------+---------+
| gzip | GZIP file format [RFC1952] | 8.4.1.3 |
+------------+-------------------------------------------+---------+
| identity | Reserved | 12.5.3 |
+------------+-------------------------------------------+---------+
| x-compress | Deprecated (alias for compress) | 8.4.1.1 |
+------------+-------------------------------------------+---------+
| x-gzip | Deprecated (alias for gzip) | 8.4.1.3 |
+------------+-------------------------------------------+---------+
Table 10 ๐
18.7. Range Unit Registration ๐
IANA updated the "HTTP Range Unit Registry" at <https://www.iana.org/assignments/http-parameters/> with the registration procedure of Section 16.5.1 and the range unit names in the table below ๐
+=================+==================================+=========+
| Range Unit Name | Description | Section |
+=================+==================================+=========+
| bytes | a range of octets | 14.1.2 |
+-----------------+----------------------------------+---------+
| none | reserved as keyword to indicate | 14.3 |
| | range requests are not supported | |
+-----------------+----------------------------------+---------+
Table 11 โจ
18.8. Media Type Registration ๐๏ธ
IANA updated the "Media Types" registry at <https://www.iana.org/assignments/media-types> with the registration information in Section 14.6 for the media type "multipart/byteranges" ๐
IANA also updated the registry note about "q" parameters with a link to Section 12.5.1 of this document ๐
18.9. Port Registration ๐
IANA updated the "Service Name and Transport Protocol Port Number Registry" at <https://www.iana.org/assignments/service-names-port-numbers/> for the services on ports 80 and 443 that use UDP or TCP ๐ง They did two things:
- use this document as "Reference", and
- when currently unspecified, set "Assignee" to "IESG" and "Contact" to "IETF_Chair" ๐
That's the field name, auth scheme, content coding, range unit, media type, and port registrations all wrapped up, bestie ๐๐ More parts coming, so stay tuned ๐ซถ
18.10. Upgrade Token Registration ๐
okay bestie, last registry in the IANA section ๐ IANA updated the Hypertext Transfer Protocol (HTTP) Upgrade Token Registry at <https://www.iana.org/assignments/http-upgrade-tokens> using the registration procedure from Section 16.7. The upgrade token names are summarized in the table below โจ
+======+===================+=========================+=========+
| Name | Description | Expected Version Tokens | Section |
+======+===================+=========================+=========+
| HTTP | Hypertext | any DIGIT.DIGIT (e.g., | 2.5 |
| | Transfer Protocol | "2.0") | |
+------+-------------------+-------------------------+---------+
Table 12 ๐ฆ
19. References ๐๐ซถ
19.1. Normative References
- [CACHING] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Caching", STD 98, RFC 9111, DOI 10.17487/RFC9111, June 2022, <https://www.rfc-editor.org/info/rfc9111>.
- [RFC1950] Deutsch, P. and J-L. Gailly, "ZLIB Compressed Data Format Specification version 3.3", RFC 1950, DOI 10.17487/RFC1950, May 1996, <https://www.rfc-editor.org/info/rfc1950>.
- [RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification version 1.3", RFC 1951, DOI 10.17487/RFC1951, May 1996, <https://www.rfc-editor.org/info/rfc1951>.
- [RFC1952] Deutsch, P., "GZIP file format specification version 4.3", RFC 1952, DOI 10.17487/RFC1952, May 1996, <https://www.rfc-editor.org/info/rfc1952>.
- [RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types", RFC 2046, DOI 10.17487/RFC2046, November 1996, <https://www.rfc-editor.org/info/rfc2046>.
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.
- [RFC4647] Phillips, A., Ed. and M. Davis, Ed., "Matching of Language Tags", BCP 47, RFC 4647, DOI 10.17487/RFC4647, September 2006, <https://www.rfc-editor.org/info/rfc4647>.
- [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, <https://www.rfc-editor.org/info/rfc4648>.
- [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008, <https://www.rfc-editor.org/info/rfc5234>.
- [RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., and W. Polk, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 5280, DOI 10.17487/RFC5280, May 2008, <https://www.rfc-editor.org/info/rfc5280>.
- [RFC5322] Resnick, P., Ed., "Internet Message Format", RFC 5322, DOI 10.17487/RFC5322, October 2008, <https://www.rfc-editor.org/info/rfc5322>.
- [RFC5646] Phillips, A., Ed. and M. Davis, Ed., "Tags for Identifying Languages", BCP 47, RFC 5646, DOI 10.17487/RFC5646, September 2009, <https://www.rfc-editor.org/info/rfc5646>.
- [RFC6125] Saint-Andre, P. and J. Hodges, "Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS)", RFC 6125, DOI 10.17487/RFC6125, March 2011, <https://www.rfc-editor.org/info/rfc6125>.
- [RFC6365] Hoffman, P. and J. Klensin, "Terminology Used in Internationalization in the IETF", BCP 166, RFC 6365, DOI 10.17487/RFC6365, September 2011, <https://www.rfc-editor.org/info/rfc6365>.
- [RFC7405] Kyzivat, P., "Case-Sensitive String Support in ABNF", RFC 7405, DOI 10.17487/RFC7405, December 2014, <https://www.rfc-editor.org/info/rfc7405>.
- [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.
- [TCP] Postel, J., "Transmission Control Protocol", STD 7, RFC 793, DOI 10.17487/RFC0793, September 1981, <https://www.rfc-editor.org/info/rfc793>.
- [TLS13] Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>.
- [URI] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005, <https://www.rfc-editor.org/info/rfc3986>.
- [USASCII] American National Standards Institute, "Coded Character Set -- 7-bit American Standard Code for Information Interchange", ANSI X3.4, 1986.
- [Welch] Welch, T., "A Technique for High-Performance Data Compression", IEEE Computer 17(6), DOI 10.1109/MC.1984.1659158, June 1984, <https://ieeexplore.ieee.org/document/1659158/>.
19.2. Informative References
- [ALTSVC] Nottingham, M., McManus, P., and J. Reschke, "HTTP Alternative Services", RFC 7838, DOI 10.17487/RFC7838, April 2016, <https://www.rfc-editor.org/info/rfc7838>.
- [BCP13] Freed, N. and J. Klensin, "Multipurpose Internet Mail Extensions (MIME) Part Four: Registration Procedures", BCP 13, RFC 4289, December 2005. Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, January 2013. <https://www.rfc-editor.org/info/bcp13>
- [BCP178] Saint-Andre, P., Crocker, D., and M. Nottingham, "Deprecating the "X-" Prefix and Similar Constructs in Application Protocols", BCP 178, RFC 6648, June 2012. <https://www.rfc-editor.org/info/bcp178>
- [BCP35] Thaler, D., Ed., Hansen, T., and T. Hardie, "Guidelines and Registration Procedures for URI Schemes", BCP 35, RFC 7595, June 2015. <https://www.rfc-editor.org/info/bcp35>
- [BREACH] Gluck, Y., Harris, N., and A. Prado, "BREACH: Reviving the CRIME Attack", July 2013, <http://breachattack.com/resources/BREACH%20-%20SSL,%20gone%20in%2030%20seconds.pdf>.
- [Bujlow] Bujlow, T., Carela-Espaรฑol, V., Solรฉ-Pareta, J., and P. Barlet-Ros, "A Survey on Web Tracking: Mechanisms, Implications, and Defenses", In Proceedings of the IEEE 105(8), DOI 10.1109/JPROC.2016.2637878, August 2017, <https://doi.org/10.1109/JPROC.2016.2637878>.
- [COOKIE] Barth, A., "HTTP State Management Mechanism", RFC 6265, DOI 10.17487/RFC6265, April 2011, <https://www.rfc-editor.org/info/rfc6265>.
- [Err1912] RFC Errata, Erratum ID 1912, RFC 2978, <https://www.rfc-editor.org/errata/eid1912>.
- [Err5433] RFC Errata, Erratum ID 5433, RFC 2978, <https://www.rfc-editor.org/errata/eid5433>.
- [Georgiev] Georgiev, M., Iyengar, S., Jana, S., Anubhai, R., Boneh, D., and V. Shmatikov, "The Most Dangerous Code in the World: Validating SSL Certificates in Non-Browser Software", In Proceedings of the 2012 ACM Conference on Computer and Communications Security (CCS '12), pp. 38-49, DOI 10.1145/2382196.2382204, October 2012, <https://doi.org/10.1145/2382196.2382204>.
- [HPACK] Peon, R. and H. Ruellan, "HPACK: Header Compression for HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, <https://www.rfc-editor.org/info/rfc7541>.
- [HTTP/1.0] Berners-Lee, T., Fielding, R., and H. Frystyk, "Hypertext Transfer Protocol -- HTTP/1.0", RFC 1945, DOI 10.17487/RFC1945, May 1996, <https://www.rfc-editor.org/info/rfc1945>.
- [HTTP/1.1] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP/1.1", STD 99, RFC 9112, DOI 10.17487/RFC9112, June 2022, <https://www.rfc-editor.org/info/rfc9112>.
- [HTTP/2] Thomson, M., Ed. and C. Benfield, Ed., "HTTP/2", RFC 9113, DOI 10.17487/RFC9113, June 2022, <https://www.rfc-editor.org/info/rfc9113>.
- [HTTP/3] Bishop, M., Ed., "HTTP/3", RFC 9114, DOI 10.17487/RFC9114, June 2022, <https://www.rfc-editor.org/info/rfc9114>.
- [ISO-8859-1] International Organization for Standardization, "Information technology -- 8-bit single-byte coded graphic character sets -- Part 1: Latin alphabet No. 1", ISO/IEC 8859-1:1998, 1998.
- [Kri2001] Kristol, D., "HTTP Cookies: Standards, Privacy, and Politics", ACM Transactions on Internet Technology 1(2), November 2001, <http://arxiv.org/abs/cs.SE/0105018>.
- [OWASP] The Open Web Application Security Project, <https://www.owasp.org/>.
- [REST] Fielding, R.T., "Architectural Styles and the Design of Network-based Software Architectures", Doctoral Dissertation, University of California, Irvine, September 2000, <https://roy.gbiv.com/pubs/dissertation/top.htm>.
- [RFC1919] Chatel, M., "Classical versus Transparent IP Proxies", RFC 1919, DOI 10.17487/RFC1919, March 1996, <https://www.rfc-editor.org/info/rfc1919>.
- [RFC2047] Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text", RFC 2047, DOI 10.17487/RFC2047, November 1996, <https://www.rfc-editor.org/info/rfc2047>.
- [RFC2068] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2068, DOI 10.17487/RFC2068, January 1997, <https://www.rfc-editor.org/info/rfc2068>.
- [RFC2145] Mogul, J. C., Fielding, R., Gettys, J., and H. Frystyk, "Use and Interpretation of HTTP Version Numbers", RFC 2145, DOI 10.17487/RFC2145, May 1997, <https://www.rfc-editor.org/info/rfc2145>.
- [RFC2295] Holtman, K. and A. Mutz, "Transparent Content Negotiation in HTTP", RFC 2295, DOI 10.17487/RFC2295, March 1998, <https://www.rfc-editor.org/info/rfc2295>.
- [RFC2324] Masinter, L., "Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0)", RFC 2324, DOI 10.17487/RFC2324, 1 April 1998, <https://www.rfc-editor.org/info/rfc2324>.
- [RFC2557] Palme, J., Hopmann, A., and N. Shelness, "MIME Encapsulation of Aggregate Documents, such as HTML (MHTML)", RFC 2557, DOI 10.17487/RFC2557, March 1999, <https://www.rfc-editor.org/info/rfc2557>.
- [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, DOI 10.17487/RFC2616, June 1999, <https://www.rfc-editor.org/info/rfc2616>.
[RFC2617] Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S., Leach, P., Luotonen, A., and L. Stewart, "HTTP Authentication: Basic and Digest Access Authentication", RFC 2617, DOI 10.17487/RFC2617, June 1999, <https://www.rfc-editor.org/info/rfc2617>.
[RFC2774] Nielsen, H., Leach, P., and S. Lawrence, "An HTTP Extension Framework", RFC 2774, DOI 10.17487/RFC2774, February 2000, <https://www.rfc-editor.org/info/rfc2774>.
[RFC2818] Rescorla, E., "HTTP Over TLS", RFC 2818, DOI 10.17487/RFC2818, May 2000, <https://www.rfc-editor.org/info/rfc2818>.
[RFC2978] Freed, N. and J. Postel, "IANA Charset Registration Procedures", BCP 19, RFC 2978, DOI 10.17487/RFC2978, October 2000, <https://www.rfc-editor.org/info/rfc2978>.
[RFC3040] Cooper, I., Melve, I., and G. Tomlinson, "Internet Web Replication and Caching Taxonomy", RFC 3040, DOI 10.17487/RFC3040, January 2001, <https://www.rfc-editor.org/info/rfc3040>.
[RFC3864] Klyne, G., Nottingham, M., and J. Mogul, "Registration Procedures for Message Header Fields", BCP 90, RFC 3864, DOI 10.17487/RFC3864, September 2004, <https://www.rfc-editor.org/info/rfc3864>.
[RFC3875] Robinson, D. and K. Coar, "The Common Gateway Interface (CGI) Version 1.1", RFC 3875, DOI 10.17487/RFC3875, October 2004, <https://www.rfc-editor.org/info/rfc3875>.
[RFC4033] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, "DNS Security Introduction and Requirements", RFC 4033, DOI 10.17487/RFC4033, March 2005, <https://www.rfc-editor.org/info/rfc4033>.
[RFC4559] Jaganathan, K., Zhu, L., and J. Brezak, "SPNEGO-based Kerberos and NTLM HTTP Authentication in Microsoft Windows", RFC 4559, DOI 10.17487/RFC4559, June 2006, <https://www.rfc-editor.org/info/rfc4559>.
[RFC5789] Dusseault, L. and J. Snell, "PATCH Method for HTTP", RFC 5789, DOI 10.17487/RFC5789, March 2010, <https://www.rfc-editor.org/info/rfc5789>.
[RFC5905] Mills, D., Martin, J., Ed., Burbank, J., and W. Kasch, "Network Time Protocol Version 4: Protocol and Algorithms Specification", RFC 5905, DOI 10.17487/RFC5905, June 2010, <https://www.rfc-editor.org/info/rfc5905>.
[RFC6454] Barth, A., "The Web Origin Concept", RFC 6454, DOI 10.17487/RFC6454, December 2011, <https://www.rfc-editor.org/info/rfc6454>.
[RFC6585] Nottingham, M. and R. Fielding, "Additional HTTP Status Codes", RFC 6585, DOI 10.17487/RFC6585, April 2012, <https://www.rfc-editor.org/info/rfc6585>.
[RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing", RFC 7230, DOI 10.17487/RFC7230, June 2014, <https://www.rfc-editor.org/info/rfc7230>.
[RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content", RFC 7231, DOI 10.17487/RFC7231, June 2014, <https://www.rfc-editor.org/info/rfc7231>.
[RFC7232] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests", RFC 7232, DOI 10.17487/RFC7232, June 2014, <https://www.rfc-editor.org/info/rfc7232>.
[RFC7233] Fielding, R., Ed., Lafon, Y., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Range Requests", RFC 7233, DOI 10.17487/RFC7233, June 2014, <https://www.rfc-editor.org/info/rfc7233>.
[RFC7234] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Caching", RFC 7234, DOI 10.17487/RFC7234, June 2014, <https://www.rfc-editor.org/info/rfc7234>.
[RFC7235] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Authentication", RFC 7235, DOI 10.17487/RFC7235, June 2014, <https://www.rfc-editor.org/info/rfc7235>.
[RFC7538] Reschke, J., "The Hypertext Transfer Protocol Status Code 308 (Permanent Redirect)", RFC 7538, DOI 10.17487/RFC7538, April 2015, <https://www.rfc-editor.org/info/rfc7538>.
[RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext Transfer Protocol Version 2 (HTTP/2)", RFC 7540, DOI 10.17487/RFC7540, May 2015, <https://www.rfc-editor.org/info/rfc7540>.
[RFC7578] Masinter, L., "Returning Values from Forms: multipart/ form-data", RFC 7578, DOI 10.17487/RFC7578, July 2015, <https://www.rfc-editor.org/info/rfc7578>.
[RFC7615] Reschke, J., "HTTP Authentication-Info and Proxy- Authentication-Info Response Header Fields", RFC 7615, DOI 10.17487/RFC7615, September 2015, <https://www.rfc-editor.org/info/rfc7615>.
[RFC7616] Shekh-Yusef, R., Ed., Ahrens, D., and S. Bremer, "HTTP Digest Access Authentication", RFC 7616, DOI 10.17487/RFC7616, September 2015, <https://www.rfc-editor.org/info/rfc7616>.
[RFC7617] Reschke, J., "The 'Basic' HTTP Authentication Scheme", RFC 7617, DOI 10.17487/RFC7617, September 2015, <https://www.rfc-editor.org/info/rfc7617>.
[RFC7694] Reschke, J., "Hypertext Transfer Protocol (HTTP) Client- Initiated Content-Encoding", RFC 7694, DOI 10.17487/RFC7694, November 2015, <https://www.rfc-editor.org/info/rfc7694>.
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, <https://www.rfc-editor.org/info/rfc8126>.
[RFC8187] Reschke, J., "Indicating Character Encoding and Language for HTTP Header Field Parameters", RFC 8187, DOI 10.17487/RFC8187, September 2017, <https://www.rfc-editor.org/info/rfc8187>.
[RFC8246] McManus, P., "HTTP Immutable Responses", RFC 8246, DOI 10.17487/RFC8246, September 2017, <https://www.rfc-editor.org/info/rfc8246>.
[RFC8288] Nottingham, M., "Web Linking", RFC 8288, DOI 10.17487/RFC8288, October 2017, <https://www.rfc-editor.org/info/rfc8288>.
[RFC8336] Nottingham, M. and E. Nygren, "The ORIGIN HTTP/2 Frame", RFC 8336, DOI 10.17487/RFC8336, March 2018, <https://www.rfc-editor.org/info/rfc8336>.
[RFC8615] Nottingham, M., "Well-Known Uniform Resource Identifiers (URIs)", RFC 8615, DOI 10.17487/RFC8615, May 2019, <https://www.rfc-editor.org/info/rfc8615>.
[RFC8941] Nottingham, M. and P-H. Kamp, "Structured Field Values for HTTP", RFC 8941, DOI 10.17487/RFC8941, February 2021, <https://www.rfc-editor.org/info/rfc8941>.
[Sniffing] WHATWG, "MIME Sniffing", <https://mimesniff.spec.whatwg.org>.
[WEBDAV] Dusseault, L., Ed., "HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)", RFC 4918, DOI 10.17487/RFC4918, June 2007, <https://www.rfc-editor.org/info/rfc4918>.
Appendix A. Collected ABNF ๐
okay bestie, this is the ABNF buffet ๐ all the grammar rules gathered in one place so you don't have to hunt for them. the list rules are expanded the way Section 5.6.1 says, so the little comma-separated bits are already spelled out for you ๐
Accept = [ ( media-range [ weight ] ) *( OWS "," OWS ( media-range [
weight ] ) ) ]
Accept-Charset = [ ( ( token / "*" ) [ weight ] ) *( OWS "," OWS ( (
token / "*" ) [ weight ] ) ) ]
Accept-Encoding = [ ( codings [ weight ] ) *( OWS "," OWS ( codings [
weight ] ) ) ]
Accept-Language = [ ( language-range [ weight ] ) *( OWS "," OWS (
language-range [ weight ] ) ) ]
Accept-Ranges = acceptable-ranges
Allow = [ method *( OWS "," OWS method ) ]
Authentication-Info = [ auth-param *( OWS "," OWS auth-param ) ]
Authorization = credentials
BWS = OWS
Connection = [ connection-option *( OWS "," OWS connection-option )
]
Content-Encoding = [ content-coding *( OWS "," OWS content-coding )
]
Content-Language = [ language-tag *( OWS "," OWS language-tag ) ]
Content-Length = 1*DIGIT
Content-Location = absolute-URI / partial-URI
Content-Range = range-unit SP ( range-resp / unsatisfied-range )
Content-Type = media-type
Date = HTTP-date
ETag = entity-tag
Expect = [ expectation *( OWS "," OWS expectation ) ]
From = mailbox
GMT = %x47.4D.54 ; GMT
HTTP-date = IMF-fixdate / obs-date
Host = uri-host [ ":" port ]
IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT
If-Match = "*" / [ entity-tag *( OWS "," OWS entity-tag ) ]
If-Modified-Since = HTTP-date
If-None-Match = "*" / [ entity-tag *( OWS "," OWS entity-tag ) ]
If-Range = entity-tag / HTTP-date
If-Unmodified-Since = HTTP-date
Last-Modified = HTTP-date
Location = URI-reference
Max-Forwards = 1*DIGIT
OWS = *( SP / HTAB )
Proxy-Authenticate = [ challenge *( OWS "," OWS challenge ) ]
Proxy-Authentication-Info = [ auth-param *( OWS "," OWS auth-param )
]
Proxy-Authorization = credentials
RWS = 1*( SP / HTAB )
Range = ranges-specifier
Referer = absolute-URI / partial-URI
Retry-After = HTTP-date / delay-seconds
Server = product *( RWS ( product / comment ) )
TE = [ t-codings *( OWS "," OWS t-codings ) ]
Trailer = [ field-name *( OWS "," OWS field-name ) ]
URI-reference = <URI-reference, see [URI], Section 4.1>
Upgrade = [ protocol *( OWS "," OWS protocol ) ]
User-Agent = product *( RWS ( product / comment ) )
Vary = [ ( "*" / field-name ) *( OWS "," OWS ( "*" / field-name ) )
]
Via = [ ( received-protocol RWS received-by [ RWS comment ] ) *( OWS
"," OWS ( received-protocol RWS received-by [ RWS comment ] ) ) ]
WWW-Authenticate = [ challenge *( OWS "," OWS challenge ) ]
absolute-URI = <absolute-URI, see [URI], Section 4.3>
absolute-path = 1*( "/" segment )
acceptable-ranges = range-unit *( OWS "," OWS range-unit )
asctime-date = day-name SP date3 SP time-of-day SP year
auth-param = token BWS "=" BWS ( token / quoted-string )
auth-scheme = token
authority = <authority, see [URI], Section 3.2>
challenge = auth-scheme [ 1*SP ( token68 / [ auth-param *( OWS ","
OWS auth-param ) ] ) ]
codings = content-coding / "identity" / "*"
comment = "(" *( ctext / quoted-pair / comment ) ")"
complete-length = 1*DIGIT
connection-option = token
content-coding = token
credentials = auth-scheme [ 1*SP ( token68 / [ auth-param *( OWS ","
OWS auth-param ) ] ) ]
ctext = HTAB / SP / %x21-27 ; '!'-'''
/ %x2A-5B ; '*'-'['
/ %x5D-7E ; ']'-'~'
/ obs-text
date1 = day SP month SP year
date2 = day "-" month "-" 2DIGIT
date3 = month SP ( 2DIGIT / ( SP DIGIT ) )
day = 2DIGIT
day-name = %x4D.6F.6E ; Mon
/ %x54.75.65 ; Tue
/ %x57.65.64 ; Wed
/ %x54.68.75 ; Thu
/ %x46.72.69 ; Fri
/ %x53.61.74 ; Sat
/ %x53.75.6E ; Sun
day-name-l = %x4D.6F.6E.64.61.79 ; Monday
/ %x54.75.65.73.64.61.79 ; Tuesday
/ %x57.65.64.6E.65.73.64.61.79 ; Wednesday
/ %x54.68.75.72.73.64.61.79 ; Thursday
/ %x46.72.69.64.61.79 ; Friday
/ %x53.61.74.75.72.64.61.79 ; Saturday
/ %x53.75.6E.64.61.79 ; Sunday
delay-seconds = 1*DIGIT
entity-tag = [ weak ] opaque-tag
etagc = "!" / %x23-7E ; '#'-'~'
/ obs-text
expectation = token [ "=" ( token / quoted-string ) parameters ]
field-content = field-vchar [ 1*( SP / HTAB / field-vchar )
field-vchar ]
field-name = token
field-value = *field-content
field-vchar = VCHAR / obs-text
first-pos = 1*DIGIT
hour = 2DIGIT
http-URI = "http://" authority path-abempty [ "?" query ]
https-URI = "https://" authority path-abempty [ "?" query ]
incl-range = first-pos "-" last-pos
int-range = first-pos "-" [ last-pos ]
language-range = <language-range, see [RFC4647], Section 2.1>
language-tag = <Language-Tag, see [RFC5646], Section 2.1>
last-pos = 1*DIGIT
mailbox = <mailbox, see [RFC5322], Section 3.4>
media-range = ( "*/*" / ( type "/*" ) / ( type "/" subtype ) )
parameters
media-type = type "/" subtype parameters
method = token
minute = 2DIGIT
month = %x4A.61.6E ; Jan
/ %x46.65.62 ; Feb
/ %x4D.61.72 ; Mar
/ %x41.70.72 ; Apr
/ %x4D.61.79 ; May
/ %x4A.75.6E ; Jun
/ %x4A.75.6C ; Jul
/ %x41.75.67 ; Aug
/ %x53.65.70 ; Sep
/ %x4F.63.74 ; Oct
/ %x4E.6F.76 ; Nov
/ %x44.65.63 ; Dec
obs-date = rfc850-date / asctime-date
obs-text = %x80-FF
opaque-tag = DQUOTE *etagc DQUOTE
other-range = 1*( %x21-2B ; '!'-'+'
/ %x2D-7E ; '-'-'~'
)
parameter = parameter-name "=" parameter-value
parameter-name = token
parameter-value = ( token / quoted-string )
parameters = *( OWS ";" OWS [ parameter ] )
partial-URI = relative-part [ "?" query ]
path-abempty = <path-abempty, see [URI], Section 3.3>
port = <port, see [URI], Section 3.2.3>
product = token [ "/" product-version ]
product-version = token
protocol = protocol-name [ "/" protocol-version ]
protocol-name = token
protocol-version = token
pseudonym = token
qdtext = HTAB / SP / "!" / %x23-5B ; '#'-'['
/ %x5D-7E ; ']'-'~'
/ obs-text
query = <query, see [URI], Section 3.4>
quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
qvalue = ( "0" [ "." *3DIGIT ] ) / ( "1" [ "." *3"0" ] )
range-resp = incl-range "/" ( complete-length / "*" )
range-set = range-spec *( OWS "," OWS range-spec )
range-spec = int-range / suffix-range / other-range
range-unit = token
ranges-specifier = range-unit "=" range-set
received-by = pseudonym [ ":" port ]
received-protocol = [ protocol-name "/" ] protocol-version
relative-part = <relative-part, see [URI], Section 4.2>
rfc850-date = day-name-l "," SP date2 SP time-of-day SP GMT
second = 2DIGIT
segment = <segment, see [URI], Section 3.3>
subtype = token
suffix-length = 1*DIGIT
suffix-range = "-" suffix-length
t-codings = "trailers" / ( transfer-coding [ weight ] )
tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
"^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
time-of-day = hour ":" minute ":" second
token = 1*tchar
token68 = 1*( ALPHA / DIGIT / "-" / "." / "_" / "~" / "+" / "/" )
*"="
transfer-coding = token *( OWS ";" OWS transfer-parameter )
transfer-parameter = token BWS "=" BWS ( token / quoted-string )
type = token
unsatisfied-range = "*/" complete-length
uri-host = <host, see [URI], Section 3.2.2>
weak = %x57.2F ; W/
weight = OWS ";" OWS "q=" qvalue
year = 4DIGIT
Appendix B. Changes from Previous RFCs ๐ฆ
ok this part is the glow-up history ๐ธ what changed from the older RFCs, so you can see what's new and what's been moved around โจ
B.1. Changes from RFC 2818
Nothing changed here! ๐ซถ the list is just "None." ๐
B.2. Changes from RFC 7230
bestie, this is the big one ๐ here's everything that shifted from RFC 7230:
The sections about HTTP's design goals, history, architecture, conformance criteria, protocol versioning, URIs, message routing, and header fields got moved into this document ๐ฆโจ
The semantic conformance requirement got swapped out for permission to ignore or work around implementation-specific failures ๐ (Section 2.2)
The description of an origin and authoritative access to origin servers got extended for both "http" and "https" URIs, so it can account for alternative services and secured connections that aren't necessarily based on TCP ๐ (Sections 4.2.1, 4.2.2, 4.3.1, and 7.3.3)
Explicit requirements got added to check the target URI scheme's semantics and to reject requests that don't meet any associated requirements ๐ฅ (Section 7.4)
Parameters in media type, media range, and expectation can now be empty via one or more trailing semicolons ๐ (Section 5.6.6)
"Field value" now refers to the value after multiple field lines are combined with commas, which is by far the most common use ๐ If you want to refer to a single header line's value, use "field line value" instead. (Section 6.3)
Trailer field semantics now go beyond chunked transfer coding specifics ๐ฆ The use of trailer fields got further limited: a sender may generate one as a trailer field only when it knows the field defines that usage, and a recipient may merge it into the header section only if it knows the corresponding field definition permits and defines how to merge. In all other cases, implementations are encouraged either to store the trailer fields separately or to discard them instead of merging. (Section 6.5.1)
The priority of the absolute form of the request URI over the Host header field by origin servers got made explicit, so it lines up with proxy handling ๐ (Section 7.2)
The grammar for the Via field's "received-by" got expanded in RFC 7230 because of changes to the URI grammar for host [URI] that aren't desirable for Via. For simplicity, uri-host got removed from the received-by production, since it can be covered by the existing grammar for pseudonym. This change also removed comma from the allowed set of characters for a host name in received-by. (Section 7.6.3)
B.3. Changes from RFC 7231 ๐ โจ
Okay so the big one first: minimum URI lengths that implementations should support are now RECOMMENDED ๐ (Section 4.1). Wait, let me say that properly: the original says they are now recommended, so the capitalised phrase goes here as RECOMMENDED. ๐ธ
The following have been clarified, bestie ๐ซถ: CR and NUL in field values are to be rejected or mapped to SP, and leading and trailing whitespace needs to be stripped from field values before they are consumed. (Section 5.5) ๐ญ
Parameters in media type, media range, and expectation can be empty via one or more trailing semicolons. (Section 5.6.6) ๐ฆ
An abstract data type for HTTP messages has been introduced ๐ง to define the components of a message and their semantics as an abstraction across multiple HTTP versions, rather than in terms of the specific syntax form of HTTP/1.1 in [HTTP/1.1], and reflect the contents after the message is parsed. This makes it easier to distinguish between requirements on the content (what is conveyed) versus requirements on the messaging syntax (how it is conveyed) and avoids baking limitations of early protocol versions into the future of HTTP. (Section 6) ๐
The terms "payload" and "payload body" have been replaced with "content", to better align with its usage elsewhere (e.g., in field names) and to avoid confusion with frame payloads in HTTP/2 and HTTP/3. (Section 6.4) ๐
The term "effective request URI" has been replaced with "target URI". (Section 7.1) ๐
Restrictions on client retries have been loosened to reflect implementation behavior. (Section 9.2.2) ๐
The fact that request bodies on GET, HEAD, and DELETE are not interoperable has been clarified. (Sections 9.3.1, 9.3.2, and 9.3.5) ๐
The use of the Content-Range header field (Section 14.4) as a request modifier on PUT is allowed. (Section 9.3.4) โจ
A superfluous requirement about setting Content-Length has been removed from the description of the OPTIONS method. (Section 9.3.7) ๐
The normative requirement to use the "message/http" media type in TRACE responses has been removed. (Section 9.3.8) ๐ฅ
List-based grammar for Expect has been restored for compatibility with RFC 2616. (Section 10.1.1) ๐
Accept and Accept-Encoding are allowed in response messages; the latter was introduced by [RFC7694]. (Section 12.3) ๐
"Accept Parameters" (accept-params and accept-ext ABNF production) have been removed from the definition of the Accept field. (Section 12.5.1) ๐ฆ
The Accept-Charset field is now deprecated. (Section 12.5.2) ๐ธ
The semantics of "*" in the Vary header field when other values are present was clarified. (Section 12.5.5) โญ
Range units are compared in a case-insensitive fashion. (Section 14.1) ๐
The use of the Accept-Ranges field is not restricted to origin servers. (Section 14.3) ๐ซถ
The process of creating a redirected request has been clarified. (Section 15.4) ๐ง
Status code 308 (previously defined in [RFC7538]) has been added so that it's defined closer to status codes 301, 302, and 307. (Section 15.4.9) ๐
Status code 421 (previously defined in Section 9.1.2 of [RFC7540]) has been added because of its general applicability. 421 is no longer defined as heuristically cacheable since the response is specific to the connection (not the target resource). (Section 15.5.20) ๐
Status code 422 (previously defined in Section 11.2 of [WEBDAV]) has been added because of its general applicability. (Section 15.5.21) ๐
B.4. Changes from RFC 7232 ๐ธ
Previous revisions of HTTP imposed an arbitrary 60-second limit on the determination of whether Last-Modified was a strong validator, to guard 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. This specification has relaxed that to allow reasonable discretion. (Section 8.8.2.2) โญ
An edge-case requirement on If-Match and If-Unmodified-Since has been removed, which required a validator not to be sent in a 2xx response if validation fails because the change request has already been applied. (Sections 13.1.1 and 13.1.4) ๐
The fact that If-Unmodified-Since does not apply to a resource without a concept of modification time has been clarified. (Section 13.1.4) ๐
Preconditions can now be evaluated before the request content is processed, rather than waiting until the response would otherwise be successful. (Section 13.2) ๐ฆ
B.5. Changes from RFC 7233 ๐ง
Refactored the range-unit and ranges-specifier grammars to simplify and reduce artificial distinctions between bytes and other (extension) range units, removing the overlapping grammar of other-range-unit by defining range units generically as a token and placing extensions within the scope of a range-spec (other-range). This disambiguates the role of list syntax (commas) in all range sets, including extension range units, for indicating a range-set of more than one range. Moving the extension grammar into range specifiers also allows protocol specific to byte ranges to be specified separately. ๐
It is now possible to define Range handling on extension methods. (Section 14.2) ๐
Described use of the Content-Range header field (Section 14.4) as a request modifier to perform a partial PUT. (Section 14.5) ๐
B.6. Changes from RFC 7235 ๐
None. ๐ธ
B.7. Changes from RFC 7538 ๐
None. ๐
B.8. Changes from RFC 7615 ๐ฆ
None. โจ
B.9. Changes from RFC 7694 ๐ซถ
This specification includes the extension defined in [RFC7694] but leaves out examples and deployment considerations. ๐ฅ
Acknowledgements ๐ท
Aside from the current editors, the following individuals deserve special recognition for their contributions to early aspects of HTTP and its core specifications: Marc Andreessen, Tim Berners-Lee, Robert Cailliau, Daniel W. Connolly, Bob Denny, John Franks, Jim Gettys, Jean-Franรงois Groff, Phillip M. Hallam-Baker, Koen Holtman, Jeffery L. Hostetler, Shel Kaphan, Dave Kristol, Yves Lafon, Scott D. Lawrence, Paul J. Leach, Hรฅkon W. Lie, Ari Luotonen, Larry Masinter, Rob McCool, Jeffrey C. Mogul, Lou Montulli, David Morris, Henrik Frystyk Nielsen, Dave Raggett, Eric Rescorla, Tony Sanders, Lawrence C. Stewart, Marc VanHeyningen, and Steve Zilles. ๐
This document builds on the many contributions that went into past specifications of HTTP, including [HTTP/1.0], [RFC2068], [RFC2145], [RFC2616], [RFC2617], [RFC2818], [RFC7230], [RFC7231], [RFC7232], [RFC7233], [RFC7234], and [RFC7235]. The acknowledgements within those documents still apply. ๐
Since 2014, the following contributors have helped improve this specification by reporting bugs, asking smart questions, drafting or reviewing text, and evaluating issues: Alan Egerton, Alex Rousskov, Amichai Rothman, Amos Jeffries, Anders Kaseorg, Andreas Gebhardt, Anne van Kesteren, Armin Abfalterer, Aron Duby, Asanka Herath, Asbjรธrn Ulsberg, Asta Olofsson, Attila Gulyas, Austin Wright, Barry Pollard, Ben Burkert, Benjamin Kaduk, Bjรถrn Hรถhrmann, Brad Fitzpatrick, Chris Pacejo, Colin Bendell, Cory Benfield, Cory Nelson, Daisuke Miyakawa, Dale Worley, Daniel Stenberg, Danil Suits, David Benjamin, David Matson, David Schinazi, ะะธะปัะฝ ะะฐะปะฐัะทะพะฒ (Dilyan Palauzov), Eric Anderson, Eric Rescorla, รric Vyncke, Erik Kline, Erwin Pe, Etan Kissling, Evert Pot, Evgeny Vrublevsky, Florian Best, Francesca Palombini, Igor Lubashev, James Callahan, James Peach, Jeffrey Yasskin, Kalin Gyokov, Kannan Goundan, ๅฅฅ ไธ็ฉ (Kazuho Oku), Ken Murchison, Krzysztof Maczyลski, Lars Eggert, Lucas Pardue, Martin Duke, Martin Dรผrst, Martin Thomson, Martynas Juseviฤius, Matt Menke, Matthias Pigulla, Mattias Grenfeldt, Michael Osipov, Mike Bishop, Mike Pennisi, Mike Taylor, Mike West, Mohit Sethi, Murray Kucherawy, Nathaniel J. Smith, Nicholas Hurley, Nikita Prokhorov, Patrick McManus, Piotr Sikora, Poul-Henning Kamp, Rick van Rein, Robert Wilton, Roberto Polli, Roman Danyliw, Samuel Williams, Semyon Kholodnov, Simon Pieters, Simon Schรผppel, Stefan Eissing, Taylor Hunt, Todd Greer, Tommy Pauly, Vasiliy Faronov, Vladimir Lashchev, Wenbo Zhu, William A. Rowe Jr., Willy Tarreau, Xingwei Liu, Yishuai Li, and Zaheduzzaman Sarker. ๐
Index ๐
1 2 3 4 5 A B C D E F G H I L M N O P R S T U V W X
1
100 Continue (status code) _Section 15.2.1_ 100-continue (expect value) _Section 10.1.1_ 101 Switching Protocols (status code) _Section 15.2.2_ 1xx Informational (status code class) _Section 15.2_
2
200 OK (status code) _Section 15.3.1_ 201 Created (status code) _Section 15.3.2_ 202 Accepted (status code) _Section 15.3.3_ 203 Non-Authoritative Information (status code) _Section 15.3.4_ 204 No Content (status code) _Section 15.3.5_ 205 Reset Content (status code) _Section 15.3.6_ 206 Partial Content (status code) _Section 15.3.7_ 2xx Successful (status code class) _Section 15.3_
3
300 Multiple Choices (status code) _Section 15.4.1_ 301 Moved Permanently (status code) _Section 15.4.2_ 302 Found (status code) _Section 15.4.3_ 303 See Other (status code) _Section 15.4.4_ 304 Not Modified (status code) _Section 15.4.5_ 305 Use Proxy (status code) _Section 15.4.6_ 306 (Unused) (status code) _Section 15.4.7_ 307 Temporary Redirect (status code) _Section 15.4.8_ 308 Permanent Redirect (status code) _Section 15.4.9_ 3xx Redirection (status code class) _Section 15.4_
4
400 Bad Request (status code) _Section 15.5.1_ 401 Unauthorized (status code) _Section 15.5.2_ 402 Payment Required (status code) _Section 15.5.3_ 403 Forbidden (status code) _Section 15.5.4_ 404 Not Found (status code) _Section 15.5.5_ 405 Method Not Allowed (status code) _Section 15.5.6_ 406 Not Acceptable (status code) _Section 15.5.7_ 407 Proxy Authentication Required (status code) _Section 15.5.8_ 408 Request Timeout (status code) _Section 15.5.9_ 409 Conflict (status code) _Section 15.5.10_ 410 Gone (status code) _Section 15.5.11_ 411 Length Required (status code) _Section 15.5.12_ 412 Precondition Failed (status code) _Section 15.5.13_ 413 Content Too Large (status code) _Section 15.5.14_ 414 URI Too Long (status code) _Section 15.5.15_ 415 Unsupported Media Type (status code) _Section 15.5.16_ 416 Range Not Satisfiable (status code) _Section 15.5.17_ 417 Expectation Failed (status code) _Section 15.5.18_ 418 (Unused) (status code) _Section 15.5.19_ 421 Misdirected Request (status code) _Section 15.5.20_ 422 Unprocessable Content (status code) _Section 15.5.21_ 426 Upgrade Required (status code) _Section 15.5.22_ 4xx Client Error (status code class) _Section 15.5_
5
500 Internal Server Error (status code) _Section 15.6.1_ 501 Not Implemented (status code) _Section 15.6.2_ 502 Bad Gateway (status code) _Section 15.6.3_ 503 Service Unavailable (status code) _Section 15.6.4_ 504 Gateway Timeout (status code) _Section 15.6.5_ 505 HTTP Version Not Supported (status code) _Section 15.6.6_ 5xx Server Error (status code class) _Section 15.6_
A
okay bestie, the index is a whole vibe ๐
here are the entries from the accelerator line through the H heading โจ
accelerator *_Section 3.7, Paragraph 6_*
Accept header field *_Section 12.5.1_*
Accept-Charset header field *_Section 12.5.2_*
Accept-Encoding header field *_Section 12.5.3_*
Accept-Language header field *_Section 12.5.4_*
Accept-Ranges header field *_Section 14.3_*
Allow header field *_Section 10.2.1_*
Authentication-Info header field *_Section 11.6.3_*
authoritative response *_Section 17.1_*
Authorization header field *_Section 11.6.2_*
B
browser *_Section 3.5_*
C
cache *_Section 3.8_*
cacheable *_Section 3.8, Paragraph 4_*
client *_Section 3.3_*
clock *_Section 5.6.7_*
complete *_Section 6.1_*
compress (Coding Format) Section 8.4.1.1
compress (content coding) *_Section 8.4.1_*
conditional request *_Section 13_*
CONNECT method *_Section 9.3.6_*
connection *_Section 3.3_*
Connection header field *_Section 7.6.1_*
content Section 6.4
content coding *_Section 8.4.1_*
content negotiation Section 1.3, Paragraph 4
Content-Encoding header field *_Section 8.4_*
Content-Language header field *_Section 8.5_*
Content-Length header field *_Section 8.6_*
Content-Location header field *_Section 8.7_*
Content-MD5 header field *_Section 18.4, Paragraph 10_*
Content-Range header field *_Section 14.4_*; Section 14.5
Content-Type header field *_Section 8.3_*
control data *_Section 6.2_*
D
Date header field *_Section 6.6.1_*
deflate (Coding Format) Section 8.4.1.2
deflate (content coding) *_Section 8.4.1_*
DELETE method *_Section 9.3.5_*
Delimiters Section 5.6.2, Paragraph 3
downstream *_Section 3.7, Paragraph 4_*
E
effective request URI *_Section 7.1, Paragraph 8.1_*
ETag field *_Section 8.8.3_*
Expect header field *_Section 10.1.1_*
F
field *_Section 5_*; Section 6.3
field line Section 5.2, Paragraph 1
field line value Section 5.2, Paragraph 1
field name Section 5.2, Paragraph 1
field value Section 5.2, Paragraph 2
Fields
* *_Section 18.4, Paragraph 9_*
Accept *_Section 12.5.1_*
Accept-Charset *_Section 12.5.2_*
Accept-Encoding *_Section 12.5.3_*
Accept-Language *_Section 12.5.4_*
Accept-Ranges *_Section 14.3_*
Allow *_Section 10.2.1_*
Authentication-Info *_Section 11.6.3_*
Authorization *_Section 11.6.2_*
Connection *_Section 7.6.1_*
Content-Encoding *_Section 8.4_*
Content-Language *_Section 8.5_*
Content-Length *_Section 8.6_*
Content-Location *_Section 8.7_*
Content-MD5 *_Section 18.4, Paragraph 10_*
Content-Range *_Section 14.4_*; Section 14.5
Content-Type *_Section 8.3_*
Date *_Section 6.6.1_*
ETag *_Section 8.8.3_*
Expect *_Section 10.1.1_*
From *_Section 10.1.2_*
Host *_Section 7.2_*
If-Match *_Section 13.1.1_*
If-Modified-Since *_Section 13.1.3_*
If-None-Match *_Section 13.1.2_*
If-Range *_Section 13.1.5_*
If-Unmodified-Since *_Section 13.1.4_*
Last-Modified *_Section 8.8.2_*
Location *_Section 10.2.2_*
Max-Forwards *_Section 7.6.2_*
Proxy-Authenticate *_Section 11.7.1_*
Proxy-Authentication-Info *_Section 11.7.3_*
Proxy-Authorization *_Section 11.7.2_*
Range *_Section 14.2_*
Referer *_Section 10.1.3_*
Retry-After *_Section 10.2.3_*
Server *_Section 10.2.4_*
TE *_Section 10.1.4_*
Trailer *_Section 6.6.2_*
Upgrade *_Section 7.8_*
User-Agent *_Section 10.1.5_*
Vary *_Section 12.5.5_*
Via *_Section 7.6.3_*
WWW-Authenticate *_Section 11.6.1_*
Fragment Identifiers Section 4.2.5
From header field *_Section 10.1.2_*
G
gateway *_Section 3.7, Paragraph 6_*
GET method *_Section 9.3.1_*
Grammar
ALPHA *_Section 2.1_*
Accept *_Section 12.5.1_*
Accept-Charset *_Section 12.5.2_*
Accept-Encoding *_Section 12.5.3_*
Accept-Language *_Section 12.5.4_*
Accept-Ranges *_Section 14.3_*
Allow *_Section 10.2.1_*
Authentication-Info *_Section 11.6.3_*
Authorization *_Section 11.6.2_*
BWS *_Section 5.6.3_*
CR *_Section 2.1_*
CRLF *_Section 2.1_*
CTL *_Section 2.1_*
Connection *_Section 7.6.1_*
Content-Encoding *_Section 8.4_*
Content-Language *_Section 8.5_*
Content-Length *_Section 8.6_*
Content-Location *_Section 8.7_*
Content-Range *_Section 14.4_*
Content-Type *_Section 8.3_*
DIGIT *_Section 2.1_*
DQUOTE *_Section 2.1_*
Date *_Section 6.6.1_*
ETag *_Section 8.8.3_*
Expect *_Section 10.1.1_*
From *_Section 10.1.2_*
GMT *_Section 5.6.7_*
HEXDIG *_Section 2.1_*
HTAB *_Section 2.1_*
HTTP-date *_Section 5.6.7_*
Host *_Section 7.2_*
IMF-fixdate *_Section 5.6.7_*
If-Match *_Section 13.1.1_*
If-Modified-Since *_Section 13.1.3_*
If-None-Match *_Section 13.1.2_*
If-Range *_Section 13.1.5_*
If-Unmodified-Since *_Section 13.1.4_*
LF *_Section 2.1_*
Last-Modified *_Section 8.8.2_*
Location *_Section 10.2.2_*
Max-Forwards *_Section 7.6.2_*
OCTET *_Section 2.1_*
OWS *_Section 5.6.3_*
Proxy-Authenticate *_Section 11.7.1_*
Proxy-Authentication-Info *_Section 11.7.3_*
Proxy-Authorization *_Section 11.7.2_*
RWS *_Section 5.6.3_*
Range *_Section 14.2_*
Referer *_Section 10.1.3_*
Retry-After *_Section 10.2.3_*
SP *_Section 2.1_*
Server *_Section 10.2.4_*
TE *_Section 10.1.4_*
Trailer *_Section 6.6.2_*
URI-reference *_Section 4.1_*
Upgrade *_Section 7.8_*
User-Agent *_Section 10.1.5_*
VCHAR *_Section 2.1_*
Vary *_Section 12.5.5_*
Via *_Section 7.6.3_*
WWW-Authenticate *_Section 11.6.1_*
absolute-URI *_Section 4.1_*
absolute-path *_Section 4.1_*
acceptable-ranges *_Section 14.3_*
asctime-date *_Section 5.6.7_*
auth-param *_Section 11.2_*
auth-scheme *_Section 11.1_*
authority *_Section 4.1_*
challenge *_Section 11.3_*
codings *_Section 12.5.3_*
comment *_Section 5.6.5_*
complete-length *_Section 14.4_*
connection-option *_Section 7.6.1_*
content-coding *_Section 8.4.1_*
credentials *_Section 11.4_*
ctext *_Section 5.6.5_*
date1 *_Section 5.6.7_*
day *_Section 5.6.7_*
day-name *_Section 5.6.7_*
day-name-l *_Section 5.6.7_*
delay-seconds *_Section 10.2.3_*
entity-tag *_Section 8.8.3_*
etagc *_Section 8.8.3_*
field-content *_Section 5.5_*
field-name *_Section 5.1_*; Section 6.6.2
field-value *_Section 5.5_*
field-vchar *_Section 5.5_*
first-pos *_Section 14.1.1_*; Section 14.4
hour *_Section 5.6.7_*
http-URI *_Section 4.2.1_*
https-URI *_Section 4.2.2_*
incl-range *_Section 14.4_*
int-range *_Section 14.1.1_*
language-range *_Section 12.5.4_*
language-tag *_Section 8.5.1_*
last-pos *_Section 14.1.1_*; Section 14.4
media-range *_Section 12.5.1_*
media-type *_Section 8.3.1_*
method *_Section 9.1_*
minute *_Section 5.6.7_*
month *_Section 5.6.7_*
obs-date *_Section 5.6.7_*
obs-text *_Section 5.5_*
opaque-tag *_Section 8.8.3_*
other-range *_Section 14.1.1_*
parameter *_Section 5.6.6_*
parameter-name *_Section 5.6.6_*
parameter-value *_Section 5.6.6_*
parameters *_Section 5.6.6_*
partial-URI *_Section 4.1_*
port *_Section 4.1_*
product *_Section 10.1.5_*
product-version *_Section 10.1.5_*
protocol-name *_Section 7.6.3_*
protocol-version *_Section 7.6.3_*
pseudonym *_Section 7.6.3_*
qdtext *_Section 5.6.4_*
query *_Section 4.1_*
quoted-pair *_Section 5.6.4_*
quoted-string *_Section 5.6.4_*
qvalue *_Section 12.4.2_*
range-resp *_Section 14.4_*
range-set *_Section 14.1.1_*
range-spec *_Section 14.1.1_*
range-unit *_Section 14.1_*
ranges-specifier *_Section 14.1.1_*
received-by *_Section 7.6.3_*
received-protocol *_Section 7.6.3_*
rfc850-date *_Section 5.6.7_*
second *_Section 5.6.7_*
segment *_Section 4.1_*
subtype *_Section 8.3.1_*
suffix-length *_Section 14.1.1_*
suffix-range *_Section 14.1.1_*
t-codings *_Section 10.1.4_*
tchar *_Section 5.6.2_*
time-of-day *_Section 5.6.7_*
token *_Section 5.6.2_*
token68 *_Section 11.2_*
transfer-coding *_Section 10.1.4_*
transfer-parameter *_Section 10.1.4_*
type *_Section 8.3.1_*
unsatisfied-range *_Section 14.4_*
uri-host *_Section 4.1_*
weak *_Section 8.8.3_*
weight *_Section 12.4.2_*
year *_Section 5.6.7_*
gzip (Coding Format) Section 8.4.1.3
gzip (content coding) *_Section 8.4.1_*
H
Okay bestie, this is the index, the big cheat sheet where you can find every header field, method, status code and term in the whole spec. ๐ Each entry points to the section it lives in, so if you're ever lost, just look it up ๐ง
HEAD method *_Section 9.3.2_*
Header Fields
Accept *_Section 12.5.1_*
Accept-Charset *_Section 12.5.2_*
Accept-Encoding *_Section 12.5.3_*
Accept-Language *_Section 12.5.4_*
Accept-Ranges *_Section 14.3_*
Allow *_Section 10.2.1_*
Authentication-Info *_Section 11.6.3_*
Authorization *_Section 11.6.2_*
Connection *_Section 7.6.1_*
Content-Encoding *_Section 8.4_*
Content-Language *_Section 8.5_*
Content-Length *_Section 8.6_*
Content-Location *_Section 8.7_*
Content-MD5 *_Section 18.4, Paragraph 10_*
Content-Range *_Section 14.4_*; Section 14.5
Content-Type *_Section 8.3_*
Date *_Section 6.6.1_*
ETag *_Section 8.8.3_*
Expect *_Section 10.1.1_*
From *_Section 10.1.2_*
Host *_Section 7.2_*
If-Match *_Section 13.1.1_*
If-Modified-Since *_Section 13.1.3_*
If-None-Match *_Section 13.1.2_*
If-Range *_Section 13.1.5_*
If-Unmodified-Since *_Section 13.1.4_*
Last-Modified *_Section 8.8.2_*
Location *_Section 10.2.2_*
Max-Forwards *_Section 7.6.2_*
Proxy-Authenticate *_Section 11.7.1_*
Proxy-Authentication-Info *_Section 11.7.3_*
Proxy-Authorization *_Section 11.7.2_*
Range *_Section 14.2_*
Referer *_Section 10.1.3_*
Retry-After *_Section 10.2.3_*
Server *_Section 10.2.4_*
TE *_Section 10.1.4_*
Trailer *_Section 6.6.2_*
Upgrade *_Section 7.8_*
User-Agent *_Section 10.1.5_*
Vary *_Section 12.5.5_*
Via *_Section 7.6.3_*
WWW-Authenticate *_Section 11.6.1_*
header section *_Section 6.3_*
Host header field *_Section 7.2_*
http URI scheme *_Section 4.2.1_*
https URI scheme *_Section 4.2.2_*
I
idempotent *_Section 9.2.2_*
If-Match header field *_Section 13.1.1_*
If-Modified-Since header field *_Section 13.1.3_*
If-None-Match header field *_Section 13.1.2_*
If-Range header field *_Section 13.1.5_*
If-Unmodified-Since header field *_Section 13.1.4_*
inbound *_Section 3.7, Paragraph 4_*
incomplete *_Section 6.1_*
interception proxy *_Section 3.7, Paragraph 10_*
intermediary *_Section 3.7_*
L
Last-Modified header field *_Section 8.8.2_*
list-based field Section 5.5, Paragraph 7
Location header field *_Section 10.2.2_*
M
Max-Forwards header field *_Section 7.6.2_*
Media Type
multipart/byteranges *_Section 14.6_*
multipart/x-byteranges Section 14.6, Paragraph 4, Item 3
message Section 3.4; *_Section 6_*
message abstraction *_Section 6_*
messages *_Section 3.4_*
metadata *_Section 8.8_*
Method
* *_Section 18.2, Paragraph 3_*
CONNECT *_Section 9.3.6_*
DELETE *_Section 9.3.5_*
GET *_Section 9.3.1_*
HEAD *_Section 9.3.2_*
OPTIONS *_Section 9.3.7_*
POST *_Section 9.3.3_*
PUT *_Section 9.3.4_*
TRACE *_Section 9.3.8_*
multipart/byteranges Media Type *_Section 14.6_*
multipart/x-byteranges Media Type Section 14.6, Paragraph 4,
Item 3
N
non-transforming proxy *_Section 7.7_*
O
OPTIONS method *_Section 9.3.7_*
origin *_Section 4.3.1_*; Section 11.5
origin server *_Section 3.6_*
outbound *_Section 3.7, Paragraph 4_*
P
phishing *_Section 17.1_*
POST method *_Section 9.3.3_*
Protection Space Section 11.5
proxy *_Section 3.7, Paragraph 5_*
Proxy-Authenticate header field *_Section 11.7.1_*
Proxy-Authentication-Info header field *_Section 11.7.3_*
Proxy-Authorization header field *_Section 11.7.2_*
PUT method *_Section 9.3.4_*
R
Range header field *_Section 14.2_*
Realm Section 11.5
recipient *_Section 3.4_*
Referer header field *_Section 10.1.3_*
representation *_Section 3.2_*
request *_Section 3.4_*
request target *_Section 7.1_*
resource *_Section 3.1_*; Section 4
response *_Section 3.4_*
Retry-After header field *_Section 10.2.3_*
reverse proxy *_Section 3.7, Paragraph 6_*
S
safe *_Section 9.2.1_*
satisfiable range *_Section 14.1.1_*
secured *_Section 4.2.2_*
selected representation *_Section 3.2, Paragraph 4_*;
Section 8.8; Section 13.1
self-descriptive *_Section 6_*
sender *_Section 3.4_*
server *_Section 3.3_*
Server header field *_Section 10.2.4_*
singleton field Section 5.5, Paragraph 6
spider *_Section 3.5_*
Status Code Section 15
Status Codes
Final Section 15, Paragraph 7
Informational Section 15, Paragraph 7
Interim Section 15, Paragraph 7
Status Codes Classes
1xx Informational *_Section 15.2_*
2xx Successful *_Section 15.3_*
3xx Redirection *_Section 15.4_*
4xx Client Error *_Section 15.5_*
5xx Server Error *_Section 15.6_*
T
target resource *_Section 7.1_*
target URI *_Section 7.1_*
TE header field *_Section 10.1.4_*
TRACE method *_Section 9.3.8_*
Trailer Fields *_Section 6.5_*
ETag *_Section 8.8.3_*
Trailer header field *_Section 6.6.2_*
trailer section *_Section 6.5_*
trailers *_Section 6.5_*
transforming proxy *_Section 7.7_*
transparent proxy *_Section 3.7, Paragraph 10_*
tunnel *_Section 3.7, Paragraph 8_*
U
unsatisfiable range *_Section 14.1.1_*
Upgrade header field *_Section 7.8_*
upstream *_Section 3.7, Paragraph 4_*
URI *_Section 4_*
origin *_Section 4.3.1_*
URI reference *_Section 4.1_*
URI scheme
http *_Section 4.2.1_*
https *_Section 4.2.2_*
user agent *_Section 3.5_*
User-Agent header field *_Section 10.1.5_*
V
validator *_Section 8.8_*
strong *_Section 8.8.1_*
weak *_Section 8.8.1_*
Vary header field *_Section 12.5.5_*
Via header field *_Section 7.6.3_*
W
WWW-Authenticate header field *_Section 11.6.1_*
X
x-compress (content coding) *_Section 8.4.1_*
x-gzip (content coding) *_Section 8.4.1_*
Authors' Addresses โจ
Meet the crew who wrote this ๐ Roy, Mark and Julian, the editors who kept the whole thing together ๐ซถ
Roy T. Fielding (editor)
Adobe
345 Park Ave
San Jose, CA 95110
United States of America
Email: fielding@gbiv.com
URI: https://roy.gbiv.com/
Mark Nottingham (editor)
Fastly
Prahran
Australia
Email: mnot@mnot.net
URI: https://www.mnot.net/
Julian Reschke (editor)
greenbytes GmbH
Hafenweg 16
48155 Mรผnster
Germany
Email: julian.reschke@greenbytes.de
URI: https://greenbytes.de/tech/webdav/
๐ฆ where this page comes from
- ietf: rfc9110 2022-06
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms