KAHIBARO
Discord Login Register

2.12. HTTP Headers

Understanding HTTP Headers

HTTP headers are small pieces of information that travel along with every HTTP request and response. They are like labels on a package that tell the server or browser how to handle the content, how to cache it, how to authenticate, and much more.

This chapter focuses on what headers are and how you, as a backend developer, use them. Other chapters explain HTTP requests, responses, status codes, cookies, sessions, and security in more depth. Here we focus on headers as a general concept and the most important examples.


What Is an HTTP Header?

Every HTTP message has three parts:

  1. Start line
    • Request: GET /path HTTP/1.1
    • Response: HTTP/1.1 200 OK
  2. Headers
    • Key-value pairs, one per line, like:
      Content-Type: application/json
  3. Optional body
    • The actual data, like HTML, JSON, an image, etc.

Headers are simple text lines in the format:

Header-Name: value

For example, a complete raw HTTP request might look like:

http
GET /products?page=2 HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0
Accept: text/html
Accept-Language: en-US
Cookie: session_id=abc123

And a response:

http
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1024
Cache-Control: max-age=60
Set-Cookie: session_id=abc123; HttpOnly; Path=/
Server: my-backend/1.0
<html>...</html>

Everything between the first line and the blank line is headers.

Rule: Every header line is Name: value and headers end at the first blank line. The body, if any, starts after that blank line.


Why Headers Matter for Backend Developers

As a backend developer you will:

Even if your framework hides the raw HTTP, you still choose which headers to read and which to send.


Header Naming and Case Sensitivity

Header names are case-insensitive. These are all treated the same:

In practice, you should follow the common style: Title-Case-With-Dashes.

Header values may be case-sensitive depending on the specific header. For example, Bearer in Authorization: Bearer token is usually case-sensitive for the scheme name.


Common Request Headers

Host

Identifies which domain name the client is trying to reach:

http
Host: example.com

This is important when multiple websites share the same IP address.

User-Agent

Describes the client software:

http
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...

You might use this to:

You should not rely on it for security, since it is easy to fake.

Accept

Tells the server what media types the client can understand:

http
Accept: text/html
Accept: application/json
Accept: text/html,application/xhtml+xml,application/xml;q=0.9

In APIs, you often respond with JSON if:

http
Accept: application/json

Accept-Language

Preferred human languages of the user:

http
Accept-Language: en-US,en;q=0.9,fr;q=0.8

You might select error messages or UI language based on this.

Content-Type (on requests)

When a request has a body (POST, PUT, PATCH), Content-Type tells the server how to parse it:

Examples:

Content-TypeMeaningTypical Use
application/jsonJSON dataJSON API requests
application/x-www-form-urlencodedURL encoded form dataClassic HTML forms
multipart/form-dataMultipart body with boundariesForms with file uploads
text/plainPlain textSimple webhooks, debug requests

Example POST with JSON:

http
POST /api/items HTTP/1.1
Host: api.example.com
Content-Type: application/json
Content-Length: 35
{"name": "Pen", "price": 3.5}

As a backend developer, you must:

Content-Length

Number of bytes in the body:

http
Content-Length: 35

In practice, your framework or server manages this for you.

Authorization

Carries credentials for authentication:

http
Authorization: Basic dXNlcjpwYXNz
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

You will handle this in authentication logic.

Cookie

The browser sends cookies back to the server in this header:

http
Cookie: session_id=abc123; theme=dark

You read cookies from this header. You set them in responses with Set-Cookie (explained later).


Common Response Headers

Content-Type (on responses)

Tells the client how to interpret the response body:

http
Content-Type: text/html; charset=utf-8
Content-Type: application/json; charset=utf-8
Content-Type: image/png

Your backend should always set this correctly. For an API returning JSON, you usually send:

http
Content-Type: application/json; charset=utf-8

Content-Length

Size of the response body in bytes:

http
Content-Length: 2048

Often handled automatically by your web server or framework.

Cache-Control

Controls caching by browsers and proxies:

http
Cache-Control: no-store
Cache-Control: no-cache
Cache-Control: max-age=60
Cache-Control: public, max-age=3600
Cache-Control: private, max-age=0, no-cache

Some common directives:

DirectiveMeaning
max-age=60Response can be cached for 60 seconds
no-cacheMust revalidate with server before reuse
no-storeMust not store this response at all (good for sensitive data)
publicCan be cached by any cache (browser, proxies, CDNs)
privateOnly the end user’s browser can cache it, not shared caches

As a backend developer, you choose caching rules for:

Location

Used mainly with redirects or newly created resources:

http
HTTP/1.1 302 Found
Location: https://example.com/login
HTTP/1.1 201 Created
Location: /api/items/123

Set-Cookie

Instructs the browser to store a cookie:

