Reading — step 1 of 5
Read
~1 min readCaching, Compression & Beyond
Virtual Hosting
One IP address routinely serves dozens of different sites. Shared web hosting, localhost development, and CDN edges all do this. The mechanism is the Host header — required since HTTP/1.1.
How it works
GET / HTTP/1.1
Host: blog.example.com
-> serve files for the 'blog' site
GET / HTTP/1.1
Host: shop.example.com
-> serve files for the 'shop' site
Same TCP socket, same IP, same nginx process — different document roots,
different config blocks, different access logs. nginx calls these server
blocks; Apache calls them VirtualHost; Caddy calls them site blocks.
Selection algorithm
- Look up the Host header value (case-insensitive, strip optional
:port). - If exact match exists, dispatch.
- Otherwise try wildcards in order of specificity:
*.example.commatchesblog.example.comandshop.example.combut notexample.comitself. - Else fall back to a configured default. Many production servers return
421 Misdirected Request(TLS) or404 Not Found(HTTP) if no match.
Edge cases
- Missing
Hostin HTTP/1.1 ->400 Bad Request(the header is mandatory) - Multiple Host headers ->
400(potential request smuggling) - IPv6 hosts use brackets:
Host: [::1]:8080 - The path is shared across vhosts —
/adminon blog.example.com and shop.example.com are different resources.
This is why HTTPS needed SNI — TLS needs to know which cert to use before the Host header is even readable, so the hostname is sent in the ClientHello.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…