| |

Internet Beginner 08 ๐ŸŒ Basic HTTP Requests and Responses

โฑ๏ธ Estimated read: 13 min | |

Every time a web page loads, a conversation happens between your browser and a server. The browser sends a message describing what it wants, and the server sends back a message containing the answer. These two messages are the fundamental units of the web. Understanding their structureโ€”what each part does, what order it appears in, and how the other side interprets itโ€”is the difference between treating HTTP as a black box and understanding why a request succeeds, fails, or redirects.

The structure is consistent across every interaction. A request has a start line, headers, and an optional body. A response has the same three parts, but the start line contains a status code instead of a method. The rules for constructing these messages are defined in the HTTP specification, and the ordering of headers, the presence of a body, and the interpretation of status codes all follow that specification . Once you know the shape of the message, you can read raw HTTP traffic, debug an API call, and understand why a server rejected your request.

This chapter covers the anatomy of both messages, the meaning of the start line and headers, how the body is framed, and the status codes that report the outcome. It also explains the practical distinction between GET and POST requests, which is where most beginners first encounter the protocol’s design decisions.

Key point: An HTTP request consists of a method, a target, and a version on the start line, followed by headers and an optional body; an HTTP response consists of a version, a status code, and a reason phrase on the start line, followed by headers and an optional body, and the status code determines how the client interprets the rest of the message.


Why the message format is structured this way

The line-based legacy. HTTP/1.1 was designed to be human-readable. The start line and headers are plain text, with each header on its own line and a blank line marking the end of the headers. This made the protocol debuggable with a terminal and a telnet connection, which was essential in the early web. The body can be binary, but the framing around it is text. HTTP/2 replaced this text framing with binary frames for efficiency, but the semantic structureโ€”method, target, headers, bodyโ€”remains identical.

The header ordering problem. The specification says that the order of headers with different names is not significant, but it recommends sending general headers first, then request or response headers, then entity headers . In practice, most clients and servers do not care about order. What matters is the blank line that separates headers from the body. Without that blank line, the server cannot know where the headers end and the body begins.

The body framing problem. A request or response body is optional. For a GET request, there is usually no body. For a POST request, the body contains the submitted data. The server needs to know whether a body is present and how large it is. The Content-Length header provides the size in bytes. The Transfer-Encoding: chunked header indicates that the body is sent in chunks, each with its own size prefix, which is useful when the total size is not known in advance . Without one of these headers, the server assumes there is no body.

The GET versus POST distinction. The method on the request line determines how the data is carried. A GET request encodes parameters in the URL, after a ? and separated by &. A POST request encodes the data in the body . This is not a stylistic choice. GET is defined as a safe and idempotent method: it should only retrieve data and should not change the server’s state . POST is neither safe nor idempotent: it submits data that may create a resource or trigger a side effect. The method tells the server and any intermediary caches how to treat the request.


a. The HTTP request message

A request message has four parts: the request line, the headers, a blank line, and an optional body.

The request line contains three space-separated elements: the method, the request target, and the HTTP version . The method is a verb like GET or POST. The target is usually the path of the resource, such as /index.html, but it can also be an absolute URI in some proxy scenarios. The version is HTTP/1.1 or HTTP/2, though HTTP/2 does not use a textual request line; the method and path are carried in binary headers instead.

Headers follow the request line. Each header is a name, a colon, and a value. The Host header is mandatory in HTTP/1.1 because a single server can host multiple domains on one IP address, and the server needs to know which domain the request is for. Other common request headers include User-Agent (identifies the client software), Accept (lists the media types the client can handle), Accept-Language (lists the preferred languages), and Authorization (carries credentials) .

A blank line marks the end of the headers. Everything after the blank line is the body. The body is present in requests like POST and PUT, where the client is sending data to the server. A GET request typically has no body. The Content-Length or Transfer-Encoding header tells the server how to read the body if one is present .


b. The HTTP response message

A response message has the same structure as a request, but the start line is different. It contains the HTTP version, a three-digit status code, and a reason phrase .

The status code is the most important part of the response. It tells the client what happened. The first digit defines the category: 2xx means success, 3xx means redirection, 4xx means the client made an error, and 5xx means the server made an error . The reason phrase is a human-readable description of the code, like OK for 200 or Not Found for 404. It is not required to be any specific string; the code is what matters.

Response headers carry metadata about the response. The Content-Type header tells the client what kind of data the body contains, such as text/html or application/json. The Content-Length header gives the size of the body. The Cache-Control header tells the client and any intermediary caches how long the response can be reused. The Location header appears in redirect responses and specifies the new URL .

The body contains the actual resource if the request succeeded and a body is appropriate. A 200 OK response to a GET request for an HTML page contains the HTML. A 201 Created response to a POST request might contain the newly created resource or a reference to it. A 204 No Content response has headers but no body. A 404 Not Found response may contain an HTML error page or a JSON error object, depending on the server.


