All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.atmosphere.cpr.AtmosphereServlet Maven / Gradle / Ivy

There is a newer version: 3.0.13
Show newest version
/*
 * Copyright 2013 Jeanfrancois Arcand
 *
 * 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.
 */
/*
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2007-2008 Sun Microsystems, Inc. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 *
 * Contributor(s):
 *
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 *
 */
package org.atmosphere.cpr;


import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;
import org.atmosphere.container.JBossWebCometSupport;
import org.atmosphere.container.Tomcat7CometSupport;
import org.atmosphere.container.TomcatCometSupport;
import org.atmosphere.di.ServletContextProvider;
import org.jboss.servlet.http.HttpEvent;
import org.jboss.servlet.http.HttpEventServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

import static org.atmosphere.cpr.HeaderConfig.WEBSOCKET_UPGRADE;

/**
 * The {@link AtmosphereServlet} acts as a dispatcher for {@link AtmosphereHandler}
 * defined in META-INF/atmosphere.xml, or if atmosphere.xml is missing, all classes
 * that implements {@link AtmosphereHandler} will be discovered and mapped using
 * the class's name.
 * 

* This {@link Servlet} can be defined inside an application's web.xml using the following: *

 *  <servlet>
 *      <description>AtmosphereServlet</description>
 *      <servlet-name>AtmosphereServlet</servlet-name>
 *      <servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
 *      <load-on-startup>0 </load-on-startup>
 *  </servlet>
 *  <servlet-mapping>
 *      <servlet-name>AtmosphereServlet</servlet-name>
 *      <url-pattern>/Atmosphere </url-pattern>
 *  </servlet-mapping>
 * 
* You can force this Servlet to use native API of the Web Server instead of * the Servlet 3.0 Async API you are deploying on by adding *
 *  <init-param>
 *      <param-name>org.atmosphere.useNative</param-name>
 *      <param-value>true</param-value>
 *  </init-param>
 * 
* You can force this Servlet to use one Thread per connection instead of * native API of the Web Server you are deploying on by adding *
 *  <init-param>
 *      <param-name>org.atmosphere.useBlocking</param-name>
 *      <param-value>true</param-value>
 *  </init-param>
 * 
* You can also define {@link Broadcaster}by adding: *
 *  <init-param>
 *      <param-name>org.atmosphere.cpr.broadcasterClass</param-name>
 *      <param-value>class-name</param-value>
 *  </init-param>
 * 
* You can also for Atmosphere to use {@link java.io.OutputStream} for all write operations. *
 *  <init-param>
 *      <param-name>org.atmosphere.useStream</param-name>
 *      <param-value>true</param-value>
 *  </init-param>
 * 
* You can also configure {@link org.atmosphere.cpr.BroadcasterCache} that persist message when Browser is disconnected. *
 *  <init-param>
 *      <param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>
 *      <param-value>class-name</param-value>
 *  </init-param>
 * 
* You can also configure Atmosphere to use http session or not *
 *  <init-param>
 *      <param-name>org.atmosphere.cpr.sessionSupport</param-name>
 *      <param-value>false</param-value>
 *  </init-param>
 * 
* You can also configure {@link BroadcastFilter} that will be applied at all newly created {@link Broadcaster} *
 *  <init-param>
 *      <param-name>org.atmosphere.cpr.broadcastFilterClasses</param-name>
 *      <param-value>BroadcastFilter class name separated by coma</param-value>
 *  </init-param>
 * 
* All the property available are defined in {@link ApplicationConfig} * The Atmosphere Framework can also be used as a Servlet Filter ({@link AtmosphereFilter}). *

* If you are planning to use JSP, Servlet or JSF, you can instead use the * {@link MeteorServlet}, which allow the use of {@link Meteor} inside those * components. * * @author Jeanfrancois Arcand */ public class AtmosphereServlet extends HttpServlet implements CometProcessor, HttpEventServlet, ServletContextProvider, org.apache.catalina.comet.CometProcessor { protected static final Logger logger = LoggerFactory.getLogger(AtmosphereServlet.class); protected AtmosphereFramework framework; /** * Create an Atmosphere Servlet. */ public AtmosphereServlet() { this(false); } /** * Create an Atmosphere Servlet. * * @param isFilter true if this instance is used as an {@link AtmosphereFilter} */ public AtmosphereServlet(boolean isFilter) { this(isFilter, true); } /** * Create an Atmosphere Servlet. * * @param isFilter true if this instance is used as an {@link AtmosphereFilter} */ public AtmosphereServlet(boolean isFilter, boolean autoDetectHandlers) { framework = new AtmosphereFramework(isFilter, autoDetectHandlers); } @Override public void destroy() { framework.destroy(); } public void init(final ServletConfig sc) throws ServletException { super.init(sc); framework.init(sc); } public AtmosphereFramework framework() { return framework; } /** * Delegate the request processing to an instance of {@link AsyncSupport} * * @param req the {@link HttpServletRequest} * @param res the {@link HttpServletResponse} * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doHead(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { doPost(req, res); } /** * Delegate the request processing to an instance of {@link AsyncSupport} * * @param req the {@link HttpServletRequest} * @param res the {@link HttpServletResponse} * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doOptions(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { doPost(req, res); } /** * Delegate the request processing to an instance of {@link AsyncSupport} * * @param req the {@link HttpServletRequest} * @param res the {@link HttpServletResponse} * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doTrace(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { doPost(req, res); } /** * Delegate the request processing to an instance of {@link AsyncSupport} * * @param req the {@link HttpServletRequest} * @param res the {@link HttpServletResponse} * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doDelete(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { doPost(req, res); } /** * Delegate the request processing to an instance of {@link AsyncSupport} * * @param req the {@link HttpServletRequest} * @param res the {@link HttpServletResponse} * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doPut(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { doPost(req, res); } /** * Delegate the request processing to an instance of {@link AsyncSupport} * * @param req the {@link HttpServletRequest} * @param res the {@link HttpServletResponse} * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { doPost(req, res); } /** * Delegate the request processing to an instance of {@link AsyncSupport} * * @param req the {@link HttpServletRequest} * @param res the {@link HttpServletResponse} * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { framework.doCometSupport(AtmosphereRequest.wrap(req), AtmosphereResponse.wrap(res)); } /** * Hack to support Tomcat AIO like other WebServer. This method is invoked * by Tomcat when it detect a {@link Servlet} implements the interface * {@link CometProcessor} without invoking {@link Servlet#service} * * @param cometEvent the {@link CometEvent} * @throws java.io.IOException * @throws javax.servlet.ServletException */ public void event(CometEvent cometEvent) throws IOException, ServletException { HttpServletRequest req = cometEvent.getHttpServletRequest(); HttpServletResponse res = cometEvent.getHttpServletResponse(); req.setAttribute(TomcatCometSupport.COMET_EVENT, cometEvent); if (!framework.getAsyncSupport().supportWebSocket()) { if (!framework.isCometSupportSpecified && !framework.isCometSupportConfigured.getAndSet(true)) { synchronized (framework.asyncSupport) { if (!framework.asyncSupport.getClass().equals(TomcatCometSupport.class)) { AsyncSupport current = framework.asyncSupport; logger.warn("TomcatCometSupport is enabled, switching to it"); framework.asyncSupport = new TomcatCometSupport(framework.config); if(current instanceof AsynchronousProcessor) { ((AsynchronousProcessor)current).shutdown(); } framework.asyncSupport.init(framework.config.getServletConfig()); } } } } framework.doCometSupport(AtmosphereRequest.wrap(req), AtmosphereResponse.wrap(res)); String transport = cometEvent.getHttpServletRequest().getParameter(HeaderConfig.X_ATMOSPHERE_TRANSPORT); if (transport != null && transport.equalsIgnoreCase(HeaderConfig.WEBSOCKET_TRANSPORT)) { cometEvent.close(); } } /** * Hack to support Tomcat 7 AIO */ public void event(org.apache.catalina.comet.CometEvent cometEvent) throws IOException, ServletException { HttpServletRequest req = cometEvent.getHttpServletRequest(); HttpServletResponse res = cometEvent.getHttpServletResponse(); req.setAttribute(Tomcat7CometSupport.COMET_EVENT, cometEvent); if (!framework.getAsyncSupport().supportWebSocket()) { if (!framework.isCometSupportSpecified && !framework.isCometSupportConfigured.getAndSet(true)) { synchronized (framework.asyncSupport) { if (!framework.asyncSupport.getClass().equals(Tomcat7CometSupport.class)) { AsyncSupport current = framework.asyncSupport; logger.warn("TomcatCometSupport7 is enabled, switching to it"); framework.asyncSupport = new Tomcat7CometSupport(framework.config); if(current instanceof AsynchronousProcessor) { ((AsynchronousProcessor)current).shutdown(); } framework.asyncSupport.init(framework.config.getServletConfig()); } } } } framework.doCometSupport(AtmosphereRequest.wrap(req), AtmosphereResponse.wrap(res)); // https://github.com/Atmosphere/atmosphere/issues/920 String transport = cometEvent.getHttpServletRequest().getParameter(HeaderConfig.X_ATMOSPHERE_TRANSPORT); boolean webSocketSupported = (transport != null && transport.equalsIgnoreCase(HeaderConfig.WEBSOCKET_TRANSPORT)); if (!webSocketSupported) { try { Enumeration connection = req.getHeaders("Connection"); if (connection != null && connection.hasMoreElements()) { String[] e = connection.nextElement().toString().split(","); for (String upgrade : e) { if (upgrade.trim().equalsIgnoreCase(WEBSOCKET_UPGRADE)) { webSocketSupported = true; break; } } } } catch (Exception ex) { logger.trace("", ex); } } if (webSocketSupported){ cometEvent.close(); } } /** * Hack to support JBossWeb AIO like other WebServer. This method is invoked * by Tomcat when it detect a {@link Servlet} implements the interface * {@link HttpEventServlet} without invoking {@link Servlet#service} * * @param httpEvent the {@link CometEvent} * @throws java.io.IOException * @throws javax.servlet.ServletException */ public void event(HttpEvent httpEvent) throws IOException, ServletException { HttpServletRequest req = httpEvent.getHttpServletRequest(); HttpServletResponse res = httpEvent.getHttpServletResponse(); req.setAttribute(JBossWebCometSupport.HTTP_EVENT, httpEvent); if (!framework.isCometSupportSpecified && !framework.isCometSupportConfigured.getAndSet(true)) { synchronized (framework.asyncSupport) { if (!framework.asyncSupport.getClass().equals(JBossWebCometSupport.class)) { AsyncSupport current = framework.asyncSupport; logger.warn("JBossWebCometSupport is enabled, switching to it"); framework.asyncSupport = new JBossWebCometSupport(framework.config); if(current instanceof AsynchronousProcessor) { ((AsynchronousProcessor)current).shutdown(); } framework.asyncSupport.init(framework.config.getServletConfig()); } } } framework.doCometSupport(AtmosphereRequest.wrap(req), AtmosphereResponse.wrap(res)); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy