Search in sources :

Example 1 with AtmosphereHandlerWrapper

use of org.atmosphere.cpr.AtmosphereFramework.AtmosphereHandlerWrapper in project atmosphere by Atmosphere.

the class AsynchronousProcessor method action.

/**
 * Invoke the {@link AtmosphereHandler#onRequest} method.
 *
 * @param req the {@link AtmosphereRequest}
 * @param res the {@link AtmosphereResponse}
 * @return action the Action operation.
 */
Action action(AtmosphereRequest req, AtmosphereResponse res) throws IOException, ServletException {
    if (!Utils.properProtocol(req)) {
        logger.debug("Invalid request state.");
        res.setStatus(501);
        res.addHeader(X_ATMOSPHERE_ERROR, "Websocket protocol not supported");
        res.flushBuffer();
        return new Action();
    }
    if (Utils.webSocketEnabled(req) && !supportWebSocket()) {
        logger.warn("Websocket protocol not supported");
        res.setStatus(501);
        res.addHeader(X_ATMOSPHERE_ERROR, "Websocket protocol not supported");
        res.flushBuffer();
        return new Action();
    }
    if (config.handlers().isEmpty()) {
        logger.error("No AtmosphereHandler found. Make sure you define it inside WEB-INF/atmosphere.xml or annotate using @___Service");
        throw new AtmosphereMappingException("No AtmosphereHandler found. Make sure you define it inside WEB-INF/atmosphere.xml or annotate using @___Service");
    }
    if (res.request() == null) {
        res.request(req);
    }
    if (supportSession()) {
        // Create the session needed to support the Resume
        // operation from disparate requests.
        HttpSession s = req.getSession(config.getInitParameter(PROPERTY_SESSION_CREATE, true));
        // https://github.com/Atmosphere/atmosphere/issues/2034
        try {
            if (s != null && s.isNew()) {
                s.setAttribute(getClass().getName(), "");
                s.removeAttribute(getClass().getName());
            }
        } catch (IllegalStateException ex) {
            AtmosphereResourceImpl r = (AtmosphereResourceImpl) req.resource();
            logger.warn("Session Expired for {}. Closing the connection", req.uuid(), ex);
            if (r != null) {
                logger.trace("Ending request for {}", r.uuid());
                endRequest(r, true);
                return Action.CANCELLED;
            } else {
                logger.trace("Sending error for {}", req.uuid());
                res.setStatus(500);
                res.addHeader(X_ATMOSPHERE_ERROR, "Session expired");
                res.flushBuffer();
                return new Action();
            }
        }
    }
    req.setAttribute(FrameworkConfig.SUPPORT_SESSION, supportSession());
    int tracing = 0;
    AtmosphereHandlerWrapper handlerWrapper = map(req);
    if (config.getBroadcasterFactory() == null) {
        logger.error("Atmosphere is misconfigured and will not work. BroadcasterFactory is null");
        return Action.CANCELLED;
    }
    AtmosphereResourceImpl resource = configureWorkflow(null, handlerWrapper, req, res);
    String v = req.getHeader(HeaderConfig.X_ATMO_BINARY);
    if (v != null) {
        resource.forceBinaryWrite(Boolean.parseBoolean(v));
    }
    if (resource.transport() == AtmosphereResource.TRANSPORT.WEBSOCKET && !Utils.webSocketEnabled(req) && !Utils.isRunningTest()) {
        logger.warn("Transport not matching webSocketEnabled. Ending request for {}", resource.uuid());
        return Action.CANCELLED;
    }
    // handler interceptor lists
    LinkedList<AtmosphereInterceptor> invokedInterceptors = handlerWrapper.interceptors;
    Action a = invokeInterceptors(invokedInterceptors, resource, tracing);
    if (a.type() != Action.TYPE.CONTINUE && a.type() != Action.TYPE.SKIP_ATMOSPHEREHANDLER) {
        return a;
    }
    try {
        // Remap occured.
        if (req.getAttribute(FrameworkConfig.NEW_MAPPING) != null) {
            req.removeAttribute(FrameworkConfig.NEW_MAPPING);
            handlerWrapper = map(req);
            if (handlerWrapper == null) {
                logger.debug("Remap {}", resource.uuid());
                throw new AtmosphereMappingException("Invalid state. No AtmosphereHandler maps request for " + req.getRequestURI());
            }
            resource = configureWorkflow(resource, handlerWrapper, req, res);
            resource.setBroadcaster(handlerWrapper.broadcaster);
        }
        // Unit test mock the request and will throw NPE.
        boolean skipAtmosphereHandler = req.getAttribute(SKIP_ATMOSPHEREHANDLER.name()) != null ? (Boolean) req.getAttribute(SKIP_ATMOSPHEREHANDLER.name()) : Boolean.FALSE;
        if (!skipAtmosphereHandler) {
            try {
                logger.trace("\t Last: {}", handlerWrapper.atmosphereHandler.getClass().getName());
                handlerWrapper.atmosphereHandler.onRequest(resource);
            } catch (IOException t) {
                resource.onThrowable(t);
                throw t;
            }
        }
    } finally {
        postInterceptors(handlerWrapper != null ? handlerWrapper.interceptors : invokedInterceptors, resource);
    }
    Action action = resource.action();
    if (supportSession() && allowSessionTimeoutRemoval() && action.type().equals(Action.TYPE.SUSPEND)) {
        // Do not allow times out.
        SessionTimeoutSupport.setupTimeout(config, req.getSession(config.getInitParameter(ApplicationConfig.PROPERTY_SESSION_CREATE, true)));
    }
    logger.trace("Action for {} was {} with transport " + req.getHeader(X_ATMOSPHERE_TRANSPORT), req.resource() != null ? req.resource().uuid() : "null", action);
    return action;
}
Also used : HttpSession(jakarta.servlet.http.HttpSession) AtmosphereHandlerWrapper(org.atmosphere.cpr.AtmosphereFramework.AtmosphereHandlerWrapper) IOException(java.io.IOException)

Aggregations

HttpSession (jakarta.servlet.http.HttpSession)1 IOException (java.io.IOException)1 AtmosphereHandlerWrapper (org.atmosphere.cpr.AtmosphereFramework.AtmosphereHandlerWrapper)1