# The HTTP protocol

> Learn how HTTP requests and responses power the web, including URLs, methods, headers, status codes, bodies, versions, HTTPS, and statelessness.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2018-10-04 | Updated: 2026-07-18 | Topics: [Networking](https://flaviocopes.com/tags/network/) | Canonical: https://flaviocopes.com/http/

HTTP stands for **Hypertext Transfer Protocol**.

It is the application-layer protocol browsers, servers, APIs, command-line clients, and intermediaries use to exchange messages on the web.

A client sends a **request**. A server returns a **response**.

HTTP transfers more than HTML. It carries JSON, images, video, fonts, form data, and any other representation described by its metadata.

## HTTP and HTTPS

Plain HTTP does not encrypt a message.

HTTPS protects HTTP with TLS. It encrypts the connection, authenticates the server certificate, and protects data from modification while in transit.

Use HTTPS for websites and APIs. Redirecting plain HTTP to HTTPS is useful, but the first unencrypted request is still exposed unless the browser already knows to use HTTPS.

HTTP semantics stay mostly the same across HTTP/1.1, HTTP/2, and HTTP/3:

- HTTP/1.1 uses a textual message format over TCP
- HTTP/2 uses binary frames and multiplexes streams over one TCP connection
- HTTP/3 maps HTTP semantics to QUIC, which runs over UDP and includes TLS

Applications normally let the browser, server, and network negotiate the available version.

## Read a URL

Consider this URL:

```text
https://flaviocopes.com/http/?format=markdown#methods
```

Its main parts are:

- `https` is the scheme
- `flaviocopes.com` is the host
- `/http/` is the path
- `format=markdown` is the query
- `methods` is the fragment

The fragment is handled by the client and is not sent in the HTTP request.

The default port is 80 for HTTP and 443 for HTTPS. A URL can specify another port explicitly.

## An HTTP request

An HTTP/1.1 request can look like this:

```http
GET /http/ HTTP/1.1
Host: flaviocopes.com
Accept: text/html
User-Agent: tutorial-client/1.0
```

The first line contains:

- the method
- the request target
- the HTTP version

Headers follow. An empty line ends the header section. Some requests then contain a body.

HTTP/2 and HTTP/3 do not send this exact textual format on the wire, but they preserve the same method, target, header, and content concepts.

## An HTTP response

An HTTP/1.1 response can look like this:

```http
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 19
Cache-Control: max-age=60

<h1>Hello HTTP</h1>
```

The response contains:

- a version
- a status code
- headers
- optional content

`Content-Type` describes the representation. `Content-Length` gives its size when the sender knows it and uses that framing.

HTTP/2 and HTTP/3 use different framing and do not use the HTTP/1.1 status line, but clients still expose the status and headers.

## Common HTTP methods

The method describes the request's purpose.

### GET

`GET` retrieves a representation of a resource:

```http
GET /posts/42 HTTP/1.1
Host: api.flaviocopes.com
```

GET is **safe** and **idempotent** by definition. It should not ask the server to change application state.

### HEAD

`HEAD` asks for the same headers a GET request would return, without response content.

It is useful for checking metadata such as modification time, size, or cache validators.

### POST

`POST` submits content for the resource to process:

```http
POST /comments HTTP/1.1
Host: api.flaviocopes.com
Content-Type: application/json

{"message":"Great tutorial"}
```

POST can create a resource, trigger an action, or process a form. Its meaning comes from the target resource.

POST is not idempotent by default. Repeating it can create another result.

### PUT

`PUT` creates or replaces the state of the target resource with the request content:

```http
PUT /profiles/42 HTTP/1.1
Host: api.flaviocopes.com
Content-Type: application/json

{"name":"Flavio"}
```

PUT is idempotent: repeating the same request should have the same intended effect as sending it once.

### PATCH

`PATCH` applies a partial modification described by the request content.

Its idempotency depends on the patch format and operation.

### DELETE

`DELETE` asks the server to remove the association for the target resource.

It is idempotent in HTTP semantics. Repeating it does not promise the same status code, only the same intended server state.

### OPTIONS

`OPTIONS` asks about communication options for a resource or server.

A response can include an `Allow` header. Browsers also use OPTIONS for some CORS preflight requests.

The protocol defines other methods, including `CONNECT` and `TRACE`. Servers often restrict them unless an application specifically needs them.

## Safe and idempotent are different

A **safe** method asks only to read or inspect state. GET, HEAD, and OPTIONS are safe.

An **idempotent** method has the same intended effect when repeated. Safe methods are idempotent, and PUT and DELETE are idempotent too.

These are protocol semantics, not automatic enforcement. A server can still implement a method incorrectly.

The distinction matters when a client, proxy, or load balancer considers retrying a request.

## Status codes

The response status describes the result.

The first digit gives the category:

- `1xx`: informational
- `2xx`: successful
- `3xx`: redirection
- `4xx`: client-side request problem
- `5xx`: server-side failure

Common examples include:

- `200 OK`
- `201 Created`
- `204 No Content`
- `301 Moved Permanently`
- `304 Not Modified`
- `400 Bad Request`
- `401 Unauthorized`
- `403 Forbidden`
- `404 Not Found`
- `429 Too Many Requests`
- `500 Internal Server Error`
- `503 Service Unavailable`

The response body can provide more details. Clients should use the numeric status, not depend on the optional reason phrase used by HTTP/1.1.

## Headers

Headers carry metadata and control how a message is handled.

Request headers can describe:

- acceptable response formats
- authorization credentials
- cookies
- cache conditions
- the requesting origin

Response headers can describe:

- content type and encoding
- caching rules
- cookies to store
- redirects
- security policies
- cross-origin permissions

Header names are case-insensitive. Header values have rules defined by each field.

Do not put secrets in URLs. URLs can appear in browser history, logs, analytics, and referrer information. Use an authorization header or protected request content according to the API design.

## HTTP is stateless, but sessions exist

HTTP does not automatically connect one request's application state to the next.

Applications add state with cookies, authorization tokens, URL data, or server-side session storage.

The transport connection can still be persistent. HTTP/1.1 can reuse a TCP connection, HTTP/2 multiplexes streams on one connection, and HTTP/3 multiplexes streams over QUIC.

Protocol statelessness and connection reuse are different concepts.

## Intermediaries

A request can pass through proxies, gateways, load balancers, and content delivery networks before reaching the origin server.

Intermediaries can:

- cache responses
- terminate TLS
- compress content
- route traffic
- authenticate requests
- enforce security rules

HTTP headers let the origin and intermediaries coordinate this behavior.

## Inspect HTTP with curl

Use `curl -i` to include response headers:

```bash
curl -i https://flaviocopes.com/http/
```

Use `-I` to make a HEAD request:

```bash
curl -I https://flaviocopes.com/http/
```

Use verbose mode to inspect connection and request details:

```bash
curl -v https://flaviocopes.com/http/
```

The output changes with the server, CDN, negotiated protocol, and current configuration. Learn the structure instead of copying one old response literally.

For the current definitions, see MDN's [HTTP overview](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Overview) and [HTTP methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods), [RFC 9110: HTTP Semantics](https://www.rfc-editor.org/rfc/rfc9110.html), and [RFC 9114: HTTP/3](https://www.rfc-editor.org/rfc/rfc9114.html).
