Получение 403 на корневых запросах при использовании ResourceHandler и пользовательского обработчика в Jetty

Во (встроенном) Jetty я пытаюсь использовать ResourceHandler для обслуживания статических файлов и пользовательский обработчик для ответа на динамические запросы. На основе этой страницы у меня есть установка, которая выглядит следующим образом:

public static void main(String[] args) throws Exception
{
    Server server = new Server();
    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(8080);
    server.addConnector(connector);

    ResourceHandler resource_handler = new ResourceHandler();
    resource_handler.setDirectoriesListed(false);

    resource_handler.setResourceBase(".");

    HandlerList handlers = new HandlerList();
    handlers.setHandlers(new Handler[] { resource_handler, new MyHandler() });
    server.setHandler(handlers);

    server.start();
    server.join();
}

Это работает в том смысле, что правильно:

  • Подает статический контент из файлов в моем общедоступном каталоге, например /public/style.css
  • Запускает MyHandler по путям, отсутствующим в общем каталоге, например /foo/bar

Проблема в том, что я получаю 403 в ответ на корневой путь (/). MyHandler способен отвечать на эти запросы, но сначала их перехватывает ResourceHandler. Есть ли способ заставить Jetty отправлять/запрашивать MyHandler?

Заранее спасибо!


person ajselvig    schedule 07.10.2012    source источник


Ответы (2)


Jetty пробует каждый обработчик последовательно, пока один из обработчиков не вызовет setHandled(true) по запросу. Не знаю, почему ResourceHandler не делает этого для "/".

Мое решение состояло в том, чтобы изменить порядок, в котором вы перечисляете обработчики, чтобы ваш вызывался первым. Затем проверьте наличие специального регистра «/» в URL-адресе. Если вы хотите передать запрос в ResourceHandler, просто вернитесь, не объявляя запрос как обработанный.

Объявить порядок обработчиков следующим образом:

Server server = new Server(8080);

CustomHandler default = new CustomHandler();
default.setServer(server);

ResourceHandler files = new ResourceHandler();
files.setServer(server);
files.setResourceBase("./path/to/resources");

HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] {default, files});

server.setHandler(handlers);

server.start();
server.join();

И определите метод дескриптора CustomHandler следующим образом:

public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
    if(!request.getRequestURI().equals("/")){
        return;
    }
    // Do Stuff...
    baseRequest.setHandled(true);
    return;
}

Я согласен, что было бы наиболее элегантно, если бы ResourceHandler просто возвращал "/" вместо обработки ответа с кодом 403.

person Jordan P    schedule 30.03.2013
comment
Большое спасибо :) Я работаю над многоразовым плагином для создания среды разработки для создания веб-приложений на основе войны с Gradle и в итоге реализовал обходной путь, аналогичный тому, который вы описываете здесь. github.com/augustl/gradle-warlike-plugin/blob/ - person August Lilleaas; 29.01.2015

Мое решение:

  • поместите MyHandler в другой путь контекста, чем "/", например. "/показатель"
  • используйте правило перезаписи для перехвата вызовов на "/" и перенаправления их на "/index"

Код, который я использую, выглядит так:

RewriteHandler rewriteHandler = new RewriteHandler();
rewriteHandler.setRewriteRequestURI(true);
rewriteHandler.setRewritePathInfo(false);
rewriteHandler.setOriginalPathAttribute("requestedPath");
RewriteRegexRule rewriteIndex = new RewriteRegexRule();
rewriteIndex.setRegex("^/$");
rewriteIndex.setReplacement("/index.html");
rewriteHandler.addRule(rewriteIndex);
rewriteHandler.setHandler(rootHandlerCollection);
server.setHandler(rewriteHandler);

Регулярное выражение гарантирует соответствие только точному пути, так что «/независимо» по-прежнему сначала обрабатывается ResourceHandler.

person claus    schedule 20.08.2014