2014-11-17 3 views
1

Я пытаюсь реализовать клапан Tomcat (в настоящее время использующий 7.0.55), который должен перехватывать каждый запрос, который достигает Sercce Tomcat, независимо от Коннектора и еще чего-то, независимо от того, есть ли хост с соответствующим именем или контекстом сервлета или что-то еще.Почему мой котел tomcat не используется?

invoke -метод клапана выглядит следующим образом:

public class MyValve extends ValveBase { 
    public void invoke(Request request, Response response) throws IOException, 
      ServletException { 
     LOG.trace("Valve is being invoked"); 
     getNext().invoke(request, response); 
    } 
} 

О системе Дев, тестирование локально, работать все, как освобожденный. Запрос на любой путь URI на моем «localhost» tomcat пишет эту строку журнала. В sever.xml, клапан настроен вне любого Host элемента:

<Server port="8005" shutdown="SHUTDOWN"> 
    ... 
    <Service name="Catalina"> 
    ... 
    <Engine defaultHost="localhost" name="Catalina"> 
     ... 
     <Realm ... /> 
     <Valve className="a.b.c.MyValve" /> 
     ... 
     <Host ...> 
     </Host> 
    </Engine> 
    </Service> 
</Server> 

Теперь говорят в хостах моей системы файл, домен test.domain.com отображается на 127.0.0.1, и есть один контекст развертывается по имени some-webapp.

Как было сказано выше, строка журнала получает распечатку, когда я звоню http://localhost:8080/some-webapp/, который, как и ожидалось, также печатается, когда я звоню http://localhost:8080/non-existing-webapp/, что также ожидается.
То же самое касается домена (который не настроен в server.xml) test.domain.com, поэтому http://test.domain.com/some-webapp/ печатает строку журнала, а также http://test.domain.com/non-existing-webapp.

Но это не относится к серверу, на котором мы тестируем. Здесь Valve вызывается только в том случае, если имя контекста URI «известно» для tomcat, то есть вызов .../some-webapp/будет печатать строку журнала во время вызова .../not-existing-webapp/просто ничего не делал - клапан вообще не вызывался.
Тем не менее tomcat обрабатывает этот запрос, поскольку 404, который отправляется клиенту, в этом случае содержит «Apache-Coyote something» в качестве заголовка ответа.

У меня нет идей о том, как отлаживать это дальше, особенно процесс «отбора» Кокта или любого другого - любые мысли там?

Спасибо!

ответ

1

Оказывается, это связано с отсутствием каталога ROOT в webapps-каталоге Tomcat. Я думаю, что Tomcat очень быстро отфильтровывает входящие запросы в очень ранний момент времени, даже до того, как любые клапаны могут справиться с запросом.
И если нет контекста по умолчанию (т. Е. ROOT-dir), то Tomcat (думает) знает, что запрос non-existing-webapp не может быть успешным и, следовательно, даже не вызывает клапан (ы). В контексте по умолчанию Tomcat не может знать, что произойдет с запросом, и, таким образом, у клапана появится возможность перехватить запрос.

0

В версиях 6 (не уверен, что происходит в более ранних версиях) - 8 Tomcat не вызывает Valve, если он определяет, что перенаправление требуется, поэтому удивительно Valves работают надежно только тогда, когда контекст определяется во время фазы отображения.

Вы можете проверить исходный код (и присоединить отладчик, если вы хотите) из org.apache.catalina.connector.CoyoteAdapter класса, где действие происходит

// Parse and set Catalina and configuration specific 
    // request parameters 
    req.getRequestProcessor().setWorkerThreadName(THREAD_NAME.get()); 
    boolean postParseSuccess = postParseRequest(req, request, res, response); 
    if (postParseSuccess) { 
     //check valves if we support async 
     request.setAsyncSupported(connector.getService().getContainer().getPipeline().isAsyncSupported()); 
     // Calling the container 
     connector.getService().getContainer().getPipeline().getFirst().invoke(request, response); 

Как вы можете видеть клапаны называются только в случае, если postParseRequest вернулся так, что не делает например, если Tomcat определяет, что он должен возвращать перенаправление во время postParseRequest. код определения того, что перенаправление требуется:

// Possible redirect 
    MessageBytes redirectPathMB = request.getMappingData().redirectPath; 
    if (!redirectPathMB.isNull()) { 
     String redirectPath = URLEncoder.DEFAULT.encode(redirectPathMB.toString()); 
     String query = request.getQueryString(); 
     if (request.isRequestedSessionIdFromURL()) { 
      // This is not optimal, but as this is not very common, it 
      // shouldn't matter 
      redirectPath = redirectPath + ";" + 
        SessionConfig.getSessionUriParamName(
         request.getContext()) + 
       "=" + request.getRequestedSessionId(); 
     } 
     if (query != null) { 
      // This is not optimal, but as this is not very common, it 
      // shouldn't matter 
      redirectPath = redirectPath + "?" + query; 
     } 
     response.sendRedirect(redirectPath); 
     request.getContext().logAccess(request, response, 0, true); 
     return false; 
    } 

В моем случае редирект был установлен в org.apache.catalina.mapper.Mapper.internalMapWrapper(...)

это может стать помехой, если вы используете RemoteIpValve как это приводит к Tomcat для отправки переадресацию с помощью неправильно схемы.

Смежные вопросы