public class StaticHandler extends Object implements HttpHandler
A StaticHandler
maps a uriPrefix
to a dirPrefix
;
a URI with the uriPrefix
is mapped to a file with the dirPrefix
.
For example, if uriPrefix="/uri", dirPrefix="/dir"
,
the URI "/uri/x/y.txt"
is mapped to the file "/dir/x/y.txt"
.
Each file can be configured individually by confMod
.
See constructor StaticHandler(uriPrefix, dirPrefix, confMod)
.
URI encoding uses UTF-8 only; no other charset is supported.
A StaticHandler
can be used directly for an HttpServer
,
if the server serves nothing but static files.
More often, a StaticHandler
is used in a parent handler that servers
both static files and dynamic contents. For example
StaticHandler staticHandler = new StaticHandler("/uri", "/dir"); HttpHandler appHandler = request -> { // try static files first HttpResponseImpl resp = staticHandler.handle(request); if(resp.statusCode()!=404) // 200, or other error codes return resp; // 404, request URI is not mapped to a static file ... };
See handle(HttpRequest)
for types of responses StaticHandler may generate.
StaticHandler
supports tagged URI which embeds the
ETag
of the file.
Response to a tagged URI never expires and can be cached forever.
For example, if currently ETag="v1.2.3"
for file "/dir/css/main.css"
,
the tagged URI is "/uri/css/main.css?v1.2.3"
.
This URI can be obtained by staticHandler.uri("css/main.css")
.
// an html template _link().rel("stylesheet").type("text/css").href( staticHandler.uri("css/main.css) )
The browser can request "/uri/css/main.css?v1.2.3"
once and cache it forever.
When the ETag is changed (because the file is modified), a new tagged URI is generated,
and the browser will issue a new request to get the new content.
Constructor and Description |
---|
StaticHandler(String uriPrefix,
String dirPrefix)
Create a StaticHandler with default settings.
|
StaticHandler(String uriPrefix,
String dirPrefix,
ConsumerX<StaticFileConf> confMod)
Create a StaticHandler.
|
Instance Methods | |
---|---|
HttpResponseImpl |
handle(HttpRequest request)
Try to serve the request with a file response.
|
String |
uri(String relativeFilePath)
Get the URI for the file identified by
relativeFilePath . |
String |
info()
Return a text document listing all files and their metadata.
|
public StaticHandler(String uriPrefix, String dirPrefix) throws RuntimeException
See constructor
StaticHandler(uriPrefix, dirPrefix, confMod)
for details.
RuntimeException
public StaticHandler(String uriPrefix, String dirPrefix, ConsumerX<StaticFileConf> confMod) throws RuntimeException
uriPrefix
must be a valid URI path, starting with "/".
Examples: "/", "/uri", "/foo/bar"
.
dirPrefix
must point to a directory.
Examples: "/dir", "../dir"
.
confMod
is used to modify per-file config variables.
For each file under the directory, a StaticFileConf
is created with default values,
then passed to confMod
; confMod
can modify any variables
in the StaticFileConf
.
Example usage:
// map "/uri/xxx" to "/dir/xxx"; cache every file in memory. static final StaticHandler staticHandler = new StaticHandler("/uri", "/dir", conf->conf.cache(true) );
This constructor does blocking IO to read metadata of all files under the directory. That's not a problem if the static handler is created during application startup; but be careful if used in a non-blocking/async context.
RuntimeException
- if something went wrong unexpectedly, for example file metadata cannot be read.public HttpResponseImpl handle(HttpRequest request)
If the request is GET/HEAD, and the URI maps to a file, a 200 response is returned to serve the file.
Other possible responses:
These error responses contain very simple text messages. If necessary (mostly for 404), the caller can transform the response to a better one.
This method always returns a new HttpResponseImpl
which the caller can modify at will.
handle
in interface HttpHandler
public String uri(String relativeFilePath) throws IllegalArgumentException
relativeFilePath
.
relativeFilePath
is relative to dirPrefix
;
it must not start with "/" or "\"; it must not have been encoded with URI encoding.
This method has two purposes: to encode the URI, and to tag the URI.
For example, if
uriPrefix="/uri", dirPrefix="/dir"
,
uri("x/a b.txt")
is mapped for file "/dir/x/a b.txt"
,
and the resulting URI is something like "/uri/x/a%20b.txt?t-53486116-314fb010"
.
relativeFilePath
can also point to a directory that contains an
index file
.
For example, uri("x") or uri("x/")
means file "/dir/x/index.html"
,
uri("")
means file "/dir/index.html"
.
IllegalArgumentException
public String info()
This is for diagnosis only. The document can be dumped on stdout, or served through a secret URL.
if(request.uri().equals(...)) return HttpResponse.text(200, staticHandler.info());