The Hypertext Transfer Protocol (HTTP) is an application-layer protocol for communication between clients and servers on the Internet and other computer networks. It provides a common framework for identifying resources, requesting operations on them, and exchanging representations of their state or content. Originally developed for the World Wide Web, HTTP carries not only HTML documents but also images, audiovisual content, application data, and many other kinds of information. Its clients include web browsers, automated programs, and software communicating through an application programming interface.
HTTP uses a request–response model: a client sends a request containing a method and a target, and a server returns a response containing a status code and, when appropriate, content. Methods, status codes, fields, caching rules, and representation metadata have shared meanings across protocol versions, while their transmission mechanisms differ. HTTP/1.1 uses a textual message format, HTTP/2 introduces binary framing and multiplexed streams over TCP, and HTTP/3 maps HTTP onto QUIC. HTTPS denotes HTTP communication secured using Transport Layer Security, providing confidentiality, integrity, and server authentication.
HTTP's importance extends beyond document retrieval to distributed applications, content delivery, and service integration. Its design combines extensible messages with mechanisms for caching, conditional requests, authentication, and communication through intermediaries. Understanding HTTP therefore involves both its standardized semantics and its interaction with transport protocols, security systems, browser policies, and large-scale network infrastructure.
Architectural Model and Protocol Scope
HTTP is an application-layer protocol for exchanging requests and responses about resources. Its shared semantics, specified in RFC 9110 (2022), define the meaning of request methods, response status codes, fields, and representation metadata independently of a particular transmission format. A resource is an identifiable target of interaction, not necessarily a stored file: it can be a document, a current weather report, a collection of orders, or a service that performs a calculation. A representation consists of information reflecting a resource’s current or desired state, together with metadata describing that information. Thus, a weather resource can provide an HTML page or a JSON document without becoming two fundamentally different subjects merely because their formats differ. A connection, by contrast, is a communication mechanism carrying messages; it is neither the resource nor its representation.
The roles of client and server apply to particular exchanges rather than permanently identifying machines or software products. A client sends a request, and a server receives it and sends a response. A user agent is the client program that initiates a request, such as a web browser, command-line retrieval tool, or automated application. An origin server is the program capable of producing authoritative responses for a target resource. It need not keep that resource in a local file: it can generate a representation from a database, execute application logic, or consult other services. For example, an order-processing application acts as a server when answering a browser’s request and as a client when requesting shipping information from another service.
An intermediary participates between a user agent and an origin server. A forward proxy is selected by a client to forward requests, whereas a gateway, commonly called a reverse proxy, presents itself to the client as the origin-facing service and forwards requests toward other servers. In an ordinary forwarding exchange, an intermediary acts as a server on its incoming connection and as a client on its outgoing connection. Consequently, one logical request can traverse several separate connections before reaching its origin. Those connections may use different HTTP versions while preserving the request’s meaning. Connection boundaries therefore do not necessarily coincide with application boundaries or with the endpoints responsible for the requested resource.
HTTP’s statelessness concerns request interpretation: each request’s semantics can be understood independently, rather than requiring the recipient to reconstruct an implicit conversational sequence from earlier requests on that connection. It does not mean that servers cannot store data or that applications cannot maintain sessions. An e-commerce application can retain a shopping cart in persistent storage and associate later requests with it through a cookie or another explicit identifier. The application maintains the cart’s state; HTTP supplies the exchanges used to inspect or change it. Likewise, connection reuse and protocol-level compression state do not turn HTTP semantics into a stateful application conversation.
HTTP is distinct from HTML, the World Wide Web, and the Internet. HTML is a document markup language; the Web is a system of interlinked resources and associated technologies; the Internet supplies the broader networking infrastructure over which HTTP commonly operates. HTTP can carry images, text, executable code, structured data, or other media, and is widely used by APIs without rendering web pages. Its semantics do not prescribe a programming language, storage system, or server implementation: a response generated dynamically and one read from disk can have the same protocol meaning.
Origins and Standardization
HTTP originated in Tim Berners-Lee’s World Wide Web project at CERN. His March 1989 proposal described a linked information system for sharing documents across heterogeneous computers; during 1990, he implemented the first Web server and the WorldWideWeb browser-editor. The initial protocol, later designated HTTP/0.9, supported a minimal retrieval exchange: a client sent a line such as GET /index.html, and the server returned the document before closing the connection. The request contained no protocol-version identifier, and the response had neither a status line nor HTTP field sections. This design served the early Web’s HTML documents but provided no general framework for describing different content types, reporting outcomes through status codes, or negotiating representations.
As independently developed browsers and servers proliferated, implementations added methods, response codes, and metadata fields. HTTP/1.0, documented in RFC 1945 in May 1996 by Tim Berners-Lee, Roy Fielding, and Henrik Frystyk Nielsen, recorded these established practices. Its request and response formats included explicit version information, and fields such as Content-Type allowed servers to identify content other than HTML. RFC 1945 was published as an Informational RFC, rather than as an Internet Standards Track specification: it described common implementation behavior while acknowledging inconsistencies and experimental extensions. HTTP/1.1 followed on the Standards Track in RFC 2068 in January 1997, with a revised specification in RFC 2616 in June 1999. Persistent connections by default, mandatory Host information in requests, chunked transfer coding, and more extensive caching and conditional-request rules addressed limitations encountered as the Web expanded.
Later standardization separated clarification of HTTP’s meaning from changes to its transmission format. In 2014, RFCs 7230–7235 replaced RFC 2616 with six documents covering message syntax and routing, semantics, conditional requests, range requests, caching, and authentication. This work took place in the Internet Engineering Task Force (IETF), through the HTTP Working Group, commonly called HTTPbis. The working group became the principal forum for maintaining HTTP’s core specifications and developing subsequent versions. Splitting the specification allowed parsing requirements, caching rules, and method semantics to be revised without treating every change as a new wire-protocol version.
Google’s SPDY experiments, publicly introduced in 2009, supplied an important basis for HTTP/2. SPDY explored multiplexing exchanges over one connection, compressing header information, and prioritizing transfers to reduce page-loading latency. The IETF developed these ideas into a distinct protocol rather than adopting SPDY unchanged. HTTP/2 was standardized in RFC 7540 in May 2015, edited by Mike Belshe, Roberto Peon, and Martin Thomson. It retained HTTP methods, status codes, and resource semantics while replacing HTTP/1.1’s textual message transmission with binary framing and concurrent streams. Google’s subsequent QUIC work explored a different transport foundation using UDP. The IETF standardized QUIC version 1 in RFC 9000 in May 2021; HTTP/3, its mapping of HTTP onto QUIC, followed in RFC 9114 in June 2022.
The June 2022 publication series consolidated a version-independent definition of HTTP alongside separate transmission specifications. RFC 9110, HTTP Semantics, defines shared concepts including methods, status codes, fields, and representation metadata; RFC 9111, HTTP Caching, specifies cache behavior. RFC 9112 defines HTTP/1.1 message syntax and connection management, while RFC 9113 replaces RFC 7540 as the HTTP/2 specification. RFC 9114 defines HTTP/3. In this organization, the version number primarily distinguishes how exchanges are carried, rather than defining a separate application meaning for a request such as GET or a response such as 404 Not Found.
Resource Identification and Request Targets
HTTP identifies resources using Uniform Resource Identifiers (URIs). In https://www.example.org:8443/catalog/items?sort=price#details, the scheme is https, the authority is www.example.org:8443, the path is /catalog/items, and the query is sort=price; details is a fragment identifier. The authority identifies a host and, optionally, an explicit port. Although generic URI syntax also permits user information in an authority, HTTP and HTTPS URI schemes prohibit that component. Paths and queries identify resources within the authority’s namespace: neither must correspond to a local filesystem path, a database record, or a particular server process. For example, /catalog/items can be implemented by a static file, an application handler, or a service distributed across multiple machines without changing its identifier.
The http and https schemes have default ports of 80 and 443, respectively. Omitting the port selects the scheme’s default, so https://example.org/ and https://example.org:443/ identify the same origin. HTTPS requires secured communication and authentication of the identified service, without changing the meanings of HTTP methods. When a URI contains a domain name, a client commonly uses the Domain Name System to obtain addressing information before establishing communication. Resolution and resource identification remain separate: several names can resolve to one address, and one name can resolve to multiple addresses. A proxy can also perform resolution on the client’s behalf. Consequently, the URI’s host is not simply an alternative spelling of the IP address ultimately contacted.
An origin is defined by the combination of scheme, host, and port, with scheme-specific defaults applied when the port is omitted. Thus, http://example.org, https://example.org, and https://example.org:8443 represent three different origins. Virtual hosting allows several authorities to share a network address and listening port, so reaching that endpoint alone does not identify the intended service. HTTP/1.1 requires a Host field in requests, such as Host: www.example.org:8443, to convey authority information. HTTP/2 and HTTP/3 provide the :authority pseudo-header field for this purpose and ordinarily carry scheme and path information in :scheme and :path. These identifiers allow servers and intermediaries to route requests without assuming that each website has a dedicated address.
HTTP/1.1 defines four request-target forms. Origin-form, used for ordinary requests directly to an origin server, contains the absolute path and optional query: GET /catalog/items?sort=price HTTP/1.1. An empty URI path is transmitted as /. Absolute-form, generally used for requests to a forward proxy, supplies the absolute URI: GET http://www.example.org/catalog/items?sort=price HTTP/1.1. This lets the proxy identify both the destination authority and the resource. Authority-form, used only with CONNECT, supplies a host and mandatory port, as in CONNECT www.example.org:443 HTTP/1.1; it identifies the destination of the requested tunnel rather than a document path. Asterisk-form, OPTIONS * HTTP/1.1, addresses the server generally rather than a particular resource. The Host field remains required in these HTTP/1.1 requests.
A fragment is interpreted on the client side and is not included in the HTTP request target. For https://www.example.org/guide?edition=2#installation, the ordinary HTTP/1.1 request target is /guide?edition=2. A browser can then use installation to locate a section within the retrieved representation; other representation formats can define different fragment semantics. Changing only the fragment can therefore change the displayed location without requiring another retrieval. The query, by contrast, is transmitted to the server and can affect which resource is selected or how the request is processed.
Messages, Fields, and Content
HTTP messages have a common logical structure: control information, an initial field section, optional content, and an optional trailer section. Request control information identifies the method and request target; response control information supplies a status code. Protocol-version information is also communicated, although its encoding differs between versions. Initial fields—commonly called headers—describe the message, its content, or the context in which it should be processed. Trailers carry additional fields after the content, allowing information calculated during transmission, such as a content digest, to be supplied without buffering the entire content first. They cannot simply replace initial fields: information needed before processing content, such as framing or authentication information, is unsuitable for trailers. This logical model is defined in RFC 9110, published in 2022; individual HTTP versions encode it differently.
An HTTP field consists of a name and a value whose syntax and meaning are defined for that particular field. Names are case-insensitive: Content-Type and content-type identify the same field, although HTTP/2 and HTTP/3 require lowercase names in their encodings. Values are not universally case-insensitive, and punctuation cannot be interpreted using one generic rule. For example, Accept permits a comma-separated list of media ranges, whereas a comma inside a quoted value need not separate list members. Multiple field lines with the same name can be combined, preserving order and inserting commas, only when the field definition permits that treatment. Set-Cookie is a prominent exception to ordinary list combination: separate occurrences convey separate cookies and cannot safely be collapsed into a comma-separated list. Recipients generally ignore unrecognized fields unless a more specific rule applies; forwarding intermediaries have additional obligations concerning which fields they preserve.
Content is distinct from the mechanisms that delimit or transport it. In HTTP/1.1, chunk sizes and chunk delimiters belong to transfer framing, not content; in HTTP/2 and HTTP/3, frame boundaries likewise do not become part of the content. By contrast, compression identified by Content-Encoding, such as gzip, remains part of the coded representation conveyed as content. A message can have no content, and the significance of content depends on the request method and response status. A successful GET response ordinarily carries a representation of the target resource, while POST request content is information for the target resource to process. Responses to HEAD contain no content, even when their fields describe what a corresponding GET response would have carried. Informational responses, 204 responses, and 304 responses also contain no content; a successful CONNECT response instead begins tunnel operation after its initial fields.
The following exchange uses HTTP/1.1 textual notation to illustrate meanings shared across versions. The response content is exactly five octets, Hello, with no trailing newline:
GET /greeting HTTP/1.1
Host: example.org
Accept: text/plain
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 5
Hello
In the request, GET selects the operation, /greeting is the request target, and Host identifies the target authority; Accept expresses a preference for plain text. In the response, 200 is the status code, while OK is an HTTP/1.1 reason phrase with no independent protocol semantics. Content-Type identifies the media type and character encoding, and Content-Length: 5 states the content length in octets, not characters. The empty lines terminate the initial field sections; actual HTTP/1.1 line endings use carriage return followed by line feed. No trailer section appears here. HTTP/2 and HTTP/3 communicate equivalent control information and fields through binary framing and pseudo-header fields rather than these textual start lines; neither uses the illustrated blank-line delimiter.
Request Methods and Their Properties
An HTTP request method identifies the operation requested on the target resource. Method names are case-sensitive: GET is the standardized method, whereas get is not equivalent. GET requests transfer of a current selected representation; retrieval need not correspond to reading a file, since servers can generate representations from a database or other services. HEAD has the same semantics as GET, except that the server must not send response content. It supports inspection of metadata without transferring the representation. Servers should return the fields they would send for GET, although fields determined only while generating content may be omitted. Content in a GET request has no generally defined semantics and cannot change the request’s meaning or target. Private agreements sometimes assign it meaning, but intermediaries may reject such requests, limiting interoperability.
POST asks the target resource to process the enclosed representation according to that resource’s own semantics. Examples include submitting a form, appending data, or creating a subordinate resource: POST /orders might create an order whose identifier the server selects. PUT, by contrast, requests creation or replacement of the target resource’s state with the state defined by the enclosed representation. With PUT /orders/123, the client already identifies the intended target. Successful creation through PUT requires 201 Created; modification of an existing representation requires 200 OK or 204 No Content. DELETE requests removal of the association between the target URI and its current functionality. It does not require physical erasure of underlying storage: an implementation may retain archived records or reclaim space later.
OPTIONS requests information about communication options for a resource, or for the server generally when the request target is *; responses can advertise supported methods through Allow. CONNECT requests establishment of a tunnel to the identified destination, commonly to carry encrypted traffic through a proxy. TRACE requests an application-level loopback of the received request for diagnostics; clients must not include sensitive fields such as credentials or cookies. PATCH, standardized in RFC 5789 in 2010, applies a set of modifications described by a patch document rather than requesting complete replacement as PUT does. Its media type defines the modification instructions. A server must apply the entire patch atomically, without exposing a partially modified representation; PATCH is not inherently idempotent.
A method is safe when its defined semantics are essentially read-only: the client does not request a state change. GET, HEAD, OPTIONS, and TRACE are safe; POST, PUT, DELETE, CONNECT, and PATCH are not. Safety does not prohibit incidental effects such as logging or charging an advertising account. It concerns what the client requests and can be held accountable for requesting. A URI such as /item?do=delete therefore must not perform deletion when accessed with GET: automated browser prefetching or search-engine traversal can legitimately retrieve it without intending a destructive operation.
Idempotence means that multiple identical requests have the same intended server-side effect as one request. All safe methods, plus PUT and DELETE, are idempotent; POST, CONNECT, and PATCH carry no such general guarantee. Responses need not be identical: a first DELETE might return 204, while a repetition returns 404 because the association is already absent. Separate logging of each request also does not violate idempotence. An individual POST or PATCH operation can be designed to be idempotent, but that property cannot be inferred from its method alone.
These properties govern recovery after communication failures. A client can automatically repeat an idempotent request when a connection closes before a response arrives. It should not automatically retry a non-idempotent request unless it knows that the operation is idempotent or that the original request was never applied; otherwise, a payment submission could execute twice. Cacheability is a separate property. POST responses are cacheable only with explicit freshness information and a Content-Location equal to the POST target URI. Such a stored response can satisfy later GET or HEAD requests, not another POST; implementation support remains less common than caching retrieval responses.
Status Codes, Redirection, and Errors
An HTTP response status code is a three-digit integer describing the request’s outcome and the meaning of the response. Its first digit identifies one of five classes: 1xx informational, for interim communication before a final response; 2xx successful, indicating successful receipt, understanding, and acceptance; 3xx redirection, indicating that further action is needed to complete the request; 4xx client error, indicating an apparent problem with the request; and 5xx server error, indicating that the server failed to fulfill an apparently valid request. These are protocol-level classifications, not guarantees about application results. An API can return 200 OK with a representation reporting a business-rule rejection, although that choice makes the rejection invisible to monitoring based solely on status codes. The shared definitions apply across HTTP versions and are consolidated in RFC 9110, published in 2022.
Informational responses allow communication before the final outcome. 100 Continue indicates that the server wishes to receive the request content after inspecting its initial fields, particularly when the client sent Expect: 100-continue; it does not guarantee eventual acceptance. 103 Early Hints, standardized in RFC 8297 in 2017, can carry Link fields so a browser can begin loading dependencies while the final response is being prepared. Among successful responses, 200 OK indicates success whose precise meaning depends on the method: a GET response normally contains the selected representation, whereas a POST response can describe processing results. 201 Created indicates creation of one or more resources, with the primary resource identified by Location when present, or otherwise by the target URI. 202 Accepted means processing has been accepted but is incomplete; it does not promise eventual success. 204 No Content indicates successful fulfillment without response content.
Redirect responses commonly use Location to identify another URI, but they differ in permanence and method handling. 301 Moved Permanently assigns a permanent replacement URI, whereas 302 Found indicates a temporary alternative. For historical compatibility, clients may change POST to GET when following either code. 303 See Other instead directs the client to retrieve another resource, normally using GET or HEAD; a common example is a form submission followed by retrieval of a confirmation page. 307 Temporary Redirect and 308 Permanent Redirect remove the method ambiguity: an automatically redirected request must preserve its method. Thus, redirecting a POST with 307 or 308 retains POST semantics rather than converting it into retrieval. Automatic following remains subject to client policy, including restrictions on forwarding credentials across origins.
Client-error responses distinguish several failure conditions. 400 Bad Request covers perceived request problems such as malformed syntax or invalid framing. 404 Not Found means that the server found no current representation, or is unwilling to disclose one; it does not establish permanent absence. 405 Method Not Allowed means the method is known but unsupported for the target resource, and the response must contain an Allow field listing currently supported methods. 409 Conflict identifies a conflict with the resource’s current state, such as an incompatible update. 415 Unsupported Media Type rejects a request content format or coding unsupported for that operation. 429 Too Many Requests, defined in RFC 6585 in 2012, signals rate limiting and can include Retry-After.
Server errors identify different failure locations. 500 Internal Server Error describes an unexpected server condition preventing fulfillment. 502 Bad Gateway means a gateway or proxy received an invalid upstream response, while 504 Gateway Timeout means it did not receive a timely upstream response. 503 Service Unavailable indicates temporary inability to handle the request, commonly because of overload or maintenance. A 503 response can include Retry-After, expressed either as an HTTP date or as a non-negative number of seconds; the field can also accompany redirects to indicate a minimum wait before following them.
Status codes are extensible. A client must understand an unrecognized code’s class and treat it like that class’s x00 code, while not caching a response with an unrecognized status code. An HTTP error response nevertheless remains a received protocol message, potentially carrying explanatory content and retry information. A name-resolution failure, connection refusal, or transport interruption before response headers arrive produces no HTTP status code; any error label shown by a client in that situation is not a status returned by the server.
Representations and Content Negotiation
A resource identified by a URI can have several representations: for example, a weather report might be available as English HTML, French HTML, or structured data. The selected representation is the particular representation chosen for a response, rather than the resource itself. Representation metadata describes how its content is to be interpreted. Content-Type identifies the media type, optionally with parameters: Content-Type: text/html; charset=utf-8 specifies HTML encoded in UTF-8. Parameters have meanings defined for the particular media type; charset is not a universal parameter applicable to every format. Content-Language: fr identifies the representation’s intended linguistic audience, not necessarily every language appearing within it. A language-learning document, for example, may contain several languages while being intended for English-speaking readers.
In proactive content negotiation, the server selects a representation using preferences supplied with the request. Accept expresses preferences among media types, Accept-Encoding among content codings, and Accept-Language among natural languages. Preference weights use a q parameter between 0 and 1; an omitted weight defaults to 1, while 0 means unacceptable within the applicable matching rules. Thus, Accept: application/json, text/html;q=0.7 prefers JSON, and Accept-Language: fr, en;q=0.8 prefers French over English. These fields are inputs to selection, not commands to produce unavailable variants: the server also considers availability and its selection policy. If no acceptable variant exists, it can return 406 Not Acceptable, but HTTP also permits disregarding negotiation preferences rather than returning that error. In reactive negotiation, the server instead supplies alternatives from which the user agent can choose, potentially requiring another request. Responses such as 300 Multiple Choices or 406 can support this process, although HTTP does not prescribe a universal format or automatic selection algorithm.
Content coding changes a representation’s encoded form without changing its underlying media type. A response containing Content-Type: text/html and Content-Encoding: gzip carries gzip-compressed HTML; the recipient decodes gzip before interpreting the HTML. Brotli, standardized in RFC 7932 in 2016, uses the coding token br. Both are lossless compression mechanisms, negotiated through Accept-Encoding. Multiple codings can be listed in application order and decoded in reverse order. This differs from HTTP/1.1 transfer coding: Transfer-Encoding: chunked delimits message content for transmission and is not a property of the selected representation. Content coding also differs from choosing a compressed file format as the media type: application/gzip identifies gzip-format data itself, rather than declaring an encoding applied to some other media type.
Vary declares which request fields, beyond the method and target URI, might have influenced representation selection. A server choosing language and compression variants might send Vary: Accept-Language, Accept-Encoding. This signals that otherwise similar requests can receive different representations because those fields differ. It neither lists available variants nor identifies the representation actually delivered; fields such as Content-Language and Content-Encoding serve the latter purpose. Vary: * indicates that selection may depend on other aspects of the request, potentially including information outside its fields. Its consequences for stored-response reuse belong to HTTP’s caching rules.
A multipart representation contains separately delimited parts within one content body. Its Content-Type includes a required boundary parameter, whose value determines the delimiter lines separating those parts. multipart/form-data, specified in RFC 7578 in 2015, commonly carries submitted form fields and uploaded files. Each part has Content-Disposition: form-data with a name parameter; file parts can also supply a filename parameter and their own Content-Type. Multipart packaging does not itself imply negotiation. Likewise, choosing JSON, XML, or an application-specific binary format is distinct from defining that format’s schema: HTTP can negotiate a media type, while the application determines the fields, structures, and meaning serialized within it.
Validators, Preconditions, and Range Requests
A validator identifies or dates the selected representation of a resource so that a recipient can test whether it has changed. An entity tag, carried in ETag, is an opaque, quoted value such as "revision-42"; clients must not infer a particular hash algorithm or revision scheme from its contents. A strong validator changes whenever the representation data changes, whereas a weak validator, marked with W/, can group representations that the server considers semantically equivalent despite differences in their bytes. Thus, W/"revision-42" cannot establish byte-for-byte identity. Last-Modified supplies a modification time in HTTP-date format. Its one-second resolution and dependence on accurate modification tracking generally make it a weak validator, although HTTP specifies circumstances in which it can be treated as strong.
Conditional retrieval lets a client request content only when its stored representation is no longer current. For example, GET /manual with If-None-Match: "revision-42" asks the server to transfer the selected representation only if its entity tag does not match. This condition uses weak comparison: matching opaque tag values count as equal regardless of the weakness marker. If the condition is false for GET or HEAD, the server returns 304 Not Modified, without response content; the client can retain its stored representation and update applicable metadata. If-Modified-Since provides a timestamp-based alternative: a qualifying representation not modified after the supplied date likewise produces 304. When both fields occur, If-None-Match takes precedence and If-Modified-Since is ignored. Cache reuse rules are separate from these conditional-request semantics.
Preconditions also support optimistic concurrency control, preventing a client from silently overwriting another client’s changes. Suppose two editors retrieve a document with ETag: "v7". After one successfully updates it, the server assigns "v8". The other editor’s subsequent PUT with If-Match: "v7" fails with 412 Precondition Failed, rather than replacing the newer document. If-Match uses strong comparison, so weak tags cannot satisfy it. If-Unmodified-Since offers a timestamp-based condition but is ignored when If-Match is present. The wildcard If-Match: * requires a current representation to exist; conversely, If-None-Match: * can protect a creation request against replacing an existing representation. A false If-None-Match condition on methods other than GET or HEAD produces 412 rather than 304.
A byte range request retrieves only part of a selected representation, commonly for interrupted downloads or media seeking. Range: bytes=0-499 requests the first 500 bytes: offsets begin at zero and both endpoints are inclusive. Open-ended forms such as bytes=500- request the remainder, while bytes=-500 requests the final 500 bytes. Accept-Ranges: bytes advertises support, but clients may attempt a range request without receiving that advertisement. A server can ignore Range and return an ordinary 200 OK response. Range processing follows precondition evaluation, so a conditional GET that warrants 304 does not become a partial-content response.
For a satisfiable single range, the server normally returns 206 Partial Content with, for example, Content-Range: bytes 0-499/1234; the response content contains those 500 bytes of the 1,234-byte representation. Multiple returned ranges use Content-Type: multipart/byteranges, with a separate Content-Range field in each body part. A server may coalesce overlapping or closely spaced ranges. If no requested range is satisfiable, it can return 416 Range Not Satisfiable; a byte-range response should include a field such as Content-Range: bytes */1234, identifying the current length. Byte offsets apply to the selected representation’s encoded bytes, not necessarily its decompressed form.
If-Range makes partial retrieval conditional on representation continuity. A client resuming a download can send Range: bytes=500- together with If-Range: "v7". If the strong entity tag matches, the server can return the remaining bytes; otherwise, it ignores the range and transfers the complete representation, normally with 200 rather than 412. A weak entity tag cannot be used in If-Range; a date is permitted only under specified strong-validator conditions. When independently retrieved portions are combined, a shared strong validator establishes that they belong to the same representation, preventing a reconstructed file from mixing bytes from different versions.
Caching and Reuse
HTTP caching, specified in RFC 9111 (2022), stores responses for later requests rather than necessarily contacting the origin server again. A private cache, typically within a web browser, serves one user; a shared cache serves multiple users through a proxy or content-delivery network (CDN). A reusable local response can eliminate network communication, while a shared cache can shorten network distance and consolidate repeated retrievals. Both reduce bandwidth consumption and origin-server load, although shared caches must respect restrictions on personalized and authenticated responses. Cacheability depends on method, status, fields, and storage rules—not simply on whether a response contains an image or an HTML document.
Freshness determines whether a stored response can normally satisfy a request without validation. A response is fresh when its freshness lifetime exceeds its current age. For shared caches, Cache-Control: s-maxage takes precedence over max-age; otherwise, max-age supplies an explicit lifetime in seconds. In their absence, Expires supplies an absolute expiry time, generally interpreted relative to Date. Current age accounts for the response’s apparent age when received, any received Age value, transit delay, and time subsequently spent in storage; it does not simply restart at each intermediary. For example, a response with max-age=600 and a calculated current age of 240 seconds has 360 seconds of freshness remaining. A cache generating a response from storage sends Age to report its estimated age in seconds.
When no explicit lifetime is supplied, a cache may assign heuristic freshness where permitted. One common heuristic uses a fraction of the interval between Last-Modified and Date; RFC 9111 gives 10 percent as a typical value, not a mandatory algorithm. Storage permission and freshness are separate decisions: a response can be stored yet require validation before reuse. private prohibits shared-cache storage while allowing private caching, whereas public explicitly permits caching, including under some conditions that would otherwise prevent shared-cache storage. no-cache permits storage but requires successful validation before reuse. no-store prohibits storage of the affected exchange; it is not an instruction to erase every previously stored response for that resource. Once a response becomes stale, must-revalidate prohibits reuse without successful validation, even when the origin is unreachable.
A cache key contains, at minimum, the request method and target URI, although many deployed caches store only GET responses and therefore effectively key primarily by URI. Vary adds matching requirements for request fields that influenced representation selection. For example, Vary: Accept-Encoding prevents a stored compressed representation from being reused for an incompatible request. Differences in query strings normally distinguish keys; URL fragments do not, because they are not sent in requests. A Vary: * response cannot match a later request through ordinary variant selection. Implementations may partition caches further, but cannot ignore protocol requirements for representation matching.
Revalidation contacts the origin conditionally to determine whether a stored representation remains usable. A 304 Not Modified response allows the cache to update stored metadata and reuse existing content, avoiding retransmission of that content; a replacement response supplies new content. Successful state-changing requests also affect stored entries: a cache receiving a non-error response to an unsafe method must invalidate the target URI, meaning removal or marking entries as requiring validation. Related URIs, such as those identified by Location or Content-Location, may also be invalidated subject to same-origin restrictions. Such invalidation reaches caches on the exchange’s path, not every cache worldwide.
Controlled stale reuse trades immediate consistency for responsiveness or availability. RFC 5861 (2010) defines stale-while-revalidate, allowing stale content during a bounded background-validation interval, and stale-if-error, allowing bounded stale reuse following specified network or server failures. With max-age=60, stale-while-revalidate=30, a cache may serve a response up to 30 seconds beyond its freshness lifetime while attempting asynchronous validation. These extensions do not provide unlimited permission to serve old data or override stricter applicable prohibitions. Consequently, different clients can temporarily receive different representations while cache entries expire or are refreshed.
Authentication, Cookies, and Application Sessions
HTTP’s challenge–response framework lets a server request credentials without prescribing an application’s account system. A response with 401 Unauthorized must contain a WWW-Authenticate field with at least one challenge, such as WWW-Authenticate: Basic realm="members". The client can then send credentials in an Authorization field; clients may also send credentials without waiting for a challenge. The scheme identifies how credentials are represented, while parameters such as realm identify the protection space. Authentication establishes identity or validates credentials; authorization determines whether access is permitted. Despite its name, 401 Unauthorized concerns missing or unacceptable authentication credentials. 403 Forbidden means that the server understands the request but refuses to fulfill it, including cases where authenticated credentials lack sufficient privileges.
Basic authentication, specified in RFC 7617 in 2015, encodes a username and password separated by a colon using Base64. This encoding provides no confidentiality: protection against network disclosure depends on a secure transport such as HTTPS. Digest authentication, updated in RFC 7616 in 2015, computes a response using credentials, a server-provided nonce, and request information rather than transmitting the password directly. It supports algorithms including SHA-256, but does not itself encrypt message content or replace transport security. Bearer authentication, specified for OAuth 2.0 in RFC 6750 in 2012, commonly uses Authorization: Bearer <token>. Possession of the token is sufficient to exercise its granted authority. Such a token can represent a limited access grant rather than a login session; HTTP does not require it to identify a server-side session record.
A server sets an HTTP cookie through a response field such as Set-Cookie: sid=abc123; Path=/; Secure; HttpOnly; SameSite=Lax. A browser stores the cookie and attaches its name and value to eligible subsequent requests, for example Cookie: sid=abc123. Attributes govern storage and transmission but are not repeated in that request field. Without a Domain attribute, a cookie is host-only; specifying an acceptable parent domain can extend eligibility to its subdomains, subject to browser restrictions such as public-suffix checks. Path limits matching request paths but is not a security boundary between applications. Cookies are not isolated by port. Max-Age specifies a lifetime in seconds and takes precedence over Expires when both are present. Without either attribute, a cookie is a session cookie, although browser session-restoration features can preserve it across restarts.
Secure restricts cookie transmission to secure channels; it does not encrypt the cookie independently, protect server-side storage, or establish confidentiality for an otherwise insecure exchange. HttpOnly prevents exposure through non-HTTP scripting interfaces such as JavaScript’s document.cookie, but the browser still attaches the cookie to eligible script-initiated requests. It therefore does not prevent injected scripts from performing authenticated actions. SameSite limits attachment in cross-site contexts: Strict excludes cross-site requests, while Lax permits certain top-level navigations using safe methods. None permits cross-site attachment and requires Secure in modern browsers. “Same-site” differs from “same-origin”: scheme and registrable domain determine the site, so different subdomains can be same-site despite being distinct origins. These attributes constrain credential exposure but do not replace application access checks.
An application session commonly associates an opaque, unpredictable cookie value with a server-side record containing a user identifier, authentication status, shopping-cart contents, or preferences. The record may reside in memory, a database, or a shared store used by several application servers. Cookie expiration and server-side session expiration are independent: a browser may retain an identifier whose record has expired, and deleting a cookie does not necessarily delete its server-side record. Other designs place signed state in client-held cookies or tokens; a signature detects modification but does not conceal the contents. In each design, requests carry the information needed to locate or validate application state. Persistent login, shopping carts, and personalized responses therefore operate above HTTP’s stateless request semantics rather than changing them.
Proxies, Gateways, and Content Delivery
A forward proxy is an intermediary selected by a client to handle requests on its behalf, for example an enterprise proxy server through which browsers access external websites. A gateway, commonly called a reverse proxy, instead presents itself to clients as the server responsible for a resource and forwards requests to one or more upstream services. Clients need not know those services’ addresses or implementation details. These roles are exchange-specific: a server can receive a request as a gateway and then act as a client toward an upstream server. A tunnel differs from both because, once established, it forwards bytes without interpreting them as HTTP messages.
Reverse proxies can distribute requests among backend instances using round-robin selection, connection counts, or application-specific routing rules. Health checks help exclude unavailable instances, while session affinity can direct related requests to the same backend. Routing may depend on the requested authority, path, or other fields: /images/ and /api/, for example, can reach different services behind one public origin. With TLS termination, the proxy decrypts incoming HTTPS traffic and establishes a separate upstream connection, which may itself use TLS. Confidentiality then has separate connection boundaries rather than extending uninterrupted to the backend. A content delivery network places reverse-proxy infrastructure at geographically distributed edge locations. DNS-based selection or anycast routing can direct clients to an edge, which may serve cached content or forward a request toward the origin; geographical proximity alone does not determine the lowest-latency route.
HTTP distinguishes fields intended for end-to-end interpretation from connection-specific information that applies only to one hop. In HTTP/1.1, the Connection field identifies additional fields that must not be forwarded: an intermediary processing Connection: keep-alive, Example-Control removes both the Connection field and the named fields before forwarding. HTTP/2 and HTTP/3 prohibit connection-specific fields such as Connection, so translation requires semantic processing rather than verbatim copying. The Via field records intermediary protocol information and identifiers; a chain can produce a value such as 1.1 proxy-a, 1.1 proxy-b. It supports tracing and loop detection, but does not necessarily reveal physical hosts, since pseudonyms are permitted. RFC 7239, published in 2014, standardized Forwarded parameters including for, by, host, and proto. Neither Forwarded nor the widely deployed X-Forwarded-For is inherently trustworthy: clients can supply such fields, so their evidential value depends on which intermediaries generated or sanitized them.
For a conventional CONNECT tunnel, a client sends a request such as CONNECT example.com:443 HTTP/1.1 to a proxy. A successful 2xx response changes the connection into a tunnel; subsequent bytes are no longer ordinary HTTP requests and responses interpreted by that proxy. A browser can then conduct a TLS handshake with example.com through the tunnel. The proxy knows the requested tunnel destination but, without terminating that TLS connection, does not read the enclosed HTTP fields or content. Later HTTP versions support CONNECT using streams, allowing a tunnel to occupy one stream rather than the entire underlying connection.
An intermediary chain creates multiple independently managed communication segments. A browser might use HTTP/3 to a CDN edge, which uses HTTP/2 to a regional gateway, which uses HTTP/1.1 to an application server. Methods and status semantics remain shared, but framing, field encoding, connection reuse, and failure handling differ at each boundary. Access logs therefore describe a particular observation point rather than the complete exchange. A gateway-generated 502 Bad Gateway or 504 Gateway Timeout identifies an upstream communication problem from that gateway’s perspective, not necessarily a failure of the ultimate origin application. Correlating requests across hops requires deliberately propagated identifiers and compatible logging; intermediary buffering, retries, and routing decisions can otherwise obscure where delay or failure occurred.
HTTP/1.1 Transmission and Connection Management
HTTP/1.1 serializes messages as a start line, field lines terminated by carriage return and line feed (CRLF), an empty CRLF line ending the header section, and an optional message body. A request line contains a method, request target, and version, as in GET /report HTTP/1.1; a response status line contains the version, status code, and optional reason phrase, as in HTTP/1.1 200 OK. RFC 9112, published in 2022, specifies parsing as a sequence of octets rather than unrestricted Unicode text: decoding before identifying message boundaries can produce inconsistent interpretations. Senders must use the prescribed syntax, including CRLF delimiters, and must not generate obsolete folded field lines. Recipients have limited allowances for tolerant parsing, but differing interpretations between recipients create security risks.
Message framing determines where one message ends and the next begins. Content-Length: 1200 specifies a body of exactly 1,200 octets, not characters. With Transfer-Encoding: chunked, chunked transfer coding divides the body into chunks, each introduced by its hexadecimal size and CRLF and followed by CRLF. A zero-sized chunk ends the data, after which an optional trailer section and a final empty line complete the message. For example, 4\r\nWiki\r\n0\r\n\r\n carries the four content octets Wiki, where \r\n denotes CRLF. A sender must not include both Content-Length and Transfer-Encoding; their coexistence can indicate a framing attack. When processing such a message, transfer coding takes precedence, and forwarding requires removing the received Content-Length.
Body-length rules also depend on the response status and request method. Responses to HEAD and responses with status 1xx, 204, or 304 end at the empty line after their header fields and cannot contain a message body or trailers. A successful 2xx response to CONNECT instead switches immediately to tunnel operation. A request without either transfer coding or a content length has a zero-length body; connection closure does not delimit request content. Where permitted, a response without explicit length framing ends when the server closes the connection. This close-delimited form prevents reuse and cannot reliably distinguish a completed response from an interrupted transmission, so explicit framing is preferable.
Persistent connections are the HTTP/1.1 default, unlike the common connection-per-request pattern of early HTTP implementations. Multiple exchanges can reuse one TCP connection, avoiding repeated connection establishment. Persistence requires unambiguous message boundaries: clients must consume an entire response before reuse, and servers must consume a request body or close the connection. Connection: close signals that the connection will not persist after the current exchange; it does not replace the message-framing rules. Persistent connections can nevertheless close unexpectedly because of timeouts or network failures, so retry behavior depends on method semantics and whether a response was received.
Pipelining permits a client to send several requests without waiting for each preceding response. The server must return the corresponding final responses in request order, even if it processes safe requests concurrently. Thus, a slow first response delays delivery of later responses on that connection: application-level head-of-line blocking. This differs from TCP-level blocking, where missing bytes prevent delivery of later bytes in the transport stream. Pipelining does not provide independently interleaved response streams, and its recovery and interoperability difficulties limited deployment; HTTP/2 multiplexing uses a different mechanism.
Expect: 100-continue allows a client to send request headers and briefly wait before transmitting a potentially large body. A server can return 100 Continue or an immediate final response, such as an authentication failure; a client need not wait indefinitely before sending content. Chunked messages can carry fields generated late, such as integrity metadata, in trailers; the Trailer field can announce expected trailer names, while TE: trailers indicates willingness to accept response trailers. Trailer fields cannot substitute for fields needed before processing the content. Finally, Upgrade, nominated by Connection: Upgrade, proposes switching protocols on the existing connection; an accepting server sends 101 Switching Protocols. Later HTTP versions retain many relevant semantics but use frames and streams rather than chunk delimiters, and do not use HTTP/1.1’s connection-wide Upgrade exchange.
HTTP/2 Framing and Multiplexing
HTTP/2 preserves HTTP methods, status codes, and representation semantics while replacing HTTP/1.1’s textual message framing with binary frames. Its current specification, RFC 9113 (2022), supersedes RFC 7540 (2015). Each frame begins with a nine-octet header containing a payload length, frame type, flags, and a 31-bit stream identifier. Stream zero is reserved for connection-level communication; other identifiers distinguish exchanges within the connection. HEADERS frames carry compressed field blocks, with CONTINUATION frames used when necessary, while DATA frames carry message content. SETTINGS communicates parameters such as concurrency limits and maximum frame size. GOAWAY signals connection shutdown and identifies the highest-numbered peer-initiated stream that might have been processed, helping clients determine which requests might need retrying.
A request and its response normally occupy one client-initiated stream, identified by an odd number. Frames belonging to different streams can be interleaved: a server can transmit part of a large image response, answer a small metadata request, and then resume the image. Within each stream, message ordering remains defined, but responses on different streams need not complete in request order. This differs from HTTP/1.1 pipelining, where multiple requests can be outstanding on a connection but their responses must be sent in the same order. The END_STREAM flag marks completion of one direction of a stream; it does not close the underlying connection. A peer can limit concurrent peer-initiated streams through SETTINGS_MAX_CONCURRENT_STREAMS.
Field sections use HPACK, standardized in RFC 7541 (2015), rather than repeatedly transmitting full textual field lines. HPACK combines a predefined static table, a connection-scoped dynamic table, and optional Huffman coding of strings. Dynamic-table entries can represent recurring names and values, such as an authority or a cookie value, through indexed references. Each direction maintains its own compression context, shared across streams in that direction; encoder and decoder must therefore keep their table state synchronized. SETTINGS_HEADER_TABLE_SIZE limits the table capacity the peer’s encoder may use. Pseudo-header fields replace information formerly carried in the request or status line: ordinary requests use :method, :scheme, and :path, usually with :authority identifying the target authority; responses use :status. Pseudo-header fields precede regular fields, whose names must be lowercase.
Flow control operates independently at stream and connection levels and applies to DATA frames, not to HEADERS or other control frames. A sender must have sufficient credit in both windows before transmitting data. Initially, both windows are 65,535 octets; SETTINGS_INITIAL_WINDOW_SIZE changes initial stream windows, whereas WINDOW_UPDATE increases available credit for a stream or the connection. These mechanisms allow a receiver to constrain incoming content without stopping all control traffic. RST_STREAM cancels an individual stream without terminating others. Server push is another protocol capability: PUSH_PROMISE associates a promised request with an existing stream, and the pushed response uses a server-initiated, even-numbered stream. Clients can disable push with SETTINGS_ENABLE_PUSH; implementation and browser deployment have varied, so protocol support does not imply widespread use.
Multiplexing does not eliminate head-of-line blocking in the underlying TCP connection. TCP delivers an ordered byte stream, so a missing segment prevents later bytes from reaching HTTP/2 even when those bytes contain frames for unrelated streams. Consequently, packet loss can temporarily stall every stream sharing that connection. Stream-level flow control and cancellation do not remove this transport-level dependency; HTTP/3 uses a different transport mapping to address it.
Connection coalescing allows a client to reuse an HTTP/2 connection for multiple origins when the server is authoritative for each. For HTTPS, the certificate must be valid for the additional hostname, and the client must establish that the connection reaches an appropriate server, commonly through matching DNS-resolved addresses. Certificate coverage alone does not authorize arbitrary cross-origin reuse. A server unable or unwilling to serve a request on that connection can return 421 Misdirected Request, allowing the client to retry over a different connection. Coalescing preserves each request’s authority and does not merge browser security origins.
HTTP/3 and QUIC
HTTP/3, standardized in RFC 9114 in June 2022, maps HTTP semantics onto QUIC rather than directly onto TCP. QUIC version 1 was specified in RFC 9000 in May 2021, with its security integration defined in RFC 9001. It runs over UDP but supplies transport functions that UDP itself lacks: reliable delivery within streams, loss detection, flow control, and congestion control. QUIC incorporates the TLS 1.3 handshake to authenticate the server and establish cryptographic keys; application data is protected within QUIC packets rather than carried in ordinary TLS records. HTTP methods, status codes, and representation semantics remain unchanged. The negotiated application-protocol identifier for standardized HTTP/3 is h3.
Each ordinary request–response exchange occupies a client-initiated bidirectional QUIC stream: the client sends the request in one direction, and the server sends the response in the other. HTTP/3 frames, including HEADERS and DATA, carry fields and content on that stream. QUIC delivers bytes reliably and in order within each stream, but does not require delivery ordering across streams. If a lost packet contains data for one response, another response whose data has arrived can continue without waiting for that loss to be repaired. This removes the transport-level head-of-line blocking that TCP imposes on HTTP/2’s multiplexed streams. Independence is not absolute: one packet can contain data from several streams, congestion control governs their aggregate traffic, and connection-level flow-control limits or connection failure can affect all exchanges.
HTTP/3 also uses unidirectional streams for connection management. Each endpoint opens one control stream, whose first frame must be SETTINGS; subsequent control frames can include GOAWAY, which supports orderly shutdown. Field sections use QPACK, standardized in RFC 9204 in 2022. QPACK combines a predefined static table with a connection-specific dynamic table, allowing repeated field names and values to be represented compactly. Unlike HTTP/2’s HPACK, it is designed for streams that can arrive independently. Dedicated encoder streams convey dynamic-table changes, while decoder streams convey acknowledgments and cancellation information. A field section referring to a dynamic-table entry not yet received can nevertheless be blocked pending that entry. Settings limit the number of streams exposed to such blocking, and encoders can avoid dependencies by using literals or already available entries. QPACK therefore manages compression dependencies rather than eliminating them entirely.
QUIC combines transport establishment with the TLS 1.3 handshake. A new connection normally permits application-data exchange after one network round trip; a server requiring address validation through a Retry packet adds a round trip. Connection identifiers allow packets to remain associated with a connection even when network addresses or ports change, rather than relying exclusively on the address-and-port tuple. With peer support and path validation, this permits migration, such as continuing a connection when a mobile device changes from Wi-Fi to cellular service. Resumption can optionally carry HTTP requests as zero-round-trip, or 0-RTT, early data. Such data can be replayed, so permission to send it depends on the request’s semantics and application policy; encryption alone does not prevent replay. A server unwilling to process an early request can return 425 Too Early, allowing a retry after the handshake.
Clients can discover HTTP/3 through the Alt-Svc response field, for example Alt-Svc: h3=":443"; ma=86400, advertising an alternative service on UDP port 443 for a specified lifetime. This changes the connection destination without changing the resource’s origin. HTTPS records in the Domain Name System, standardized in RFC 9460 in 2023, can also advertise supported protocols through an alpn parameter, potentially revealing HTTP/3 availability before the first HTTP exchange. An advertisement does not guarantee reachability: firewalls, blocked UDP, or other network conditions can prevent QUIC connections. Clients can race connection attempts or fall back to HTTP/2 or HTTP/1.1 over TCP, subject to the service’s supported protocols and the client’s connection policy.
HTTPS and Transport Security
HTTPS applies authenticated, encrypted transport to HTTP; it does not introduce different meanings for methods such as GET or POST, or for response status codes. The https URI scheme identifies access secured for the named origin, normally on port 443. HTTP/1.1 and HTTP/2 commonly use Transport Layer Security (TLS) over TCP. HTTP/3 instead uses QUIC, which incorporates the TLS 1.3 handshake and key establishment while protecting packets through QUIC’s own transport mechanisms, rather than carrying ordinary TLS records over TCP. RFC 9110, published in 2022, defines the shared HTTPS semantics independently of these version-specific transports.
Certificate-based server authentication binds the connection to the hostname in the requested URI. A server presents an end-entity certificate and usually intermediate certificates; the client constructs and validates a chain to a locally trusted root certificate. Validation includes certificate signatures, validity periods, applicable constraints, and the identity being contacted. For example, a certificate valid only for shop.example does not authenticate payments.example. Modern service-identity rules use names in the certificate’s Subject Alternative Name extension rather than the legacy Common Name field. Authentication also requires evidence that the peer possesses the corresponding private key: in a certificate-authenticated TLS 1.3 handshake, the CertificateVerify message signs the handshake transcript. Optional client-certificate authentication allows the server to authenticate a client through a similar mechanism, but mapping that identity to an account and its permissions remains an application decision.
TLS provides confidentiality and integrity for HTTP fields and content between its endpoints. Consequently, an on-path observer normally cannot read the request path, query string, cookies, or response body, or modify them without detection. These protections do not conceal all communication metadata: destination IP addresses, packet sizes, and timing remain observable, while hostname exposure depends on DNS and handshake protections. The Server Name Indication extension can disclose the hostname unless protected by Encrypted Client Hello. Protection also ends wherever TLS terminates. A content-delivery service or reverse proxy terminating a browser’s connection can read the HTTP messages; a separate encrypted connection to the origin protects a different transport segment. HTTPS therefore does not guarantee that an origin application is trustworthy, that stored data is secure, or that application-generated content is harmless.
Application-Layer Protocol Negotiation (ALPN), standardized in RFC 7301 in 2014, lets endpoints select an application protocol during secure connection establishment. The client advertises supported protocol identifiers, and the server selects one supported option. For TLS-over-TCP HTTP, identifiers include h2 for HTTP/2 and http/1.1 for HTTP/1.1. HTTP/3 uses h3 through the TLS handshake integrated into QUIC. ALPN identifies the protocol to run on the connection; it does not itself discover an HTTP/3 endpoint or convert a TCP connection into QUIC.
HTTP Strict Transport Security (HSTS), specified in RFC 6797 in 2012, lets an HTTPS server send a Strict-Transport-Security field that instructs a browser to use secure connections for subsequent requests. For example, max-age=31536000; includeSubDomains establishes a one-year policy extending to subdomains. Browsers accept this policy only over an authenticated secure connection; a header received over plain HTTP cannot establish it. Browser preload lists can cover the otherwise unprotected first visit, and HSTS requires termination rather than user bypass when secure connection establishment fails. Mixed-content handling addresses a different problem: an HTTPS document requesting resources over insecure HTTP. Browsers block active mixed content such as insecure scripts and may automatically upgrade certain other requests, including images, to HTTPS. These mechanisms support secure transport use without establishing that the application’s scripts, authorization rules, or business logic are correct.
Browser Security and Protocol-Level Threats
The same-origin policy restricts how scripts in a web browser interact with resources from another origin, defined by scheme, host, and port. For example, https://shop.example and https://api.example are different origins despite sharing a parent domain. Cross-origin embedding, navigation, and some request transmission remain possible; the policy principally restricts access to responses and other protected data. Cross-Origin Resource Sharing (CORS) lets servers authorize specified cross-origin response access through fields such as Access-Control-Allow-Origin. Requests using methods or fields outside the CORS safelist generally require an automatic OPTIONS preflight, which declares the intended method and field names. The browser checks the response before transmitting the actual request. Qualifying requests can be sent without preflight even when their responses cannot subsequently be read by the initiating script.
For credentialed cross-origin access, a browser request must use an appropriate credentials mode, while the server must return Access-Control-Allow-Credentials: true and an explicitly permitted origin rather than the wildcard *. Cookie restrictions still apply independently: CORS permission does not override SameSite attributes or browser policies restricting third-party cookies. Preflight requests themselves normally exclude credentials. CORS is a browser-enforced response-access mechanism, not authentication: non-browser clients need not enforce it, and an allowed origin does not establish the identity or privileges of a user. Consequently, a server’s acceptance of a request and a browser’s permission to expose its response are distinct decisions.
Cross-site request forgery (CSRF) exploits credentials that browsers attach automatically, particularly cookies. An attacker-controlled page can induce a request to another site that the server interprets as an action by an authenticated user, even if the attacker cannot read the response. Cross-site scripting (XSS), by contrast, occurs when attacker-controlled content executes as script within a trusted site’s security context. Such script may read accessible application data or issue authenticated requests from that context. An HttpOnly cookie prevents direct script access to its value but does not prevent the browser from attaching it to script-initiated requests. Anti-CSRF tokens and origin checks address request authenticity; contextual output encoding and restrictions on script execution address different aspects of XSS.
Request smuggling arises when recipients in an intermediary chain disagree about request boundaries. In HTTP/1.1, inconsistent treatment of Content-Length, Transfer-Encoding, or malformed field syntax can cause a front-end proxy and a back-end server to interpret the same bytes as different sequences of requests. Translation between protocol versions can also introduce ambiguous framing. RFC 9112, published in 2022, specifies handling rules for conflicting framing information because such ambiguity can affect subsequent requests on a reused connection. Response splitting instead concerns untrusted data being interpreted as response syntax—for example, when carriage-return and line-feed characters enter generated fields—potentially creating unintended fields or apparent additional responses.
Cache poisoning and cache deception exploit different mismatches between caching and application behavior. In cache poisoning, attacker-influenced content is stored and later served to other users; one cause is a response that depends on an input omitted from the cache key. For example, an unkeyed request field might alter a generated redirect while the cache stores that redirect under the ordinary target URI. Cache deception instead induces storage of content that should not be shared, often because a cache treats a path as a static asset while the application routes it to a personalized endpoint. Filename suffixes, path normalization, routing rules, and representation selection can therefore produce security-relevant differences in interpretation.
HTTP also exposes privacy risks through metadata. Sensitive URL paths or query parameters can enter browser history, server logs, monitoring systems, and, subject to referrer policy, the historically misspelled Referer field. Cookies and identifying request fields can support recognition across requests; combinations of browser characteristics can contribute to fingerprinting. Transport encryption does not conceal these values from endpoints or authorized TLS-terminating intermediaries. Resource exhaustion is a separate protocol-level threat: slow message delivery can occupy connection state, large fields or bodies can consume memory and processing capacity, and rapid stream creation and cancellation can impose disproportionate work on multiplexed servers. Request counts, transferred bytes, and computational cost therefore measure different dimensions of abusive traffic.
Web Applications, APIs, and Streaming
During page navigation, a web browser typically retrieves an HTML document and parses it to discover dependent resources, including stylesheets, scripts, images, and fonts. These resources are requested separately, potentially from different origins; cached responses can eliminate some network transfers. Scripts can initiate further requests through interfaces such as fetch(), updating a page without replacing the entire document. Resource loading is not necessarily sequential: browsers can request dependencies concurrently, although stylesheet processing, script execution, and newly discovered URLs affect when particular requests begin. HTTP supplies retrieval and response semantics, while HTML and browser processing rules determine how the returned resources become a rendered, interactive page.
An HTTP API exposes application operations and data through requests and responses whose content may use JSON, XML, or binary formats. For example, GET /orders/42 might retrieve an order representation, while POST /orders submits data for creating an order. HTTP does not prescribe those paths, the representation schema, or the application's business rules. Representational State Transfer (REST), described in Roy Fielding's 2000 doctoral dissertation, is an architectural style rather than another name for an HTTP API. Its constraints include stateless interaction, caching, a uniform interface, and layered organization; its uniform-interface constraints include resource identification and hypermedia-driven application state transitions. By contrast, an application-specific remote procedure call might submit an operation name and arguments to one endpoint. Using HTTP as its transport does not make that interface RESTful.
Web Distributed Authoring and Versioning (WebDAV) demonstrates standardized extension of HTTP beyond document retrieval. Initially standardized in RFC 2518 in 1999, its core specification was revised in RFC 4918 in 2007. WebDAV adds methods including PROPFIND for retrieving properties and collection information, PROPPATCH for changing properties, MKCOL for creating collections, and COPY and MOVE for resource management. LOCK and UNLOCK support coordinated editing through lock tokens. A 207 Multi-Status response can carry XML describing separate outcomes for multiple resources or properties. Despite the name, the core WebDAV specification does not itself provide a complete version-control system; versioning extensions were specified separately in DeltaV, RFC 3253, in 2002.
Long polling, Server-Sent Events (SSE), and incremental response streaming support updates without repeatedly downloading a complete page, but organize delivery differently. With long polling, the server holds a request until an event or timeout, responds, and the client issues another request; reconnection creates opportunities for gaps unless the application tracks event positions. SSE uses a continuing response with the media type text/event-stream, decoded as UTF-8. Its line-oriented format uses fields such as data, event, and id, with blank lines delimiting events. The browser's EventSource interface supports reconnection and can send Last-Event-ID to facilitate resumption. More generally, a client can consume a response body incrementally, using application framing such as newline-delimited JSON. Neither HTTP/1.1 chunk boundaries nor HTTP/2 or HTTP/3 DATA-frame boundaries inherently delimit application records. Proxy buffering, compression buffers, and delayed server writes can prevent incremental production from becoming immediate delivery.
WebSocket, standardized in RFC 6455 in 2011, provides bidirectional, message-oriented communication rather than a sequence of ordinary HTTP requests and responses. Its HTTP/1.1 opening handshake uses GET with upgrade fields; a successful server response is 101 Switching Protocols, after which WebSocket framing governs the connection. Either peer can then send messages without waiting for a corresponding request. Later HTTP versions use different setup mechanisms: RFC 8441, published in 2018, defines extended CONNECT for WebSocket over HTTP/2, and RFC 9220, published in 2022, specifies its use over HTTP/3. With the required protocol support signaled, WebSocket traffic occupies a stream rather than converting the entire multiplexed connection into a WebSocket connection.
Performance, Measurement, and Implementation
Observed request latency includes work at several layers: DNS resolution, connection establishment, security negotiation, request transmission, server processing, and response delivery. On a new TCP connection, the three-way handshake normally adds approximately one network round-trip time before ordinary application data can be sent. A full TLS 1.3 handshake over TCP normally adds another round trip before the client sends its HTTP request, although resumption and early-data mechanisms can change this sequence. HTTP/3 combines transport and security establishment through QUIC. These costs are not incurred afresh for every request: DNS caching, reused connections, and previously established security state alter the timing. Server processing may include queueing, database queries, and calls to other services; a small response can therefore be slow even when network bandwidth is abundant.
Connection pooling, compression, multiplexing, and prioritization affect different bottlenecks and can interact. Pools reuse established connections, avoiding repeated handshakes, but their size influences concurrency and server resource consumption. HTTP/2 and HTTP/3 multiplex requests, reducing the need for numerous parallel connections; shared congestion control and bandwidth nevertheless limit aggregate progress. Compressing text reduces transmitted bytes at a CPU cost, whereas recompressing already compressed images can provide little benefit. Field compression reduces repeated metadata but introduces connection-specific compression state. Prioritization can favor resources needed for rendering over background transfers, yet its effect depends on scheduling decisions throughout the delivery path. RFC 9218, published in 2022, defines extensible priority signals including urgency values from 0, highest urgency, to 7, lowest; these are advisory signals rather than delivery guarantees.
Implementations range from browsers and command-line clients to application libraries, origin servers, and managed gateways. Apache HTTP Server and nginx can serve content directly or act as reverse proxies; curl provides a command-line client, while libcurl embeds transfer functionality in other software. Java’s java.net.http.HttpClient and Go’s net/http package expose HTTP through programming interfaces, with different pooling, timeout, and streaming behavior. Managed gateways commonly terminate secure connections, route requests, and enforce service limits. Support must be assessed for the specific release, build configuration, and connection hop: a browser can negotiate HTTP/3 with an edge service while that service forwards the request to an origin over HTTP/1.1.
Measurement tools expose different portions of an exchange. Access logs record server-observed events such as status codes, transferred bytes, and processing durations, but ordinarily exclude the client’s earlier DNS lookup and connection setup. Browser developer tools display request waterfalls, cache use, negotiated protocols, and timing subdivisions. curl can report cumulative timings for name lookup, connection establishment, first received byte, and completion. Time to first byte must therefore be interpreted with its measurement boundary: a value measured from navigation start includes different work from one measured after request transmission. Throughput may mean application-content bytes or total wire bytes per second, and an error rate requires an explicit denominator and classification of HTTP errors, timeouts, and connection failures. Packet analysis reveals retransmissions and connection behavior, but encrypted HTTP content requires endpoint access or suitable session keys. Distributed tracing correlates an incoming request with downstream operations; the W3C Trace Context Recommendation of 2020 standardized the traceparent and tracestate fields for propagating trace context.
Interoperability testing exercises combinations of clients, servers, and intermediaries rather than treating one successful direct exchange as sufficient. Relevant cases include reused connections, concurrent streams, cancellation, large field sections, trailers, slow receivers, and protocol translation at gateways. Malformed-message tests check whether implementations reject invalid framing consistently, while load and fault tests reveal resource limits and recovery behavior. Protocol conformance and operational compatibility are distinct: a conforming optional feature can remain unusable when an intermediary does not support it, and successful traffic between two implementations does not establish that either handles all required cases correctly.
Extensibility and Deployment Constraints
HTTP extensions are coordinated through Internet Assigned Numbers Authority (IANA) registries covering request methods, status codes, field names, and version-specific parameters such as HTTP/2 and HTTP/3 settings. Registration records an identifier and its defining specification; it does not establish that implementations support it. Registration procedures differ among registries, with some requiring standards review and others permitting registration against a published specification. An application can also define private fields or conventions without creating a generally interoperable extension: an Example-Account-ID field understood by one service has no universal HTTP meaning. RFC 6648, published in 2012, deprecated the general practice of distinguishing private parameters with an X- prefix, partly because experimental names frequently became permanent deployment dependencies.
Structured field values provide reusable syntax and parsing rules for new HTTP fields. Initially standardized in RFC 8941 in 2021 and revised by RFC 9651 in 2024, they define items, lists, dictionaries, parameters, and data types such as integers, strings, tokens, and byte sequences. A dictionary can express named members with attached parameters without requiring each field designer to invent another quoting, escaping, or delimiter convention. The Priority field, defined in RFC 9218 in 2022, provides a concrete example: Priority: u=1, i expresses urgency and an incremental-processing preference using a structured dictionary. This common syntax reduces parsing variation, but the field specification must still define the meaning of each member, permitted values, defaults, and error handling. Existing fields cannot simply be reinterpreted as structured fields where their established grammar differs.
Compatibility depends on extension-specific rules rather than a universal instruction to ignore anything unfamiliar. A proxy generally forwards unrecognized fields unless they are connection-specific or forwarding is otherwise restricted. An unknown status code is interpreted according to its class—for example, an unfamiliar 4xx code as a generic client error—but a response bearing an unrecognized status code must not be cached. HTTP/2 requires unknown setting identifiers to be ignored, allowing new settings to coexist with older peers. Features needing affirmative agreement require an explicit signal: extended CONNECT in HTTP/2, standardized in RFC 8441 in 2018, uses SETTINGS_ENABLE_CONNECT_PROTOCOL before a client can use that mechanism. Reusing an established method or field with incompatible semantics risks older clients, caches, and gateways silently applying the original interpretation.
Protocol ossification occurs when deployed components enforce assumptions narrower than the protocol permits. A gateway might reject unfamiliar methods, strip fields, or assume that all valid responses use a fixed set of status codes. Such behavior can make a valid extension unusable along an otherwise functioning path. Encryption limits opportunities for nonparticipating network devices to inspect and constrain HTTP syntax, helping preserve room for protocol evolution. It does not remove constraints imposed by endpoints or TLS-terminating reverse proxies, which still interpret messages. Deployment also depends on transport reachability: networks that block UDP can prevent HTTP/3 use even when both endpoints support it, making fallback to another HTTP version operationally important.
Adoption measurements must distinguish capability from actual use. A website survey might count origins that successfully answer an HTTP/3 probe; a browser measurement might count requests carried over HTTP/3; an operator might report its share of transferred bytes. These denominators are not interchangeable: a few large downloads can dominate byte volume, while a site supporting several versions may negotiate different versions with different clients. Meaningful claims specify the measurement date, sampled population, geographic and client coverage, treatment of failed attempts, and whether the unit is websites, requests, connections, or bytes. Discovery state, connection reuse, intermediary configuration, and fallback behavior can all separate advertised support from negotiated traffic.