Files
cpp-httplib/docs-src/pages/en/cookbook/s04-static-files.md
T
yhirose 9bfd2ddf1c Fix README and docs pages that no longer match the code
Bring the READMEs and the docs pages (en and ja) in line with the
current header:

- Fix the client sample that does not compile, the Transfer-Encoding
  statement for default headers, the verifier callback comment, the
  thread pool spawn rule, the sanitize_filename description, and the
  inverted Accept-Encoding sentence.
- Describe recent behaviour: TLS errors behind Read/Write failures,
  Host validation, Connection: close for a body without length,
  content_reader rules, refused CONNECT, WebSocketClient proxies,
  CPPHTTPLIB_INTERIM_RESPONSE_MAX_COUNT, the SSE event size limit, and
  the payload limit of the Stream API.
- Complete the API references of WebSocket, WebSocketClient and the
  stream:: helpers, and the SSE reconnect rules.
- Fix cookbook pages: keychain loading on every backend, received Close
  status, a multipart sample that trusted the client's file name, an
  echo sample that sent binary as text, SNI, pre-request handler scope,
  stop() with WebSocket handlers, and the thread pool notes.
- Restore the mutex in the LLM app's Chapter 5 code.
2026-10-18 10:13:57 -04:00

2.1 KiB

title, order, status
title order status
S04. Serve Static Files 23 draft

To serve static files like HTML, CSS, and images, use set_mount_point(). Just map a URL path to a local directory, and the whole directory becomes accessible.

Basic usage

httplib::Server svr;
if (!svr.set_mount_point("/", "./public")) {
  // ./public doesn't exist
  return 1;
}
svr.listen("0.0.0.0", 8080);

set_mount_point() returns false when the directory doesn't exist, so check the return value.

./public/index.html is now reachable at http://localhost:8080/index.html, and ./public/css/style.css at http://localhost:8080/css/style.css. The directory layout maps directly to URLs.

A request for a directory serves its index.html, and one without the trailing slash (/docs) is redirected (301) to /docs/. A symlink that resolves outside the mounted directory gets a 403.

Multiple mount points

You can register more than one mount point.

svr.set_mount_point("/", "./public");
svr.set_mount_point("/assets", "./dist/assets");
svr.set_mount_point("/uploads", "./var/uploads");

You can even mount multiple directories at the same path — they're searched in registration order, and the first hit wins.

Combine with API handlers

Static files and API handlers coexist happily. For GET and HEAD, the mount points are searched first; handlers registered with Get() and friends run only when no file is found.

svr.Get("/api/users", [](const auto &req, auto &res) {
  res.set_content("[]", "application/json");
});

svr.set_mount_point("/", "./public");

This gives you an SPA-friendly setup: /api/* hits the handlers, everything else is served from ./public/.

Add MIME types

cpp-httplib ships with a built-in extension-to-Content-Type map, but you can add your own.

svr.set_file_extension_and_mimetype_mapping("wasm", "application/wasm");

Warning: The static file server methods are not thread-safe. Don't call them after listen() — configure everything before starting the server.

For download-style responses, see S06. Return a file download response.