Search code examples
jettyembedded-jettyjetty-8

Static content in my C:\ drive being aliased away by jetty ResourceHandler


I am using emmedded jetty in my java project. For some reason, the path I am sending into resourceHandler is c:\ (lower case) and it is being aliased to C:\ (upper case). Because of this my static content is not being served.

I read some docs that indicated that jetty compares the absolute path and canonical path to detect aliases. In the log I see:

[qtp15485575-19] INFO org.eclipse.jetty.server.handler.ResourceHandler - file:/c:/filepath aliased to file:/C:/filepath

Anyone have any ideas on how to resolve?

Update: logged bug to eclipse for this: https://bugs.eclipse.org/bugs/show_bug.cgi?id=471526

Here's their response: "it is indeed very annoying, but is forced on us by the poor security model of the servlet spec.

IF the spec had said that all URIs were denied unless explicitly allowed, we would not need to check for aliases. But instead it has a model where it allows all URIs except those that are specifically denied.

Thus if a security constraint is put on /secretfile.txt we have to make sure that any aliases of that file are also constrained... and do so in an FS independent way. That means on various operating systems we might need to block:

/sEcRetFile.TXT
/secretfile.txt 
/SECRE~01.TXT
/secretfile.txt@@0

etc. etc. etc.

So to be sure, we have implemented the alias system.

Normally we don't get problems with c: and C: because that should be normalized when configuring the context, so the correct one should be used. But filesystems do change their behaviour between releases, so it can be very annoying.

I think this is handled somewhat better in jetty 9.3 where we can use the Path classes to better examine parts of the path."

So probably the best bet is to use Jetty 9 if you can and use Joakin's fix if it is still an issue.


Solution

  • Give your ResourceHandler a full, absolute, and real path.

    package jetty.resource;
    
    import java.io.File;
    import java.nio.file.Path;
    
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.server.handler.ResourceHandler;
    import org.eclipse.jetty.util.resource.PathResource;
    
    public class ResourceHandlerFromFSExample
    {
        public static void main(String[] args) throws Exception
        {
            Server server = new Server(8080);
    
            Path webRootPath = new File("src/test/webroot").toPath().toRealPath();
    
            System.err.println("WebRoot is " + webRootPath);
    
            ResourceHandler handler = new ResourceHandler();
            handler.setBaseResource(new PathResource(webRootPath));
            handler.setDirectoriesListed(true);
    
            server.setHandler(handler);
    
            server.start();
            server.join();
        }
    }
    

    And btw, DefaultServlet is still a better choice for static file serving.