Why is my tomcat valve not being invoked?

后端 未结 2 1365
旧巷少年郎
旧巷少年郎 2021-01-25 17:58

I try to implement a Tomcat valve (currently using 7.0.55) that should intercept every request that reaches the Tomcat serivce, regardless of Connector and whatnot, regardless o

2条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-25 18:06

    In versions 6(not sure what happens in earlier versions) - 8 Tomcat does not call Valve if it determines that redirect is required, so suprisingly Valves work reliably only when context is determined during mapping phase.

    You can check the source code(and attach a debugger if you wish) of org.apache.catalina.connector.CoyoteAdapter class where the action happens

        // 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);
    

    As you can see Valves are called only in case postParseRequest returned true, which does not happen for example if Tomcat determines that it should return redirect during postParseRequest. Code determining that redirect is required:

        // 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;
        }
    

    In my case redirect was set in org.apache.catalina.mapper.Mapper.internalMapWrapper(...)

    This may become a nuisance if you use RemoteIpValve as it causes Tomcat to send redirects using the wrong schema.

提交回复
热议问题