Class StaticFiles
- All Implemented Interfaces:
HttpServer.Handler
Serves files out of a document root, on the kernel's zero-copy path.
The body goes out with sendfile() where the platform has it: the bytes move from the page cache to the socket inside the kernel, never entering this process. For a file server that is the difference between two copies per byte and none. TLS is the exception and always will be -- encrypted bytes have to be produced in user space, so that path reads and writes like anything else.
Correctness this does NOT cut corners on:
- the resolved file must be inside the root, proven with realpath() rather than by inspecting the request string. "../" is only the obvious attack; percent-encoding and a symlink pointing out of the tree are the other two, and only resolution catches all three
- the descriptor is opened FIRST and stat'd from the open fd, so the length in the header and the bytes in the body describe the same file even if it is replaced mid-request
- conditional requests (If-None-Match, If-Modified-Since) and ranges, because a static server without them re-sends whole files to clients that already have them
-
Constructor Summary
ConstructorsConstructorDescriptionStaticFiles(String root, String prefix, String indexFile, String cacheControl) root: the document root; resolved once, and every request must land inside it
StaticFiles(String root, String prefix, String indexFile, String cacheControl, boolean precompressed) As above, and withprecompresseda file that has a gzip copy beside it -
Method Summary
Modifier and TypeMethodDescriptionhandle(HttpServer.Request request) static booleanTrue when the body is sent by the kernel rather than copied through here.
-
Constructor Details
-
StaticFiles
public StaticFiles(String root, String prefix, String indexFile, String cacheControl) throws IOException root: the document root; resolved once, and every request must land inside itprefix: URL prefix to strip, "" or "/" for nonecacheControl: the Cache-Control value, or null to omit it
- Throws:
IOException
-
StaticFiles
public StaticFiles(String root, String prefix, String indexFile, String cacheControl, boolean precompressed) throws IOException As above, and with
precompresseda file that has a gzip copy beside it --app.js.gznext toapp.js-- is answered with that copy to a client that accepts gzip.This is how a large text file is compressed without leaving the zero-copy path: compressing on the way out would mean reading the whole file into this process for every request, and the copy made once at build time goes from the page cache to the socket like any other file. It is off unless asked for, because nothing but the build that wrote both can know that
x.gzisxcompressed and not some other file.- Throws:
IOException
-
-
Method Details
-
isZeroCopy
public static boolean isZeroCopy()True when the body is sent by the kernel rather than copied through here. -
handle
- Specified by:
handlein interfaceHttpServer.Handler- Throws:
Exception
-