c. Status codes and what they mean for the client

The status code determines how the client should interpret the response. This is not just a label; it changes what the client does next.

A 200 OK tells the client that the request succeeded and the body contains the requested representation . The client should process the body. A 201 Created tells the client that a new resource was created, usually in response to a POST or PUT. The Location header often points to the new resource .

A 301 Moved Permanently tells the client that the resource has a new permanent URL, given in the Location header. The client should update its bookmarks and use the new URL for future requests. A 302 Found tells the client that the resource is temporarily at a different URL. A 304 Not Modified tells the client that its cached copy is still valid, so it should use the cache instead of downloading the resource again .

A 400 Bad Request tells the client that the server could not understand the request, often because the syntax was malformed. A 401 Unauthorized tells the client that authentication is required, and the response usually includes a WWW-Authenticate header describing the authentication scheme. A 403 Forbidden tells the client that the server understood the request but refuses to authorize it, and re-authenticating will not help. A 404 Not Found tells the client that the resource does not exist .

A 500 Internal Server Error tells the client that the server encountered an unexpected condition and could not fulfill the request. A 503 Service Unavailable tells the client that the server is temporarily overloaded or under maintenance, and the Retry-After header may suggest when to try again .


Complete Example Session

The following session shows a complete request-response exchange for a GET request and a POST request, with annotations for each part.

// ============================================
// PART 1: THE GET REQUEST
// ============================================
GET /articles/rust HTTP/1.1        โ† method, target, version
Host: example.com                   โ† mandatory in HTTP/1.1
User-Agent: Mozilla/5.0             โ† client identity
Accept: text/html                   โ† preferred response type
Accept-Language: en-US,en;q=0.9     โ† preferred languages
                                    โ† blank line ends headers
                                    โ† no body for GET

// ============================================
// PART 2: THE GET RESPONSE
// ============================================
HTTP/1.1 200 OK                     โ† version, status code, reason
Content-Type: text/html; charset=UTF-8  โ† body is HTML
Content-Length: 1256                โ† body size in bytes
Cache-Control: max-age=3600         โ† cache for one hour
                                    โ† blank line ends headers
<!DOCTYPE html>                     โ† body begins
<html><body><h1>Rust</h1></body></html>

// ============================================
// PART 3: THE POST REQUEST
// ============================================
POST /articles HTTP/1.1             โ† method is POST
Host: example.com
Content-Type: application/json      โ† body is JSON
Content-Length: 45                  โ† body size
                                    โ† blank line ends headers
{"title": "Async Rust", "body": "..."}  โ† body contains data

// ============================================
// PART 4: THE POST RESPONSE
// ============================================
HTTP/1.1 201 Created                โ† new resource created
Location: /articles/42              โ† URL of the new resource
Content-Type: application/json
Content-Length: 21
                                    โ† blank line
{"id": 42, "status": "created"}     โ† body confirms creation

// ============================================
// PART 5: A REDIRECT RESPONSE
// ============================================
HTTP/1.1 301 Moved Permanently      โ† permanent redirect
Location: https://example.com/new-path  โ† new URL
Content-Length: 0
                                    โ† no body needed

// ============================================
// PART 6: AN ERROR RESPONSE
// ============================================
HTTP/1.1 404 Not Found              โ† resource missing
Content-Type: text/html
Content-Length: 150
                                    โ† blank line
<html><body><h1>Page not found</h1></body></html>

The six parts cover a GET request and its 200 OK response, a POST request and its 201 Created response, a redirect response, and an error response. What the session demonstrates is that the structure is identical across all messages: a start line, headers, a blank line, and an optional body. The method on the request line and the status code on the response line are the parts that determine meaning.


Quick Reference

Request Line

PartExampleMeaning
MethodGET, POSTIntent of the request
Target/articles/rustResource path
VersionHTTP/1.1Protocol version

Response Line

PartExampleMeaning
VersionHTTP/1.1Protocol version
Status code200, 404Outcome category
Reason phraseOK, Not FoundHuman-readable description

Common Request Headers

HeaderPurpose
HostTarget domain (required in HTTP/1.1)
User-AgentClient software identity
AcceptPreferred response media types
Content-TypeMedia type of request body
Content-LengthSize of request body
AuthorizationCredentials for authentication

Common Response Headers

HeaderPurpose
Content-TypeMedia type of response body
Content-LengthSize of response body
Cache-ControlCaching instructions
LocationRedirect target or new resource URL

Status Code Categories

RangeMeaningClient Action
2xxSuccessProcess the body
3xxRedirectionFollow Location
4xxClient errorFix the request
5xxServer errorRetry or report

Best Practices

โœ… Do This:

// Use GET for retrieval, POST for creation
// Set Content-Type on requests with a body
// Set Content-Length or use chunked encoding
// Check the status code before reading the body
// Include the Host header in HTTP/1.1 requests

