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