Package io.undertow.servlet.handlers

Source Code of io.undertow.servlet.handlers.ServletInitialHandler

/*
* JBoss, Home of Professional Open Source.
* Copyright 2012 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.undertow.servlet.handlers;

import javax.servlet.DispatcherType;
import javax.servlet.ServletException;

import io.undertow.UndertowLogger;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.handlers.form.FormDataParser;
import io.undertow.servlet.api.ServletDispatcher;
import io.undertow.servlet.api.ThreadSetupAction;
import io.undertow.servlet.core.ApplicationListeners;
import io.undertow.servlet.core.CompositeThreadSetupAction;
import io.undertow.servlet.core.ServletBlockingHttpExchange;
import io.undertow.servlet.spec.HttpServletRequestImpl;
import io.undertow.servlet.spec.HttpServletResponseImpl;
import io.undertow.servlet.spec.RequestDispatcherImpl;
import io.undertow.servlet.spec.ServletContextImpl;
import org.xnio.IoUtils;

/**
* This must be the initial handler in the blocking servlet chain. This sets up the request and response objects,
* and attaches them the to exchange.
*
* @author Stuart Douglas
*/
public class ServletInitialHandler implements HttpHandler, ServletDispatcher {

    private final HttpHandler next;
    //private final HttpHandler asyncPath;

    private final CompositeThreadSetupAction setupAction;

    private final ServletContextImpl servletContext;

    private final ApplicationListeners listeners;

    private final ServletPathMatches paths;

    public ServletInitialHandler(final ServletPathMatches paths, final HttpHandler next, final CompositeThreadSetupAction setupAction, final ServletContextImpl servletContext) {
        this.next = next;
        this.setupAction = setupAction;
        this.servletContext = servletContext;
        this.paths = paths;
        this.listeners = servletContext.getDeployment().getApplicationListeners();
    }

    @Override
    public void handleRequest(final HttpServerExchange exchange) throws Exception {
        if (exchange.isInIoThread()) {
            exchange.dispatch(this);
            return;
        }
        final String path = exchange.getRelativePath();
        final ServletPathMatch info = paths.getServletHandlerByPath(path);
        final HttpServletResponseImpl response = new HttpServletResponseImpl(exchange, servletContext);
        final HttpServletRequestImpl request = new HttpServletRequestImpl(exchange, servletContext);
        exchange.putAttachment(HttpServletRequestImpl.ATTACHMENT_KEY, request);
        exchange.putAttachment(HttpServletResponseImpl.ATTACHMENT_KEY, response);

        try {
            exchange.startBlocking(new ServletBlockingHttpExchange(exchange));
            exchange.putAttachment(ServletAttachments.SERVLET_PATH_MATCH, info);
            dispatchRequest(exchange, info, request, response, DispatcherType.REQUEST);
        } catch (Throwable t) {
            UndertowLogger.REQUEST_LOGGER.errorf(t, "Internal error handling servlet request %s", exchange.getRequestURI());
            exchange.endExchange();
        }
    }

    public void dispatchToPath(final HttpServerExchange exchange, final ServletPathMatch pathInfo, final DispatcherType dispatcherType) throws Exception {
        HttpServletRequestImpl req = HttpServletRequestImpl.getRequestImpl(exchange.getAttachment(HttpServletRequestImpl.ATTACHMENT_KEY));
        HttpServletResponseImpl resp = HttpServletResponseImpl.getResponseImpl(exchange.getAttachment(HttpServletResponseImpl.ATTACHMENT_KEY));
        exchange.putAttachment(ServletAttachments.SERVLET_PATH_MATCH, pathInfo);
        dispatchRequest(exchange, pathInfo, req, resp, dispatcherType);
    }

    @Override
    public void dispatchToServlet(final HttpServerExchange exchange, final ServletChain servletchain, final DispatcherType dispatcherType) throws Exception {
        HttpServletRequestImpl req = HttpServletRequestImpl.getRequestImpl(exchange.getAttachment(HttpServletRequestImpl.ATTACHMENT_KEY));
        HttpServletResponseImpl resp = HttpServletResponseImpl.getResponseImpl(exchange.getAttachment(HttpServletResponseImpl.ATTACHMENT_KEY));
        dispatchRequest(exchange, servletchain, req, resp, dispatcherType);
    }

    public void dispatchRequest(final HttpServerExchange exchange, final ServletChain servletChain, final HttpServletRequestImpl request, final HttpServletResponseImpl response, final DispatcherType dispatcherType) throws Exception {
        exchange.putAttachment(HttpServletRequestImpl.DISPATCHER_TYPE_ATTACHMENT_KEY, dispatcherType);
        exchange.putAttachment(ServletAttachments.CURRENT_SERVLET, servletChain);
        if (dispatcherType == DispatcherType.REQUEST || dispatcherType == DispatcherType.ASYNC) {
            handleFirstRequest(exchange, servletChain, request, response);
        } else {
            next.handleRequest(exchange);
        }
    }

    public void handleFirstRequest(final HttpServerExchange exchange, final ServletChain servletChain, final HttpServletRequestImpl request, final HttpServletResponseImpl response) throws Exception {

        ThreadSetupAction.Handle handle = setupAction.setup(exchange);
        try {

            listeners.requestInitialized(request);
            next.handleRequest(exchange);

            if (!exchange.isResponseStarted() && exchange.getResponseCode() >= 400 && !exchange.isDispatched()) {
                String location = servletContext.getDeployment().getErrorPages().getErrorLocation(exchange.getResponseCode());
                if (location != null) {
                    RequestDispatcherImpl dispatcher = new RequestDispatcherImpl(location, servletContext);
                    dispatcher.error(request, response, servletChain.getManagedServlet().getServletInfo().getName());
                }
            }
            //
        } catch (Throwable t) {
            if(request.isAsyncStarted() || request.getDispatcherType() == DispatcherType.ASYNC) {
                exchange.unDispatch();
                request.getAsyncContextInternal().handleError(t);
            } else {
                if (!exchange.isResponseStarted()) {
                    exchange.setResponseCode(500);
                    exchange.getResponseHeaders().clear();
                    String location = servletContext.getDeployment().getErrorPages().getErrorLocation(t);
                    if (location == null && t instanceof ServletException) {
                        location = servletContext.getDeployment().getErrorPages().getErrorLocation(t.getCause());
                    }
                    if (location != null) {
                        RequestDispatcherImpl dispatcher = new RequestDispatcherImpl(location, servletContext);
                        try {
                            dispatcher.error(request, response, servletChain.getManagedServlet().getServletInfo().getName(), t);
                        } catch (Exception e) {
                            UndertowLogger.REQUEST_LOGGER.errorf(e, "Exception while generating error page %s", location);
                        }
                    } else {
                        UndertowLogger.REQUEST_LOGGER.errorf(t, "Servlet request failed %s", exchange);
                    }
                }
            }
        } finally {
            handle.tearDown();
        }

        request.getServletContext().getDeployment().getApplicationListeners().requestDestroyed(request);
        if (!exchange.isDispatched()) {
            response.responseDone();
            //this request is done, so we close any parser that may have been used
            final FormDataParser parser = exchange.getAttachment(FormDataParser.ATTACHMENT_KEY);
            IoUtils.safeClose(parser);
        }
    }

    public HttpHandler getNext() {
        return next;
    }

}
TOP

Related Classes of io.undertow.servlet.handlers.ServletInitialHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.