Serving Static Content
Web Servers Fundamentals
Chapter 5 · Serving Static Content
Chapter 1 described serving a static file as simply "read it from disk, send it back" — true as far as it goes, but there's more going on underneath. This chapter covers three details every one of the three servers has to handle for static content: telling the browser what kind of file it just received, deciding what to serve when a URL names a folder rather than a file, and what happens when there's nothing obvious to serve at all.
MIME Types: Telling the Browser What It's Looking At
Every HTTP response includes a Content-Type header — the MIME type — telling the browser how to interpret the bytes that follow (as HTML, as CSS, as a JPEG image, and so on). Each server maps file extensions to MIME types using its own lookup table: Apache and Nginx both ship a mime.types file mapping common extensions to their MIME type, extendable via Apache's AddType directive or Nginx's own types {} block; IIS maintains its own MIME type mappings through IIS Manager or the equivalent XML config. An extension with no matching entry typically falls back to a generic type like application/octet-stream, which prompts most browsers to offer the file as a download rather than trying to render it — a frequent, easy-to-miss cause of "why is my browser downloading this instead of showing it."
Directory Indexes: What Happens When a URL Names a Folder
Requesting /blog/ rather than a specific file requires the server to decide what to actually serve. All three maintain an ordered list of candidate filenames to check inside that directory: Apache's DirectoryIndex directive (commonly index.html index.php, checked in order), Nginx's index directive (the same idea, its own directive name), and IIS's Default Document feature, configured via IIS Manager, listing candidates like Default.htm or index.html in priority order. All three are solving the exact same problem — what to serve for a bare directory request — just under a different directive name each.
Directory Listings: What Happens With No Matching Index File
If none of the configured index candidates exist in a requested directory, each server has a separate, distinct setting controlling what happens next: generate an automatic listing of the directory's actual contents, or return an error. Apache's mod_autoindex can generate this listing if explicitly enabled; Nginx's own autoindex directive is off by default; IIS's Directory Browsing feature is likewise off by default. Enabling this is occasionally useful (a simple internal file share), but it's also a well-known way to accidentally expose a directory's full contents to anyone who requests it.
| Apache | Nginx | IIS | |
|---|---|---|---|
| MIME type mapping | mime.types + AddType | mime.types + types {} | MIME Types config (GUI/XML) |
| Default document directive | DirectoryIndex | index | Default Document (GUI) |
| Directory listing default | Off (module not typically enabled) | Off (autoindex off) | Off (Directory Browsing disabled) |
| Unknown extension fallback | application/octet-stream | application/octet-stream | application/octet-stream |
text/plain or application/octet-stream instead of text/css, many browsers refuse to apply it as a stylesheet at all. Checking the actual Content-Type header, not just whether the file loaded, is the right first step whenever this happens.
Hands-On Exercises
A server serves a .woff2 font file with no matching MIME type entry configured, so it falls back to application/octet-stream. Explain what a browser is likely to do when it requests this file as part of loading a webpage's CSS, and why.
📄 View solutionA directory contains index.php but not index.html, and the server's directory-index list is configured as "index.html index.php" in that order. Explain what actually gets served when a bare directory URL is requested, and why the order of the list matters.
📄 View solutionA developer enables directory listing on a production server "temporarily, just to quickly check what files are in a folder from the browser," then forgets to disable it. Explain, using this chapter's own warning box, what could actually go wrong if this is left enabled.
📄 View solutionChapter 5 Quick Reference
- MIME types tell the browser how to interpret a response's body — an unmapped extension falls back to
application/octet-stream, often triggering a download instead of rendering - Directory index candidates — Apache's
DirectoryIndex, Nginx'sindex, IIS's Default Document — all check an ordered list of filenames for a bare directory request - Directory listing is off by default on all three servers, for good reason — it's a real, common way to accidentally expose a folder's contents