โŒ Don’t Do This:

// Use GET for operations that change state
// Omit Content-Length when sending a body
// Assume a 200 response means the operation succeeded
// Ignore the Location header on redirects
// Send sensitive data in a GET URL

Common Pitfalls

PitfallWhy It HappensFix
Server cannot parse requestMissing blank line after headersEnsure \r\n\r\n separates headers from body
Body not receivedNo Content-Length headerAdd Content-Length or use chunked encoding
Client ignores redirectStatus code not checkedFollow 3xx responses with Location
API returns error but client succeedsStatus code ignoredCheck status code before processing body
GET request rejected for large dataURL length limitUse POST with body

Real-World Examples

1. Basic GET request

GET /index.html HTTP/1.1
Host: example.com

2. Basic 200 response

HTTP/1.1 200 OK
Content-Type: text/html

3. POST with JSON body

POST /api/users HTTP/1.1
Content-Type: application/json
Content-Length: 42

{"name": "Alice", "age": 30}

4. 201 Created response

HTTP/1.1 201 Created
Location: /api/users/42

5. 404 error response

HTTP/1.1 404 Not Found
Content-Type: text/html

6. 301 redirect

HTTP/1.1 301 Moved Permanently
Location: https://example.com/new

7. HEAD request

HEAD /large.zip HTTP/1.1
Host: example.com

8. 204 No Content

HTTP/1.1 204 No Content

9. 401 Unauthorized

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer

10. 500 Server Error

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{"error": "Database connection failed"}

Visual

Request Message Anatomy

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  GET /articles/rust HTTP/1.1   โ† start line  โ”‚
โ”‚  Host: example.com             โ† header      โ”‚
โ”‚  Accept: text/html             โ† header      โ”‚
โ”‚  User-Agent: Mozilla/5.0       โ† header      โ”‚
โ”‚                                โ† blank line  โ”‚
โ”‚  (body, usually none for GET)  โ† body        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Response Message Anatomy

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  HTTP/1.1 200 OK               โ† start line  โ”‚
โ”‚  Content-Type: text/html       โ† header      โ”‚
โ”‚  Content-Length: 1256          โ† header      โ”‚
โ”‚  Cache-Control: max-age=3600   โ† header      โ”‚
โ”‚                                โ† blank line  โ”‚
โ”‚  <html>...</html>              โ† body        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

GET vs POST Data Placement

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  GET /search?q=rust&page=2 HTTP/1.1          โ”‚
โ”‚  Data in URL after ?                         โ”‚
โ”‚  Visible in history, logs, bookmarks         โ”‚
โ”‚                                              โ”‚
โ”‚  POST /search HTTP/1.1                       โ”‚
โ”‚  Content-Type: application/x-www-form-urlencoded โ”‚
โ”‚  Content-Length: 17                          โ”‚
โ”‚                                              โ”‚
โ”‚  q=rust&page=2                               โ”‚
โ”‚  Data in body                                โ”‚
โ”‚  Not visible in URL                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Status Code Decision

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  2xx โ†’ Success, read the body                โ”‚
โ”‚  3xx โ†’ Redirect, follow Location             โ”‚
โ”‚  4xx โ†’ Client error, fix the request         โ”‚
โ”‚  5xx โ†’ Server error, retry or report         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
Request start lineMethod, target, version
Response start lineVersion, status code, reason phrase
Header separatorBlank line
Body presenceSignaled by Content-Length or Transfer-Encoding
Host headerRequired in HTTP/1.1
Content-TypeMedia type of body
2xxSuccess
3xxRedirect
4xxClient error
5xxServer error

Key takeaways:

  • Both messages have the same structure. A start line, headers, a blank line, and an optional body. The difference is what the start line contains: a method for requests, a status code for responses .
  • The blank line separates headers from body. Without it, the server cannot know where the body begins.
  • The Host header is mandatory in HTTP/1.1. It tells the server which domain the request is for, which is necessary when multiple domains share an IP address .
  • GET puts data in the URL; POST puts data in the body. GET is for retrieval and should not change state. POST is for submission and can create resources .
  • The status code determines the client’s next action. 2xx means process the body. 3xx means follow the redirect. 4xx means fix the request. 5xx means retry or report .
  • The body is optional. A GET request usually has no body. A 204 No Content response has no body. The Content-Length or Transfer-Encoding header tells the recipient whether to expect one .

Remember: An HTTP exchange is a conversation with a fixed grammar. The request line says what the client wants. The headers say how to interpret the message. The blank line says where the headers end. The body carries the data. The response follows the same pattern, with a status code replacing the method. Once you can read the start line and the Content-Type, you can understand any HTTP message, whether it is a simple page load, an API call, or a redirect that sends you somewhere else. The protocol has evolved from text to binary, but the structure of the conversation has never changed.


Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!