The Hypertext Transfer Protocol is an application-level communication protocol for exchanging requests and responses about resources. In the client-server model, an HTTP request supplies an HTTP request method and target; an HTTP response supplies an HTTP status code and associated information. HTTP header fields convey metadata, and messages can carry content. These semantics are distinct from the particular wire format used by a protocol version.[ref]
For a concrete exchange, a client can send method GET for https://example.org/manual. A successful response can carry status 200 and an HTML representation of the resource. A response with status 404 instead says that the server did not find a current representation, or is unwilling to disclose one; successful communication does not require successful retrieval.[ref]
The request's URL identifies the target, while the response describes the outcome of this exchange. A later exchange can return different content or a different status. The protocol's stateless request semantics also do not prevent an application from maintaining state: the distinction concerns what a request must mean, not whether a user can have an ongoing session.[ref]
An HTTP cache key is the information an HTTP cache uses to choose a stored response. The standard's minimum basis comprises the request method and target URI, while additional request information can distinguish negotiated responses or partition storage. Common caches that store only GET responses can use the URI alone for that minimum basis.[ref]
For an own example, suppose a cache holds both JSON and HTML responses for GET /report, each with Vary: Accept. Their explanatory selection inputs are (GET, /report, Accept=application/json) and (GET, /report, Accept=text/html). The target and method agree, but the nominated field distinguishes the variants. Another matching request for JSON must not receive the HTML entry merely because its target is also /report.[ref]
A request for /report?page=2 also has a different target from /report. Sharing a path prefix is not enough to identify a stored response. The example's tuples describe selection information rather than prescribe a particular serialized key or database implementation.
Field matching itself follows the specification. It can include the normalization permitted for the nominated fields; comparing every raw header string byte for byte is not the general rule. A missing field and an arbitrary different value also cannot be silently treated as equivalent.[ref]
Selection and permission to reuse are separate steps. A matching stored response must still satisfy the applicable cache controls and HTTP freshness or validation requirements. An HTTP private cache and an HTTP shared cache differ in their scope and some controls, but neither can infer complete reuse permission from a key match alone.[ref]
The key becomes especially important with HTTP content negotiation: several representations can belong to one resource without being interchangeable for every request. Identifying the selection dimensions explains both correct reuse and why one broadly shared target identifier need not yield one universal cached body.
An HTTP shared cache stores HTTP responses for reuse by more than one user. It is often part of an intermediary, though that deployment is not required by the definition. An HTTP private cache is instead dedicated to a single user.[ref]
For an own example, suppose four users request the same public manual through one shared cache. The first request obtains a complete, cacheable response with a -octet body. Assume the following three requests match the required HTTP cache key inputs, arrive while the stored response remains reusable, and have no directives requiring forwarding. They can be satisfied from that stored response. The origin then sends the body once instead of four times, avoiding origin-body octets in this stipulated sequence. This does not count headers, validation traffic or delivery from the cache to the users.
Matching the target identifier alone need not be sufficient. If the response uses Vary: Accept, the relevant request-field matching rules also matter; one user's negotiated HTTP representation is not automatically suitable for another request's preferences.[ref] HTTP content negotiation and cache selection therefore interact.
Storage and reuse are separate decisions. The unqualified Cache-Control: private response directive forbids storage by a shared cache. Other responses must still satisfy the ordinary storage constraints, and the cache must consider HTTP freshness or successful HTTP cache validation when constructing a later response.[ref]
A shared cache also interprets s-maxage when present. For Cache-Control: max-age=600, s-maxage=60, its explicit freshness lifetime is sixty seconds rather than six hundred. This gives the origin a way to specify a shared reuse interval independently of the corresponding private-cache interval.[ref]
The benefit comes from reusing an eligible response across users, not from assuming all users receive identical content. State selection inputs and cache controls before extrapolating the simple manual example to personalized or negotiated resources.
An HTTP private cache is dedicated to a single user. It is often implemented as part of a user agent, but its defining property is the single-user scope rather than a particular machine or storage medium. An HTTP shared cache can instead reuse responses for multiple users.[ref]
Suppose a user's response carries Cache-Control: private, max-age=60. The unqualified private directive permits a private cache to store the response subject to the normal storage rules, while forbidding a shared cache from storing it. The max-age directive supplies its explicit HTTP freshness lifetime; it does not cancel the single-user storage restriction.[ref]
If the correctly calculated HTTP current age is twenty seconds, sixty seconds exceeds that age and forty seconds remain until the freshness boundary. Reuse still requires matching the relevant request and satisfying other applicable constraints. At current age sixty, the strict freshness comparison fails; HTTP cache validation may then establish whether the stored representation remains suitable.[ref]
Being private does not mean that every response must be stored or may be reused indefinitely. A cache can discard an entry, and an otherwise applicable restrictive directive remains significant. In particular, unqualified no-cache requires successful validation before subsequent reuse, whereas no-store prohibits the corresponding storage and reuse under its defined rules.[ref]
The word private is also a cache-control distinction, not an encryption mechanism or a promise that the message is inaccessible to everyone else. The standard explicitly separates those meanings. Correct HTTP cache key selection and response handling still matter inside a single-user cache.[ref]
For negotiated content, the stored representation can depend on request fields as well as the target. A private cache must therefore apply the same relevant matching rules rather than treating every request by its one user as interchangeable.
An HTTP trailer field is a message field carried in a trailer section after the content. It can provide metadata whose final value becomes available while the content is being generated or processed. Its placement lets a sender stream content before that metadata is complete.[ref]
For a concrete HTTP/1.1 example, define an illustrative extension field Example-Count to report the number of content octets and explicitly permit it in trailers. This is a definition for the example, not a standard field. A response can announce Transfer-Encoding: chunked and Trailer: Example-Count in its header section. Its following transfer-coded body, using visible escape notation, is 3\r\nabc\r\n0\r\nExample-Count: 3\r\n\r\n.
Here \r\n denotes a carriage-return/line-feed pair in the actual stream. The three-octet chunk supplies abc. The zero-sized chunk ends the chunks, and Example-Count: 3 then supplies the trailer metadata before the final empty line. The content is just abc; the trailer field is not appended to the representation data.[ref]
The initial Trailer field names metadata the sender anticipates sending. A recipient can use this announcement to prepare its processing, but it does not guarantee that every announced field will actually arrive. The field value itself remains in the later trailer section.[ref]
Placement is constrained by semantics. A sender must know that a field's definition permits trailer use; fields needed earlier for HTTP message framing, routing or content interpretation generally cannot simply be moved to the end. A recipient must not merge trailer fields into the header section unless their definitions explicitly permit and define the merge.[ref]
Trailers can also be discarded in transit, so an application cannot assume that arbitrary metadata placed there will reach or be acted upon by every recipient. Keeping HTTP trailer fields distinct from HTTP header fields preserves the distinction between information available before content processing and information learned afterwards.[ref]
HTTP freshness describes whether a stored HTTP response is young enough for reuse according to its applicable lifetime. The comparison is
The strict inequality matters: a response exactly at its lifetime boundary is no longer fresh.[ref]
The HTTP freshness lifetime can come from explicit cache controls or, where permitted, a heuristic. The HTTP current age accounts for age accumulated before the response entered the present cache as well as its residence there. Counting only the seconds since this cache received the response can therefore underestimate its age.[ref]
For an own example, suppose the applicable lifetime is seconds and the correctly calculated current age at a chosen instant is seconds. Keep the lifetime fixed. After another seconds, the age is , so and the response remains fresh. After another seconds from the original instant, the age is and the strict comparison fails. After seconds it is , again stale. These calculations start from a given current age; they do not derive it from local residence time alone.
Freshness and HTTP cache validation answer different questions. An old response might still match the origin's present HTTP representation. Validation can establish that reuse remains appropriate without retransmitting the representation body. Conversely, a fresh response has not thereby been checked against the origin at every use.[ref]
Other rules still govern reuse. For example, the unqualified Cache-Control: no-cache response directive requires successful validation before subsequent use, even though the response can be stored. Stale-serving rules also have explicit conditions. A freshness calculation is therefore one part of deciding whether a stored HTTP response may satisfy a particular request, rather than a complete permission test.[ref]
HTTP current age is a cache's estimate of an HTTP response's age at the time it is considered for reuse. It includes age accumulated before the response reached this cache and the time it has since spent there. The received Age field is therefore an input to the calculation, not generally the response's current age at every later instant.[ref]
Write for the request time, for response receipt, for now, for the Date value and for the received Age value, all in compatible seconds. The RFC defines HTTP apparent age and HTTP response delay through
It permits as the corrected initial age. For paths with very old caches, it also gives the more conservative choice
The current age then adds local residence:
The maximum-based choice is an allowed conservative alternative, not the only permitted initial-age calculation.[ref]
For an own clock example, set , , , and . Assume adequately synchronized clocks and use the conservative choice. Apparent age is , response delay is , and corrected age is . Thus
Using only local residence would have produced six seconds and substantially understated the estimated age.
If the HTTP freshness lifetime is seconds, this response is fresh at the example's current time because . At , its age reaches and that strict comparison fails. HTTP freshness still does not replace the other rules governing cache reuse or HTTP cache validation.
The calculation combines local intervals with metadata supplied by other machines. The apparent-age route assumes reasonable clock synchronization, while the delay-corrected route accounts for time spent obtaining the response. Treating Date or Age as a simple local stopwatch reading would lose those distinctions.[ref]
In the HTTP current age calculation, HTTP response delay is the interval between the cache's request time and the time it receives the corresponding HTTP response:
The interval corrects the age information carried in the response for time spent obtaining it. It is one input to cache-age estimation.[ref]
For an own example, a cache initiates a request at local time seconds and receives the response at . Its response delay is seconds. If the response carries Age: 12, the RFC's delay-corrected value is
After another four seconds of local residence, using that corrected initial age would give seconds of current age.[ref]
This interval does not isolate server computation. Transport, waiting and response handling can all contribute; a single elapsed interval does not reveal their separate amounts. Likewise, the received Date value comes from response metadata rather than defining either local endpoint of this subtraction.
The RFC permits the corrected age value as the corrected initial age. It also gives a conservative alternative that takes the maximum of that value and HTTP apparent age, particularly for paths involving old caches that might not supply appropriate Age information. The example uses the delay-corrected route explicitly instead of silently assuming both routes always agree.[ref]
A correct elapsed-time calculation matters because HTTP freshness compares the resulting age with an HTTP freshness lifetime. Treating a received response as age zero simply because it has just reached the local cache would discard both the received age estimate and the acquisition interval.
HTTP apparent age estimates the age of an HTTP response at receipt by comparing its Date value with the receiving cache's clock. With receipt time and date value expressed in compatible seconds,
The nonnegative clamp prevents a negative age when the date appears to lie in the receiver's future. The RFC describes this estimation route as relying on reasonable clock synchronization.[ref]
For example, receipt time and date value give an apparent age of six seconds. With receipt time and date value , the result is instead
This zero does not establish that the representation was generated at the instant of receipt. A disagreement between clocks can conceal age in this comparison.
Another estimation route uses the received Age value and HTTP response delay. Suppose a request starts at , its response arrives at , the date value is and the received age is ten seconds. The apparent age is zero, while the delay-corrected value is . The RFC's conservative maximum-based initial estimate therefore gives fourteen seconds rather than zero.[ref]
After six more seconds in this cache, that initial estimate gives HTTP current age . Apparent age itself is the receipt-time estimate; adding local residence belongs to the later current-age calculation. Keeping those stages distinct avoids adding the wrong interval or treating the original estimate as a permanently current value.
The result feeds HTTP freshness rather than replacing the full reuse decision. A small apparent age does not override cache controls, validate the current origin state or make every stored response eligible for reuse. It is useful precisely as one defined estimate with explicit inputs and assumptions.
The HTTP freshness lifetime is the duration against which an HTTP response's HTTP current age is compared to determine HTTP freshness. It can be specified explicitly or, where allowed, estimated by a cache. It is not the same as the amount of fresh time remaining: that depends on the response's current age as well.[ref]
For valid explicit metadata, the RFC applies the first relevant rule. An HTTP shared cache uses s-maxage when present; otherwise max-age applies. If neither applicable directive is present, Expires supplies an expiration time from which the response's Date is subtracted, with the specified receipt-time fallback when Date is absent. Only when there is no explicit expiration time can HTTP heuristic freshness be applicable.[ref]
Consider a response with Cache-Control: max-age=600, s-maxage=60. An HTTP shared cache, which serves more than one user, takes a -second lifetime. An HTTP private cache, dedicated to one user, uses seconds instead. Assume the response otherwise satisfies the relevant storage and reuse rules.[ref]
At current age seconds, the shared cache has seconds until its freshness boundary, while the private cache has . At age , the shared response is no longer fresh because is false; the private cache's comparison still succeeds. These are two cache policies for the same response metadata, not conflicting estimates of the response's age.
HTTP heuristic freshness is constrained estimation, not an instruction to assign every response an arbitrary lifetime. The RFC allows heuristics under specified conditions and does not prescribe one universal estimation algorithm.[ref]
Finally, a computed lifetime does not override every other directive. Conflicting controls require the restrictive handling specified by the RFC; a freshness calculation also does not force a user agent to refresh its visible page. The lifetime governs cache operation, while the complete reuse decision still depends on the request and applicable response rules.[ref]
HTTP heuristic freshness estimates an HTTP freshness lifetime when a stored HTTP response lacks explicit expiration information and is otherwise eligible for that treatment. It allows constrained reuse when the origin has not supplied a lifetime, without pretending that the origin explicitly guaranteed one.[ref]
Eligibility comes first. The RFC permits heuristics for otherwise allowed responses that are heuristically cacheable by status or explicitly marked cacheable, when explicit freshness information is absent. A cache must not replace an explicit expiration time with its own heuristic. The ordinary storage constraints still apply.[ref]
For an own example, assume a successful response satisfies those conditions and has no restrictive directives. Its Date corresponds to time seconds and Last-Modified to seconds. Choose a cache policy that fixes its lifetime at one tenth of the interval between those timestamps:
At HTTP current age seconds, and fifteen seconds remain until the freshness boundary. At age , the strict comparison fails.
The fraction and exact timestamp policy are stated assumptions of this example. The RFC encourages a fraction of the interval since modification and mentions ten percent as a typical setting, but does not prescribe a universal heuristic algorithm or require that fraction.[ref]
A long time since modification is evidence useful to an estimate; it is not proof that the origin will remain unchanged for the chosen lifetime. HTTP cache validation can later check whether a stored representation remains suitable. Different permitted heuristics can also produce different lifetimes from the same metadata.
An HTTP private cache and an HTTP shared cache must each respect the applicable caching constraints; being private or shared does not authorize arbitrary estimation. When an origin needs explicit freshness behavior, an explicit control such as max-age avoids relying on the cache to infer that lifetime.[ref]
An HTTP persistent connection carries more than one HTTP request/HTTP response exchange over the same connection. HTTP/1.1 uses persistence by default unless its connection rules indicate closure. Reusing the connection avoids establishing a separate connection for every exchange.[ref]
For a sequential example, a client retrieves /color and reads a response with Content-Length: 4 followed by blue. It then requests /shape on the same connection and reads Content-Length: 6 followed by circle. These are two distinct requests and two distinct responses, each with its own control information and HTTP message framing. Neither resource name nor method is inherited merely because the connection is reused.
This example relies on being able to finish the first message without closing the connection. To retain persistence, the message lengths must be self-defined rather than delimited by closure. A server must read the complete request body or close the connection after responding; otherwise leftover body bytes could be mistaken for a new request. A client likewise must consume the complete response body before reusing the connection.[ref]
Connection: close signals that the connection will close after the current response. Persistence is not a promise of an unlimited lifetime: a connection can also close unexpectedly. Whether an outstanding operation can be retried automatically depends on its semantics, particularly HTTP idempotence, rather than on the fact that the connection had previously been reusable.[ref]
Persistence also does not require sending requests before earlier responses arrive. That additional option is HTTP pipelining; in HTTP/1.1, the corresponding responses must retain request order. The sequential example uses persistence without pipelining.[ref]
HTTP pipelining sends several HTTP requests on one HTTP persistent connection without waiting for each corresponding HTTP response before sending the next request. In HTTP/1.1, the server must send the responses in request order, even when it can process requests in parallel. Parallel processing of the sequence is permitted when its methods are all HTTP safe methods.[ref]
For example, a client can send independent GET requests for /a, /b and /c before receiving the response for /a. The response for /a must come first, followed by those for /b and /c. Each response still needs correct HTTP message framing; persistence and pipelining do not merge three responses into one representation.
A simple timing model shows the motivation. Suppose an established connection has a round-trip propagation time of milliseconds, every request takes milliseconds of server processing, the server processes them sequentially, and transmission times are negligible. Waiting for each complete response before submitting the next gives arrival times , and milliseconds at the client. Sending all three requests at time zero lets them reach the server together after milliseconds; their processing finishes at , and milliseconds, so responses arrive at , and milliseconds. These are stipulated model calculations, not measured browser performance.
Ordered responses also impose head-of-line blocking. If the first response cannot be completed promptly, a later response cannot pass it on this connection even if its computation is ready. The processing order and the permitted transmission order are therefore different constraints.
Pipelining also requires care after a failed connection: retrying outstanding requests is governed by method semantics and the protocol's recovery rules. HTTP idempotence helps determine when automatic repetition is justified. A client must not interpret the disappearance of a connection as proof that none of its outstanding operations took effect.[ref]
HTTP message framing determines where an HTTP request or HTTP response ends and whether it is complete. The concrete rules depend on the protocol version. In HTTP/1.1, an empty line ends the header section, but the end of the message body requires the applicable length, transfer-coding or connection rules. A body can itself contain line breaks.[ref]
Consider an ordinary successful response to GET whose text is café in UTF-8. Its four displayed letters occupy five octets, with hexadecimal values 63 61 66 c3 a9. With no transfer coding and no overriding bodyless-response rule, Content-Length: 5 therefore frames this body. Counting displayed characters would give the wrong boundary.[ref]
An alternative is chunked transfer coding. Use Transfer-Encoding: chunked instead of the content-length field. The body can then be written in visible escape notation as 2\r\nca\r\n3\r\nfé\r\n0\r\n\r\n. Here \r\n denotes an actual carriage-return/line-feed pair, and the text is encoded in UTF-8. The first chunk supplies two octets; the second supplies three; the zero-sized chunk and empty trailer section finish the coding. This transfer-coded body occupies twenty octets and yields the same five content octets after decoding.[ref]
Precedence matters. Responses to HEAD and responses with status 1xx, 204 or 304 have no message body even when fields appear to suggest a length. Some responses instead end with connection closure; requests are not close-delimited. Receiving fewer than the declared number of octets leaves a length-delimited message incomplete.[ref]
Framing is separate from media type: a recipient first needs to delimit the transmitted data, then interpret its format. It also makes HTTP persistent connections possible, since a recipient can finish one exchange without treating connection closure as the only indication of completion.
Chunked transfer coding is a HTTP/1.1 transfer coding that wraps content in successive chunks, each preceded by its size in hexadecimal. It supplies HTTP message framing without requiring the sender to know the entire content length before starting transmission. The last chunk has size zero and is followed by any HTTP trailer fields and a final empty line.[ref]
A response using this coding declares Transfer-Encoding: chunked. An own example of its complete body, written with visible escape notation, is A\r\nabcdefghij\r\n3\r\nXYZ\r\n0\r\n\r\n. Each \r\n denotes an actual carriage-return/line-feed pair; the other displayed characters are ASCII. Decode it as follows: A is hexadecimal ten, so consume the ten octets abcdefghij and their following line ending. The next size is three, so consume XYZ and its line ending. Zero then ends the chunks, and the final empty line ends the empty trailer section.
The recovered content is abcdefghijXYZ, with thirteen octets. This example's transfer-coded body occupies twenty-eight octets: fifteen for the first chunk, eight for the second, and five for the terminating zero-size line and empty trailer section. Those counts exclude the response start line and header section. Chunking provides boundaries; this example increases the number of transmitted octets rather than performing data compression.
A decoder must follow the declared octet counts. Chunk data can contain line endings of their own, so splitting the entire body into text lines is not a substitute for parsing the sizes. A sender can generate chunks progressively and retain an HTTP persistent connection after the message ends.[ref]
The empty trailer section in the example can instead contain permitted HTTP trailer fields, for metadata available only after generating the content. These have their own applicability rules and cannot simply be merged indiscriminately into the earlier fields. If the stream ends before the terminating zero-sized chunk arrives, the message is incomplete.[ref]
An HTTP conditional request carries one or more preconditions to be evaluated before applying its HTTP request method. The condition can ask whether the selected HTTP representation still has a previously observed entity tag. This makes the request depend on the state the client knows, rather than applying an operation unconditionally.[ref]
For HTTP cache validation, suppose an earlier retrieval of /color stored the text blue with entity tag "v7". A later GET with If-None-Match: "v7" asks for the representation only if its tag no longer matches. If the selected representation still matches, the condition is false and the server returns status 304 instead of transferring the representation data again. If it has changed, an otherwise successful retrieval can return the new data.[ref]
A second use prevents overwriting another client's work. Suppose two clients read version "v7". The first makes an update and the server assigns version "v8". The second submits a different PUT with If-Match: "v7". The stale tag does not match, so the server must not apply that update; in this example it returns 412. Checking and applying the condition as part of the operation prevents the second client from silently replacing the first client's changes.[ref]
The two field names deliberately use different comparisons: If-Match requires strong entity tag comparison, while If-None-Match uses weak comparison and can match a weak entity tag. Failed If-Match need not always yield 412: the specification permits a success response when the requested change appears already applied. Authentication, redirects and other normal request checks also precede precondition evaluation. An HTTP conditional request therefore combines method semantics, a particular condition and the specified evaluation order.
HTTP cache validation checks whether a stored HTTP response remains suitable for reuse, commonly by sending an HTTP conditional request containing a validator such as an entity tag. It supports reusing stored representation data while checking with a server whether the relevant state has changed.[ref]
Validation and HTTP freshness answer different questions. A stored response may still be fresh according to its lifetime and age, allowing reuse under the applicable rules without this exchange. A response that is no longer fresh is not thereby known to have different content at the origin: validation can establish that reuse remains appropriate.[ref]
Suppose a cache stores a successful /manual response with a -octet body and entity tag "manual-4". Assume that it is otherwise eligible for reuse after successful validation. A later GET sends If-None-Match: "manual-4". If the selected HTTP representation still matches, the origin returns 304 without a representation body. The cache identifies the matching stored response, updates its fields according to the validation rules, and reuses its stored data.[ref][ref]
In that unchanged branch, the origin avoids retransmitting the representation-body octets. The validation request and response still have a cost; the body count alone is not a measurement of total network savings. Nor is 304 an empty replacement document: the useful data are the body already held by the cache.
If the selected representation changed, an otherwise successful validation request can instead receive a full response with its new data. The cache uses that response to satisfy the request and may store it subject to the ordinary storage constraints.[ref] A validator alone does not make every stored response reusable: selection inputs, applicable cache controls and the result of validation still matter.
The comparison rule also matters. If-None-Match uses weak entity tag comparison, so HTTP cache validation can accept the server's declared equivalence through a weak entity tag. An update requiring an exact precondition through If-Match instead uses strong entity tag comparison.[ref]
HTTP/1.1 is a version of the Hypertext Transfer Protocol with a specified message syntax, parsing rules and connection behavior. Its shared method and status meanings come from the broader HTTP semantics; its concrete messages use a start line, field lines, an empty line and any permitted message body.[ref]
A short response can be represented with visible escape notation as HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\nblue. Here \r\n denotes the carriage-return/line-feed pair in the actual byte stream, rather than four literal characters. The body is the four bytes spelling blue; the empty line separates it from the header section.
This illustrates HTTP message framing: a recipient needs rules for locating the end of one message before interpreting subsequent bytes. In this example, the declared content length identifies four body bytes. Other permitted cases have their own framing rules; a line break inside body data is not automatically a new message.[ref]
An HTTP persistent connection can carry multiple exchanges rather than requiring a fresh connection for each message. Persistence does not imply that a previous request's method or target is silently inherited by the next one; each request still has its own defined control information.[ref]
Distinguish this wire format from the abstract HTTP request and HTTP response. A different HTTP version can encode control information differently while retaining shared meanings such as GET or status 200. Likewise, the protocol version alone does not identify the media type of a returned representation.
An HTTP representation consists of data and metadata describing a selected state or form of a resource. It is the information transferred or referenced to express that resource, rather than the resource identifier itself. A resource can have more than one available representation.[ref]
For an invented /color resource, one representation is the plain-text bytes blue with type text/plain. Another is an HTML document displaying the same color information, with type text/html. The underlying application value can agree while the bytes and media types differ. HTTP content negotiation can help select among available representations according to request information.
An HTTP response also contains control information about the exchange, such as its HTTP status code. It is not simply another name for representation data. A HEAD response, for example, can describe a selected representation without transferring its content, while a GET can transfer that content.[ref]
Representation metadata tells a recipient how to interpret the data. A media type concerns format, character-set information concerns text encoding, and an entity tag supplies a validator for the selected representation. These properties can differ between two forms of the same resource.
A URL therefore does not promise one immutable byte sequence. A resource can change with time or offer different forms; conversely, matching application meaning does not require byte-identical representations. When comparing responses, record which representation was selected and compare the relevant data and metadata rather than only the identifier.
HTTP content negotiation provides mechanisms for choosing among available HTTP representations, for example different formats, languages or content encodings. One resource can have several representations without requiring that its identifier change for every preference.[ref]
For a concrete example, stipulate that /color offers both an HTML representation and plain text. A client sends Accept: text/html;q=0.8, text/plain;q=0.5. The weights express a preference for HTML. If this server honors that ranking and both choices are available, it selects HTML and declares Content-Type: text/html. The Accept request field describes preferences; the Content-Type response field identifies the selected media type.[ref]
The quality weight q lies between zero and one, defaults to one when omitted, and uses zero for an unacceptable choice. These weights are preference values, not probabilities. The example stipulates a server policy; it is not a claim that all servers must select by a universal maximum-weight algorithm.[ref]
In HTTP proactive negotiation, the server makes its choice using information from the request. A response field Vary: Accept indicates that the request's Accept value might influence selection. This matters when reusing a stored response: the resource identifier alone need not describe every relevant selection input.[ref]
In HTTP reactive negotiation, the client selects after receiving an initial response containing alternatives, potentially making a further request. This can expose the choices directly but can require an additional exchange. Neither mechanism guarantees that every requested representation exists, nor that the server knows the user's eventual purpose.[ref]
HTTP reactive negotiation is HTTP content negotiation in which the client selects a representation after receiving an initial response identifying alternatives. The mechanism can be as simple as links to the available forms. The specification also calls this agent-driven negotiation.[ref]
For an invented example, a client requests /report. The response presents links to /report.html and /report.json, describing the available HTML and JSON forms. A person or client program chooses JSON and requests /report.json. The server then returns that representation. The first response can already contain useful content alongside its alternatives; reactive selection does not require it to be an otherwise empty menu.
The specification discusses alternatives in responses with status 300 or 406, but the defining feature is the client's selection after the first response. The example's suffixes are application conventions: an HTTP representation's actual media type is described by its response metadata, rather than established by a filename alone.[ref]
An extra request can add delay. In a toy model with an established connection, milliseconds per complete request/response exchange, negligible processing and transmission time, and no existing copy of the alternatives, fetching the menu and then a chosen representation takes milliseconds. A correct HTTP proactive negotiation choice in one exchange would take milliseconds under those same assumptions. These numbers illustrate the additional dependency, not a universal measured performance difference.
The tradeoff can be worthwhile when the client knows requirements that the server cannot infer, or when alternatives can be reused effectively. The server exposes the choices instead of guessing the user's preference. The standard does not prescribe a general automatic selection algorithm for the client, so providing alternatives does not itself establish that every client will make or follow a choice.[ref]
HTTP proactive negotiation is HTTP content negotiation in which the server selects an HTTP representation using information in the client's request. Explicit preferences can describe acceptable media types, languages or content encodings; the server can also use implicit request characteristics. The specification also calls this server-driven negotiation.[ref]
Suppose /report offers both JSON and HTML. A client sends Accept: application/json, text/html;q=0.5. The omitted quality weight for JSON defaults to one, so the request expresses a stronger preference for JSON than for HTML. If the server honors this ranking and both forms are available, it returns the JSON form with Content-Type: application/json.[ref]
This can deliver the preferred representation in the first response. The client does not first need to retrieve a menu of alternatives and then make another choice. In contrast, HTTP reactive negotiation leaves selection to the client after an initial response identifies alternatives. Either approach still requires the application to decide what the available representations mean.
A server selecting on Accept can send Vary: Accept. That field identifies an additional request dimension that might affect the response, beyond the method and target identifier. A stored response chosen for one Accept value is consequently not automatically the appropriate selection for another; caching must account for the relevant variation.[ref]
The server's information is incomplete. A supported format need not be the best format for the user's intended task, and describing capabilities in every request can increase message size and disclose information about the client. The specification also permits servers to disregard negotiation preferences rather than return 406 when honoring them would leave no acceptable choice. The example's ranking policy is therefore a stated application assumption, not an unconditional protocol guarantee.[ref]
An HTTP request method identifies the operation requested for an HTTP request's target. The target and method have separate roles: the same resource can be read, replaced or processed according to the chosen method and its defined semantics. Method tokens are case-sensitive.[ref]
For example, an invented /color resource uses GET to retrieve its current color and PUT to replace that color with the supplied value. One PUT storing blue and two identical such operations leave the same intended color. A different /log resource is stipulated to append each POST value: two appends of x then produce two entries. The append behavior belongs to this example application; it is not a universal definition of every POST.
HTTP idempotence concerns repeated intended effects, not identical response messages. A repeated replacement can leave the same state while returning a different HTTP status code because the resource already exists. An HTTP safe method requests essentially read-only semantics; incidental activities such as logging do not make every safe request a request to change the resource.[ref]
Cacheability is another property, governed by method and response rules rather than by idempotence alone. Interpret the HTTP request method, HTTP header fields and HTTP response together before deciding what a repeated or cached exchange means.[ref]
HTTP idempotence means that multiple identical requests have the same intended server-side effect as one request. It concerns the requested resource operation, rather than requiring every part of server state or every returned message to remain identical. The HTTP request methods defined as idempotent include PUT, DELETE and the HTTP safe methods.[ref]
A small state model makes the distinction precise. Let indicate whether a resource exists, and model deletion by . Then
Deleting again cannot make the resource more absent. Contrast an application operation that appends an item to a list: applying it twice can add two items.
For an invented endpoint, suppose a first DELETE removes an item and returns 204, while a second returns 404 because it is already absent. The intended final existence state agrees after one or two requests, although the HTTP status codes differ. These particular responses are stipulated for the example, not required for every deletion endpoint.
Idempotence also differs from read-only behavior. The first deletion can change a resource, whereas an HTTP safe method requests essentially read-only semantics. Separate logging or revision history can change on repeated requests without contradicting idempotence of the intended operation.[ref]
This property matters when a connection fails before a client receives the response: repeating an idempotent request can recover the intended result without needing to know whether the earlier attempt completed. It does not establish that the operation was executed only once. A method without a general idempotence guarantee can still implement a particular application operation that is idempotent, but that requires additional knowledge of its semantics.[ref]
An HTTP safe method has essentially read-only requested semantics: the client does not ask the server to change resource state through the operation. GET and HEAD are examples. The definition concerns what the operation requests, rather than asserting that no incidental activity occurs anywhere on the server.[ref]
For example, reading a stored color can return blue while leaving that color unchanged. The server can still append an access-log entry. A later read can return red if some separate operation changed the color in between; safe semantics do not require an unchanging response or an immutable resource.
At the intended-state level, a read-only operation can be modeled as . It follows immediately that
This illustrates why safe methods are also idempotent. The converse fails: deletion can map both present and absent states to absent, satisfying HTTP idempotence while changing a present resource on its first application.
The chosen HTTP request method remains meaningful even when the target URL contains a query string. Naming a destructive action in a query does not redefine GET as a method for requesting that action; the standard requires such actions to be disallowed when accessed through safe methods.[ref]
Use this term for protocol semantics. Successful transfer, access permission and the truth of returned application data are separate questions. Interpret the method with the target and application contract, rather than deciding safety from whether a response happens to contain a body.
An HTTP header field is named information carried in an HTTP message's header section. Its definition determines how its value is interpreted. Field names are case-insensitive, while values follow the rules of their particular field rather than one universal casing rule.[ref]
For example, ETag: "AbC" and etag: "abc" use the same field name but different entity tags. The quoted opaque strings are compared character by character under the relevant tag-comparison rules. Lowercasing both names is harmless for identifying the field; lowercasing all values would erase a real distinction.[ref]
Other fields express different kinds of information. Content-Type: text/plain; charset=utf-8 describes a media type and character encoding for content. It does not contain the content itself, and its meaning cannot be inferred by applying the entity-tag grammar to it.
In HTTP/1.1, a textual field line places a colon between the name and value; an empty line terminates the header section. This is a wire-format example, not a requirement that every HTTP version transmit identical text lines.[ref]
Repeated field occurrences also need their own semantics. Some can be combined as ordered lists, but treating every header section as a dictionary with exactly one value per name can lose information. Read the field definition before combining lines or rearranging values.[ref]
An entity tag is an opaque validator associated with a selected HTTP representation and commonly supplied in an ETag HTTP header field. It allows requests to refer to a previously observed version or equivalence class without interpreting the representation's contents. The tag's spelling need not reveal how the server generated it.[ref]
A strong entity tag has no weak marker; a weak entity tag has the prefix W/. Strong comparison succeeds only when both tags are non-weak and their opaque values match character by character. Weak comparison checks the opaque values while ignoring whether either tag is marked weak.[ref]
For example, "v1" and W/"v1" match weakly but not strongly. Two occurrences of "v1" match under either comparison. Tags "AbC" and "abc" match under neither: field-name case insensitivity does not make the opaque value case-insensitive.
A useful HTTP conditional request illustrates the purpose. Suppose a client retains representation data tagged "v1", then sends GET with If-None-Match: "v1". If the selected current tag matches, this precondition fails and the server returns 304 without transferring that response content. The retained data can then be used according to the applicable caching rules. If-None-Match uses weak comparison, while If-Match uses strong comparison.[ref]
An entity tag is therefore a protocol validator, not an instruction to lowercase or decode its opaque string. Different representations of one resource can require different validators. Compare the tag for the selected representation under the comparison rule required by the field, rather than assuming that equal resource URLs alone establish equal data.
A weak entity tag is an entity tag explicitly marked W/ whose validation guarantee does not require distinguishing every change to the HTTP representation data. A server may group representations it regards as suitable substitutes, rather than identify each distinct sequence of bytes. The weak marker is case-sensitive.[ref]
For an invented example, an HTML resource sometimes ends its source with an extra newline. Stipulate that this does not change its relevant rendered meaning and that the server considers both forms interchangeable for reuse. It can retain W/"page-4" across those two forms. It should change the tag when it no longer regards an older representation as an acceptable substitute. This policy is a server decision, not a license for clients to ignore arbitrary differences.[ref]
Weak comparison ignores whether a tag is marked weak but still compares the opaque value character for character. Consequently W/"page-4" weakly matches both W/"page-4" and "page-4"; it does not match W/"Page-4". Strong comparison fails whenever either operand is a weak entity tag, even when their opaque values agree.[ref]
This distinction supports HTTP cache validation. An HTTP conditional request with If-None-Match: W/"page-4" uses weak comparison, so a matching selected representation can produce 304 for GET. An update protected by If-Match instead requires a strong entity tag comparison and cannot obtain that guarantee from this weak tag.[ref]
Weakness concerns the strength of the equivalence assertion. It does not mean that the tag is malformed, that an exchange failed, or that its opaque text measures how similar two representations are.
A strong entity tag is an entity tag that satisfies HTTP's strong-validator requirements. Its value must change whenever the HTTP representation data change in a way observable in a successful GET response. Its syntax has no weak W/ prefix, for example "revision-7".[ref]
Suppose a resource serves the four bytes blue with tag "revision-7". Changing the first byte to produce Blue requires a different strong entity tag, even if the application regards the capitalization difference as unimportant. A revision counter can implement this example, but the client must treat the quoted tag as opaque: the syntax does not promise that a number can be parsed or incremented to predict the next tag.[ref]
Strong comparison succeeds only when both entity tags are strong and their quoted opaque values match character for character. Thus "revision-7" matches "revision-7", but not W/"revision-7" and not "Revision-7". Removing the weak marker in a client would change the meaning of the validator rather than upgrade the server's guarantee.[ref]
An HTTP conditional request using If-Match requires strong comparison. This is useful when an update should proceed only against the representation the client previously observed. The guarantee is scoped to the resource: identical tag text on two unrelated resources does not establish that their data are equal. Conversely, a strong validator may change for a relevant metadata change as well as a data change, so a changed tag alone is not a byte-by-byte difference report.[ref]
An HTTP status code is a three-digit code in an HTTP response describing the outcome or progress of handling an HTTP request. Its first digit identifies a broad class: informational 1xx, successful 2xx, redirection 3xx, client-error 4xx or server-error 5xx. The particular code and request method refine the meaning.[ref]
For an invented /color resource, a PUT can store blue and return 204 to indicate successful fulfillment without response content. A later GET can return 200 with the text blue. A HEAD response can also have status 200 while carrying no response content. Thus a successful code does not by itself determine whether there is a body to read.[ref]
In HTTP/1.1, a status line might be written HTTP/1.1 200 OK. The numerical code supplies the standardized status; the accompanying reason phrase is optional and is not the authority for interpretation. Changing the descriptive phrase does not redefine code 200.[ref]
An HTTP status code describes this exchange rather than proving that every application-level goal succeeded. A request can be transferred correctly and still receive an error status. Conversely, receiving 200 does not establish that an application-specific calculation inside the returned content is correct. Interpret status, HTTP header fields, content and the application's contract together.
An HTTP response is a message returned in response to an HTTP request, carrying an HTTP status code, associated HTTP header fields and any permitted content. An exchange can include informational responses before its final response.[ref]
For an invented plain-text resource, a successful GET can return status 200, Content-Type: text/plain; charset=utf-8 and the content blue. These four letters occupy four bytes in UTF-8, so a corresponding content length is four. The HTTP representation's data, its media type and the status describing this exchange have different roles.
A response need not contain a representation body. A successful PUT can return 204 without response content, and a HEAD response carries no content even when the corresponding GET would retrieve data. Interpreting a response therefore requires the request method as well as the status code.[ref]
In HTTP/1.1, HTTP/1.1 200 OK is a possible status line, followed by field lines, an empty line and any message body allowed by the framing rules. This spelling is one version's concrete syntax for the broader response abstraction.[ref]
The received content can change between requests while the resource identifier stays the same. Conversely, the same content can accompany different exchange metadata. Inspect status, fields and content together instead of treating any one of them as the entire response or as a guarantee of an application-specific result.
An HTTP request is a message asking a server to apply an HTTP request method to a target resource. It includes control information and HTTP header fields, and can include content according to the applicable method and message rules. Its meaning is distinct from the textual framing used by one protocol version.[ref]
For an illustrative HTTP/1.1 request, the line GET /color?view=plain HTTP/1.1 selects a method and request target, while Host: example.org supplies host information. An empty line ends the header section. These pieces belong to the version's request-line and field syntax.[ref]
Starting from https://example.org/color?view=plain#legend, the ordinary origin-form target is /color?view=plain. The query string participates in that target, while the fragment identifier does not: fragment processing is performed on the client side rather than by including the fragment in the target sent to the server.[ref][ref]
The method cannot be inferred from a content string alone. Sending the text blue to an endpoint stipulated to replace a color and sending it to an endpoint stipulated to append a log entry request different operations. The target, method and application contract supply that distinction.
An HTTP request also differs from a returned HTTP response. A successfully transmitted request can receive an error status, and a connection can end before a final response is obtained. Reasoning about the requested operation, its eventual outcome and the transport event as separate observations makes failures easier to interpret.

Articles by others on the same topic (0)

There are currently no matching articles.