Search in sources :

Example 1 with IXServletLowLevelFilter

use of com.helger.xservlet.filter.IXServletLowLevelFilter in project ph-web by phax.

the class AbstractXServlet method service.

/**
 * Dispatches client requests to the protected <code>service</code> method.
 * There's no need to override this method.
 *
 * @param aHttpRequest
 *        the {@link HttpServletRequest} object that contains the request the
 *        client made of the servlet
 * @param aHttpResponse
 *        the {@link HttpServletResponse} object that contains the response
 *        the servlet returns to the client
 * @exception IOException
 *            if an input or output error occurs while the servlet is handling
 *            the HTTP request
 * @exception ServletException
 *            if the HTTP request cannot be handled
 * @see javax.servlet.Servlet#service
 */
@Override
protected final void service(@Nonnull final HttpServletRequest aHttpRequest, @Nonnull final HttpServletResponse aHttpResponse) throws ServletException, IOException {
    // Increase counter
    m_aCounterRequestsTotal.increment();
    // Increase per servlet invocation
    m_aStatusMgr.onServletInvocation(getClass());
    // Ensure a valid HTTP version is provided
    final String sProtocol = aHttpRequest.getProtocol();
    final EHttpVersion eHttpVersion = EHttpVersion.getFromNameOrNull(sProtocol);
    if (eHttpVersion == null) {
        // HTTP version disallowed
        logInvalidRequestSetup("Request has unsupported HTTP version (" + sProtocol + ")!", aHttpRequest);
        aHttpResponse.sendError(CHttp.HTTP_VERSION_NOT_SUPPORTED);
        return;
    }
    m_aCounterRequestsPerVersionAccepted.increment(eHttpVersion.getName());
    // Ensure a valid HTTP method is provided
    final String sMethod = aHttpRequest.getMethod();
    final EHttpMethod eHttpMethod = EHttpMethod.getFromNameOrNull(sMethod);
    if (eHttpMethod == null) {
        // HTTP method unknown
        logInvalidRequestSetup("Request has unsupported HTTP method (" + sMethod + ")!", aHttpRequest);
        aHttpResponse.sendError(CHttp.HTTP_NOT_IMPLEMENTED);
        return;
    }
    m_aCounterRequestsPerMethodAccepted.increment(eHttpMethod.getName());
    // May already be set in test cases!
    if (FIRST_REQUEST.getAndSet(false) && !StaticServerInfo.isSet()) {
        // First set the default web server info
        StaticServerInfo.init(aHttpRequest.getScheme(), aHttpRequest.getServerName(), aHttpRequest.getServerPort(), ServletContextPathHolder.getContextPath());
    }
    // Create a wrapper around the Servlet Response that saves the status code
    final StatusAwareHttpResponseWrapper aHttpResponseWrapper = StatusAwareHttpResponseWrapper.wrap(aHttpResponse);
    // Create effective filter list with all internal filters as well
    final ICommonsList<IXServletLowLevelFilter> aEffectiveFilterList = new CommonsArrayList<>(4 + m_aFilterLowLevelList.size());
    // Add internal filters - always first
    aEffectiveFilterList.add(XServletFilterSecurityPoxy.INSTANCE);
    aEffectiveFilterList.add(XServletFilterConsistency.INSTANCE);
    if (m_aSettings.hasHttpReferrerPolicy())
        aEffectiveFilterList.add(new XServletFilterSecurityHttpReferrerPolicy(m_aSettings.getHttpReferrerPolicy()));
    if (m_aSettings.hasXFrameOptions())
        aEffectiveFilterList.add(new XServletFilterSecurityXFrameOptions(m_aSettings.getXFrameOptionsType(), m_aSettings.getXFrameOptionsDomain()));
    // Add custom filters
    aEffectiveFilterList.addAll(m_aFilterLowLevelList);
    // Filter before request scope is created!
    boolean bInvokeHandler = true;
    for (final IXServletLowLevelFilter aFilter : aEffectiveFilterList) if (aFilter.beforeRequest(aHttpRequest, aHttpResponseWrapper, eHttpVersion, eHttpMethod).isBreak()) {
        bInvokeHandler = false;
        return;
    }
    boolean bIsHandledAsync = false;
    Exception aCaughtException = null;
    try {
        if (bInvokeHandler) {
            // Create request scope
            final BiFunction<? super HttpServletRequest, ? super HttpServletResponse, IRequestWebScope> aFactory;
            aFactory = m_aSettings.isMultipartEnabled() ? RequestWebScopeMultipart::new : RequestWebScope::new;
            try (final RequestScopeInitializer aRequestScopeInitializer = RequestScopeInitializer.create(aHttpRequest, aHttpResponseWrapper, aFactory)) {
                final IRequestWebScope aRequestScope = aRequestScopeInitializer.getRequestScope();
                aRequestScope.attrs().putIn(REQUEST_ATTR_SCOPE_CREATED, aRequestScopeInitializer.isNew());
                // Find and invoke handler
                _invokeHandler(aHttpRequest, aHttpResponseWrapper, eHttpVersion, eHttpMethod, aRequestScope);
                bIsHandledAsync = aRequestScope.attrs().getAsBoolean(AbstractXServlet.REQUEST_ATTR_HANDLED_ASYNC, false);
                if (bIsHandledAsync) {
                    // The request scope is needed in the async handler!
                    aRequestScopeInitializer.internalSetDontDestroyRequestScope();
                }
            }
        }
    } catch (final Exception ex) {
        // Remember
        aCaughtException = ex;
        // This log entry is mainly present to have an overview on how often
        // this really happens
        log("Servlet exception propagated to the outside", ex);
        // Ensure only exceptions with the correct type are propagated
        if (ex instanceof IOException)
            throw (IOException) ex;
        if (ex instanceof ServletException)
            throw (ServletException) ex;
        throw new ServletException("Wrapped " + ex.getClass().getName(), ex);
    } finally {
        // Filter after
        for (final IXServletLowLevelFilter aFilter : aEffectiveFilterList) try {
            aFilter.afterRequest(aHttpRequest, aHttpResponseWrapper, eHttpVersion, eHttpMethod, bInvokeHandler, aCaughtException, bIsHandledAsync);
        } catch (final ServletException | IOException ex) {
            LOGGER.error("Exception in low-level filter afterRequest of " + aFilter + " - re-thrown", ex);
        // Don't re-throw in finally
        // throw ex;
        }
    }
}
Also used : XServletFilterSecurityXFrameOptions(com.helger.xservlet.filter.XServletFilterSecurityXFrameOptions) XServletFilterSecurityHttpReferrerPolicy(com.helger.xservlet.filter.XServletFilterSecurityHttpReferrerPolicy) EHttpVersion(com.helger.http.EHttpVersion) IXServletLowLevelFilter(com.helger.xservlet.filter.IXServletLowLevelFilter) IOException(java.io.IOException) ServletException(javax.servlet.ServletException) ForcedRedirectException(com.helger.xservlet.forcedredirect.ForcedRedirectException) IOException(java.io.IOException) ServletException(javax.servlet.ServletException) EHttpMethod(com.helger.commons.http.EHttpMethod) RequestScopeInitializer(com.helger.web.scope.request.RequestScopeInitializer) StatusAwareHttpResponseWrapper(com.helger.servlet.response.StatusAwareHttpResponseWrapper) CommonsArrayList(com.helger.commons.collection.impl.CommonsArrayList) IRequestWebScope(com.helger.web.scope.IRequestWebScope)

Aggregations

CommonsArrayList (com.helger.commons.collection.impl.CommonsArrayList)1 EHttpMethod (com.helger.commons.http.EHttpMethod)1 EHttpVersion (com.helger.http.EHttpVersion)1 StatusAwareHttpResponseWrapper (com.helger.servlet.response.StatusAwareHttpResponseWrapper)1 IRequestWebScope (com.helger.web.scope.IRequestWebScope)1 RequestScopeInitializer (com.helger.web.scope.request.RequestScopeInitializer)1 IXServletLowLevelFilter (com.helger.xservlet.filter.IXServletLowLevelFilter)1 XServletFilterSecurityHttpReferrerPolicy (com.helger.xservlet.filter.XServletFilterSecurityHttpReferrerPolicy)1 XServletFilterSecurityXFrameOptions (com.helger.xservlet.filter.XServletFilterSecurityXFrameOptions)1 ForcedRedirectException (com.helger.xservlet.forcedredirect.ForcedRedirectException)1 IOException (java.io.IOException)1 ServletException (javax.servlet.ServletException)1