Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jetty-dev] Jetty Split File Server combined with a Header Filter

Hi Joakim,

This is a delayed response but thanks very much for your assistance. I eventually got this working. The example I gave was a bit simplified so I had to make some changes to our code to get it all working.

Much appreciated - thanks for always answering Jetty questions for everyone.

Cheers!


On Wed, Jun 13, 2018 at 2:47 PM, Joakim Erdfelt <joakim@xxxxxxxxxxx> wrote:

Joakim Erdfelt / joakim@xxxxxxxxxxx

On Wed, Jun 13, 2018 at 1:44 PM, Joakim Erdfelt <joakim@xxxxxxxxxxx> wrote:
Don't mix ResourceHandler and ServletContextHandler unless you *REALLY* know what you are doing.

Eg: once you enter a ServletContextHandler you are subject to all of the rules for a javax.servlet.ServletContext.  You never exit a ServletContextHandler, and Filters only apply within the request chain within that ServletContext.
A sub-handler like you declared it, is NOT part of the ServletContext, or the request chain in that ServletContext.

A better approach, stay with 1 ServletContextHandler, no ResourceHandler, use the DefaultServlet instead to serve static content (its a MUCH better choice then ResourceHandler anyway).

File codeDocsDir = new File("/tmp/code-docs");
Resource codeDocsResource = Resource.newResource(codeDocsDir);
File userGuideDocsDir = new File("/tmp/user-guide-docs");
Resource userGuideDocsResource = Resource.newResource(userGuideDocsDir);
ResourceCollection resources = new ResourceCollection(codeDocsResource, userGuideDocsResource);

ServletContextHandler handler = new ServletContextHandler();
handler.setContextPath("/");
handler.setBaseResource(resources); // what static content resources are used

FilterHolder frameOptions = new FilterHolder(FRAME_OPTIONS_FILTER);
frameOptions.setName("X-Frame-Options");
 
handler.addFilter(frameOptions, "/*", EnumSet.allOf(DispatcherType.class));
handler.setContextPath(contextPath);

ServletHolder holderDef = new ServletHolder("default", DefaultServlet.class); // what serves the static resources
holderDef.setInitParameter("dirAllowed","false");
handler.addServlet(holderDef,"/");
 
return handler;

Joakim Erdfelt / joakim@xxxxxxxxxxx

On Wed, Jun 13, 2018 at 1:32 PM, Nathan Gough <returntosender404@xxxxxxxxx> wrote:
Hi,

I've created a demo application to demonstrate the issue I'm having:

package jetty.demo;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceCollection;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.EnumSet;
public class EmbeddedDocsWebApp
{
    public EmbeddedDocsWebApp() {
    }
 
    public static void main(String[] args)
    {
        System.setProperty("org.eclipse.jetty.LEVEL","DEBUG");
 
        Server server = new Server();
        ServerConnector connector = new ServerConnector(server);
        connector.setPort(8181);
        server.addConnector(connector);
 
        String contextPath = "/all-docs";
 
        jetty.demo.EmbeddedDocsWebApp webApp = new jetty.demo.EmbeddedDocsWebApp();
        ServletContextHandler context = webApp.createDocsWebApp(contextPath);
        server.setHandler(context);
 
        try
        {
            server.start();
            server.dump(System.err);
            server.join();
        }
        catch (Throwable t)
        {
            t.printStackTrace(System.err);
        }
    }
 
    private ServletContextHandler createDocsWebApp(final String contextPath) {
        try {
            final ResourceHandler resourceHandler = new ResourceHandler();
            resourceHandler.setDirectoriesListed(false);
 
            final File codeDocsDir = new File("/tmp/code-docs");
            final Resource codeDocsResource = Resource.newResource(codeDocsDir);
 
            // Load the component documentation working directory
            final File userGuideDocsDir = new File("/tmp/user-guide-docs");
            final Resource userGuideDocsResource = Resource.newResource(userGuideDocsDir);
 
            // Create resources for three docs locations - User Guides, Processor Docs, NiFi Web API
            final ResourceCollection resources = new ResourceCollection(codeDocsResource, userGuideDocsResource);
            resourceHandler.setBaseResource(resources);
 
            // Create the context handler
            final ServletContextHandler handler = new ServletContextHandler();
            FilterHolder frameOptions = new FilterHolder(FRAME_OPTIONS_FILTER);
            frameOptions.setName("X-Frame-Options");
 
            // <!-- This is the filter that does not get called when a request is made to localhost:8181/all-docs -->
            handler.addFilter(frameOptions, "/*", EnumSet.allOf(DispatcherType.class));
            handler.setContextPath(contextPath);
            handler.insertHandler(resourceHandler);
 
            System.out.println("Loading documents web app with context path set to " + contextPath);
            return handler;
        } catch (Exception ex) {
            System.out.println("Unhandled Exception in createDocsWebApp: " + ex.getMessage());
            return null;    // required by compiler, though never be executed.
        }
    }
 
    private static final Filter FRAME_OPTIONS_FILTER = new Filter() {
        private static final String FRAME_OPTIONS = "X-Frame-Options";
        private static final String SAME_ORIGIN = "SAMEORIGIN";
 
        @Override
        public void doFilter(final ServletRequest req, final ServletResponse resp, final FilterChain filterChain)
                throws IOException, ServletException {
 
            // set frame options accordingly
            final HttpServletResponse response = (HttpServletResponse) resp;
            response.setHeader(FRAME_OPTIONS, SAME_ORIGIN);
            filterChain.doFilter(req, resp);
        }
 
        @Override
        public void init(final FilterConfig config) {
        }
 
        @Override
        public void destroy() {
        }
    };
}

In this case, when hitting localhost:8181/all-docs, the ResourceHandler returns the static resources but does not apply the X-Frame-Options header using the FRAME_OPTIONS_FILTER. How do I get this target to hit the Filter before handling the static resource request?

Thanks in advance.


On Fri, Jun 8, 2018 at 9:09 AM, Nathan Gough <returntosender404@xxxxxxxxx> wrote:

This Jetty doco page https://www.eclipse.org/jetty/documentation/9.3.x/embedded-examples.html#embedded-split-file-server shows how to set up two context handlers which serve two different resource bases (eg. /var/www/docs and /var/www/api-docs) to the same path (eg. myurl.com/documentation).

A previous question showed how to do this with a ServletContextHandler: Serving static files from alternate path in embedded Jetty. You can add a Filter to a ServletContextHandler, but how do you add a Filter to a ContextHandlerCollection? For example an X-Frame-Options header? Is there a way to do split file/multiple resource bases for the same target and also add a header using an embedded method?

Thanks!




_______________________________________________
jetty-dev mailing list
jetty-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-dev



_______________________________________________
jetty-dev mailing list
jetty-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-dev


Back to the top