You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Garret Wilson <ga...@globalmentor.com> on 2019/05/04 16:39:51 UTC

determining resource MIME type via metadata sidecars

Let's say that I want to use embedded Tomcat to serve static content 
using `org.apache.catalina.servlets.DefaultServlet`. But rather than 
determining each resource's MIME type from the server's fixed list of 
MIME types, I want to determine each resource's MIME type dynamically 
based upon some resource metadata, not the resource filename extension.

Just as an example, for the resource `foobar`, I might have a 
`foobar.sidecar.properties` sidecar file that contains a `contentType` 
property of `text/html` for that resource, even though `foobar` has no 
extension at all.

(If you really want to know /why/: I'm experimenting having "clean" 
URLs, not by URL rewriting via Apache which I know how to do, but by 
uploading resources without extensions to AWS S3 buckets and setting the 
content type metadata for the resource there so they will be served as 
HTML files. But I still want to test locally with a server, which is 
where Tomcat comes in.)

So to pull this off, it looks like I would have to:

 1. Extend `FileResource` so that it reads the metadata from wherever
    (e.g. a sidecar) and returns it via `getMimeType()`.
 2. Extend `FileResourceSet` so that it creates `MyFileResource` instead
    of `FileResource`. (There doesn't seem to be a way to plug in a
    factory.)
 3. Extend `StandardRoot` so that it creates `MyFileResourceSet` rather
    than `FileResourceSet`. (There doesn't seem to be a way to plug in a
    factory here, either.)
 4. When I create my embedded context, call `myContext.setResources()`
    passing it `MyStandardRoot`.

Is that pretty much the gist of it?

This is probably going to be even more difficult than it sounds because 
some of the classes I have to extend don't nicely modularize their 
factory functionality. For example when I override 
`FileResourceSet.getResource()` to create a `MyFileResource`, I'll have 
to copy basically all the code in that method just to get at the single 
`return new FileResource(root, path, f, isReadOnly(), null)` line that I 
want to override. :(

Is this more trouble than it's worth? Is there an easier approach? Or is 
this another case where I should look into alternative embedded servers?

Garret