http
Set-Cookie: session_id=abc123; HttpOnly; Path=/; Secure; SameSite=Lax

Important attributes:

AttributePurpose
HttpOnlyNot accessible from JavaScript
SecureOnly sent over HTTPS
SameSiteControls cross-site cookie sending behavior
PathLimits which paths will send the cookie
DomainLimits which domains will send the cookie
Expires / Max-AgeControls cookie lifetime

Set-Cookie is covered in more detail in the Cookies chapter. Here you just need to know it is a response header that creates or updates cookies.

Server

Identifies the software handling the request:

http
Server: nginx/1.25.0
Server: my-backend/1.0

For security reasons, you should not expose too much detail.


Headers for Content Negotiation

Content negotiation is how the client and server agree on the best representation of a resource.

Common request headers:

Common response headers:

Example:

http
GET /article/42 HTTP/1.1
Host: example.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9
Accept-Language: fr-FR,fr;q=0.9,en;q=0.8
Accept-Encoding: gzip, deflate, br

Server response:

http
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Language: fr-FR
Content-Encoding: gzip

The server chose French HTML, and gzip compressed it.


Caching and Conditional Requests

Headers are heavily used for caching. A simple example:

http
HTTP/1.1 200 OK
ETag: "abc123"
Cache-Control: max-age=60
Last-Modified: Wed, 21 Aug 2024 10:00:00 GMT

Next time the client requests this resource, it may send:

http
GET /resource HTTP/1.1
If-None-Match: "abc123"
If-Modified-Since: Wed, 21 Aug 2024 10:00:00 GMT

If the resource did not change, the server can respond:

http
HTTP/1.1 304 Not Modified

No body is needed. The client reuses its cached copy.

Key headers in this area:

Handling these correctly can greatly reduce bandwidth and improve performance.


Security Related Headers

Some security controls are done with headers. They are discussed in detail in the Backend Security chapter, but here is a quick overview.

Examples:

http
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: no-referrer

Rough purposes:

HeaderPurpose
Strict-Transport-SecurityForce HTTPS in browsers
Content-Security-PolicyLimit where scripts and resources can load
X-Content-Type-OptionsPrevent MIME type sniffing
X-Frame-OptionsControl if page can be shown in an iframe
Referrer-PolicyControl Referer header details sent by browser

As a backend developer, you usually configure these globally in your server or framework middleware.


CORS Related Headers

Cross-Origin Resource Sharing (CORS) uses headers to allow or block browser requests from other domains.

Server side example:

http
Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true

These headers are explained deeply in the CORS section, but from a headers point of view:

Custom Headers

You can define your own headers for application specific needs. By convention, custom headers often start with X-, although modern practice is to just use a clear name.

Examples:

http
X-Request-ID: 9a8f7e2c
X-User-Id: 42
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 1692619200
Request-ID: 9a8f7e2c
Correlation-ID: order-123

Use cases:

Rule: Avoid putting sensitive data (like passwords or full tokens) into custom headers unless absolutely necessary, and always use HTTPS.


Examples in a Typical Backend Scenario

Example 1: JSON API with Authentication

Client request:

http
GET /api/me HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Server response:

http
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Cache-Control: no-store
X-Request-ID: d1c3e4
{"id": 1, "email": "user@example.com"}

Key points:

Example 2: HTML Page with Session Cookie

Client initial request (no cookie yet):

http
GET /login HTTP/1.1
Host: example.com
Accept: text/html

Server response sets a cookie:

http
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Set-Cookie: session_id=abc123; HttpOnly; Path=/; Secure; SameSite=Lax
<html>...</html>

Next request from the browser:

http
GET /dashboard HTTP/1.1
Host: example.com
Accept: text/html
Cookie: session_id=abc123

The session mechanism depends on Set-Cookie and Cookie headers.


How Frameworks Expose Headers

In real code, your framework gives you simple ways to work with headers.

Reading Headers (Python / FastAPI example)

python
from fastapi import FastAPI, Request
app = FastAPI()
@app.get("/info")
async def info(request: Request):
    user_agent = request.headers.get("user-agent")
    accept = request.headers.get("accept")
    return {"user_agent": user_agent, "accept": accept}

Setting Headers

python
from fastapi import FastAPI, Response
app = FastAPI()
@app.get("/hello")
def hello():
    response = Response(
        content='{"message": "Hello"}',
        media_type="application/json",  # sets Content-Type
    )
    response.headers["X-Request-ID"] = "123abc"
    response.headers["Cache-Control"] = "no-store"
    return response

Even though you do not type raw HTTP, understanding the underlying headers helps you configure and debug behavior correctly.


Summary

In later chapters on cookies, sessions, security, and CORS, you will revisit many of these headers in more detail.

Views: 7

Comments

Please login to add a comment.

Don't have an account? Register now!