HTTP Headers
# an Unexpected source of power
@docroms.com
Romuald
Bluesky : docroms.com
(link : 100ko)

LeadDev
- Performance
- Qualité (éthique, sécurité… )
- Eco-conception
- Ecologie
- Numérique Responsable
- Inclusion & Accessibilité



HTTP Headers ?
Metadata added to HTTP requests and responses
curl -I https://www.docroms.com
HTTP/2 103
link: </assets/styles/app-w4xBlKW.css>; as=style; rel=preload
HTTP/2 200
date: Sat, 06 Dec 2025 15:30:22 GMT
content-type: text/html; charset=UTF-8
cache-control: max-age=604800, public, s-maxage=31536000
content-security-policy: default-src 'none'; script-src 'self' 'nonce-M6Bq3suks0l/INdD59VptA=='; style-src 'self' 'nonce-M6Bq3suks0l/INdD59VptA=='; img-src 'self' data:; connect-src 'self'; worker-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; manifest-src 'self'; upgrade-insecure-requests;
[...]
alt-svc: h3=":443"; ma=86400
These are HTTP response headers.

Captured from our favorite browser’s DevTools.
HTTP Headers ?
-
Interpreted by browser, CDN, proxy, server
-
Control:
-
security
-
caching
-
protocol behavior
-
permissions
-
rendering
-
debugging
-
...
-

HTTP Headers ?

-
Pseudo-headers (h2/h3 only)
-
Accept-* (content negotiation)
-
Caching
-
Priority (exp)
-
Client capabilities, User-Agent
-
Client Hints
-
Fetch metadata
-
Privacy / Tracking Reduction
-
-
Cookies
-
Protocol version, languages
-
Custo

Request (client) → server
- protocol steering
- cache policy
- encoding
- security
- preload
- debug / CDN
Response (CDN & server) → client

Performance Headers

Headers don’t impact performance
... That’s why every fast website uses them.


cache-control: public, max-age=3600, s-maxage=86400
public
max-age=3600
s-maxage=86400
no-store / no-cache
public / private
browser cache
CDN cache (edge / surrogate cache)
content-encoding: zstd
zstd
gzip
deflate
br
good ratio + perf
old one
old one
good ratio
accept-encoding: gzip, br, zstd
link: </assets/app.css>; rel=preload; as=style
link: </assets/app.js>; rel=modulepreload
link
Early Hints
HTTP/2 103
link: </main.css>; rel=preload; as=style
link: </hero.webp>; rel=preload; as=image
preloading ressource

priority: u=0, i
🆕It's a modern header that lets the server tell the browser how important a resource is.
priority: high

Mdn Priority
(link, 234ko)
👆These headers can boost your performance…
...and some others can ruin it in a single line👇
set-cookie: session=ohmygod

CORS
Headers

Cross-Origin Resource Sharing
CORS isn’t here to protect your server !
It’s here to protect your users
and that protects your server from data leaks.
Mdn CORS
(link, 600ko)


Mdn CSRF*
(link, 876ko)

*Cross-Site Request Forgery
Access-Control-Allow-Origin: https://fr.docroms.com
URL Same origin? Why
| https://fr.docroms.com | ✅ YES | Exact same protocol + domain + port |
| https://jp.docroms.com | ❌ NO | Subdomains = different origins |
| http://fr.docroms.com | ❌ NO | Different protocol (http ≠ https) |
| https://fr.docroms.com:8080 | ❌ NO | Different port (443 ≠ 8080) |
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type, Authorization, X-Custom-Token
Access-Control-Request-Headers: X-Auth, Content-Type
Access-Control-Allow-Headers: X-Auth, Content-Type
👆Request header (client)
Response Header (server)👇
Access-Control-Max-Age: 86400
OPTIONS /api/user
Origin: https://my-app.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Auth, Content-Type
Access-Control-Allow-Origin: https://my-app.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: X-Auth, Content-Type
Access-Control-Max-Age: 86400
👆Request header (client)
Response Header (server)👇
Security
Headers
Mozilla observatory
Observatory
(link, 600ko)



content-security-policy :
default-src 'none';
script-src 'self' 'nonce-dieeyMPtZ2GBFaCMDgrQwQ=='; style-src 'self' 'nonce-dieeyMPtZ2GBFaCMDgrQwQ==';
img-src 'self' data:;
connect-src 'self';
worker-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
manifest-src 'self';
upgrade-insecure-requests;

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Referrer-Policy: strict-origin-when-cross-origin
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Permissions-Policy:
accelerometer=(),
camera=(),
microphone=(),
geolocation=(),
payment=(),
usb=(),
serial=(),
fullscreen=(),
autoplay=()
CORS headers + Security Headers = 💪

Customize
Headers
x-<my-header>: <myValue>
<my-header>: <myValue>
<my-header>:
You can invent any header you want !
Custom headers can be used for absolutely anything :
A/B testing, monitoring, debugging, performance analytics, feature flags...
You can even create headers whose only purpose is to expose or describe other headers !

Merci !
Des questions ?
Bluesky : docroms.com
(link : 100ko)



Les headers HTTP, force insoupçonnée
By Romuald Priol
Les headers HTTP, force insoupçonnée
- 13