/* * Copyright 2005 Joe Walker * * 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 org.directwebremoting.servlet; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.directwebremoting.WebContextFactory; import org.directwebremoting.extend.DwrConstants; import org.directwebremoting.extend.Remoter; import org.directwebremoting.extend.ScriptSessionManager; import org.directwebremoting.extend.ServerLoadMonitor; import org.directwebremoting.util.VersionUtil; /** * A Handler that supports requests for engine.js * @author Joe Walker [joe at getahead dot ltd dot uk] */ public class EngineHandler extends FileJavaScriptHandler { /** * Setup the default values */ public EngineHandler() { super(DwrConstants.PACKAGE + "/engine.js"); } /* (non-Javadoc) * @see org.directwebremoting.servlet.FileHandler#getSearchReplacePairs() */ @Override public Map<String, String> getSearchReplacePairs() { HttpServletRequest request = WebContextFactory.get().getHttpServletRequest(); Map<String, String> replace = new HashMap<String, String>(); // If we are dynamic then we might need to pre-configure some variables. boolean streaming = true; // If the maxWaitAfterWrite time is less than half a second then we // count ourselves to be not streaming, and use the simple XHR // connection method. if (maxWaitAfterWrite > -1 && maxWaitAfterWrite < 500) { streaming = false; } // If the ServerLoadMonitor says no streaming, then obviously ... if (!serverLoadMonitor.supportsStreaming()) { streaming = false; } // Poll using XHR (to avoid IE clicking) if we close // the connection than 1sec after output happens. String pollWithXhr = streaming ? "false" : "true"; replace.put("${pollWithXhr}", pollWithXhr); // What is the replacement field we use to tell engine.js what we are using // for script tag hack protection String contextServletPath = request.getContextPath() + request.getServletPath(); String pathToDwrServlet = remoter.getPathToDwrServlet(contextServletPath); replace.put("${pathToDwrServlet}", pathToDwrServlet); // Under what cookie name is the session id stored? replace.put("${sessionCookieName}", sessionCookieName); // Does engine.js do GETs for Safari replace.put("${allowGetForSafariButMakeForgeryEasier}", String.valueOf(allowGetForSafariButMakeForgeryEasier)); // What is the replacement field we use to tell engine.js what we are // using for script tag hack protection replace.put("${scriptTagProtection}", scriptTagProtection); // engine.js needs to know the URLs to send requests to: replace.put("${plainCallHandlerUrl}", plainCallHandlerUrl); replace.put("${plainPollHandlerUrl}", plainPollHandlerUrl); replace.put("${htmlCallHandlerUrl}", htmlCallHandlerUrl); replace.put("${htmlPollHandlerUrl}", htmlPollHandlerUrl); // Do we start off with everything in Sjax mode? replace.put("${defaultToAsync}", String.valueOf(defaultToAsync)); // Version numbers so clients can sort out what they're up against replace.put("${versionMajor}", String.valueOf(VersionUtil.getMajor())); replace.put("${versionMinor}", String.valueOf(VersionUtil.getMinor())); replace.put("${versionRevision}", String.valueOf(VersionUtil.getRevision())); replace.put("${versionBuild}", String.valueOf(VersionUtil.getBuild())); replace.put("${versionTitle}", String.valueOf(VersionUtil.getTitle())); replace.put("${versionLabel}", String.valueOf(VersionUtil.getLabel())); replace.put("${initCode}", scriptSessionManager.getInitCode()); return replace; } /** * This API is primarily for JAWR to discover the tags that we are using * to customize our output. */ public static List<String> getKeywords() { return Arrays.asList(new String[] { "pollWithXhr", "pathToDwrServlet", "sessionCookieName", "allowGetForSafariButMakeForgeryEasier", "scriptTagProtection", "plainCallHandlerUrl", "plainPollHandlerUrl", "htmlCallHandlerUrl", "htmlPollHandlerUrl", "defaultToAsync", "versionMajor", "versionMinor", "versionRevision", "versionBuild", "versionTitle", "versionLabel", "initCode", }); } /** * Are we supporting streaming? * @param serverLoadMonitor the serverLoadMonitor to set */ public void setServerLoadMonitor(ServerLoadMonitor serverLoadMonitor) { this.serverLoadMonitor = serverLoadMonitor; } /** * @param allowGetForSafariButMakeForgeryEasier Do we reduce security to help Safari */ public void setAllowGetForSafariButMakeForgeryEasier(boolean allowGetForSafariButMakeForgeryEasier) { this.allowGetForSafariButMakeForgeryEasier = allowGetForSafariButMakeForgeryEasier; } /** * What is the string we use for script tag hack protection * @param scriptTagProtection the scriptTagProtection to set */ public void setScriptTagProtection(String scriptTagProtection) { this.scriptTagProtection = scriptTagProtection; } /** * Alter the session cookie name from the default JSESSIONID. * @param sessionCookieName the sessionCookieName to set */ public void setSessionCookieName(String sessionCookieName) { this.sessionCookieName = sessionCookieName; } /** * Sometimes with proxies, you need to close the stream all the time to * make the flush work. A value of -1 indicated that we do not do early * closing after writes. * @param maxWaitAfterWrite the maxWaitAfterWrite to set */ public void setMaxWaitAfterWrite(int maxWaitAfterWrite) { this.maxWaitAfterWrite = maxWaitAfterWrite; } /** * @param plainCallHandlerUrl the plainCallHandlerUrl to set */ public void setPlainCallHandlerUrl(String plainCallHandlerUrl) { this.plainCallHandlerUrl = plainCallHandlerUrl; } /** * @param plainPollHandlerUrl the plainPollHandlerUrl to set */ public void setPlainPollHandlerUrl(String plainPollHandlerUrl) { this.plainPollHandlerUrl = plainPollHandlerUrl; } /** * @param htmlCallHandlerUrl the htmlCallHandlerUrl to set */ public void setHtmlCallHandlerUrl(String htmlCallHandlerUrl) { this.htmlCallHandlerUrl = htmlCallHandlerUrl; } /** * @param htmlPollHandlerUrl the htmlPollHandlerUrl to set */ public void setHtmlPollHandlerUrl(String htmlPollHandlerUrl) { this.htmlPollHandlerUrl = htmlPollHandlerUrl; } /** * @param remoter the remoter to set */ public void setRemoter(Remoter remoter) { this.remoter = remoter; } /** * @param scriptSessionManager the scriptSessionManager to set */ public void setScriptSessionManager(ScriptSessionManager scriptSessionManager) { this.scriptSessionManager = scriptSessionManager; } /** * URL that engine.js makes calls into */ private String plainCallHandlerUrl; /** * URL that engine.js makes calls into */ private String plainPollHandlerUrl; /** * URL that engine.js makes calls into */ private String htmlCallHandlerUrl; /** * URL that engine.js makes calls into */ private String htmlPollHandlerUrl; /** * The source of the commands to we give to the client on startup? */ private ScriptSessionManager scriptSessionManager; /** * The session cookie name */ private String sessionCookieName = "JSESSIONID"; /** * Sometimes with proxies, you need to close the stream all the time to * make the flush work. A value of -1 indicated that we do not do early * closing after writes. * See also: org.directwebremoting.dwrp.BasePollHandler.maxWaitAfterWrite */ private int maxWaitAfterWrite = -1; /** * By default we disable GET, but this hinders old Safaris */ private boolean allowGetForSafariButMakeForgeryEasier = false; /** * What is the string we use for script tag hack protection */ private String scriptTagProtection; /** * Does DWR by default use synchronous XHR - i.e. Sjax */ private final boolean defaultToAsync = true; /** * So we can correctly calculate the path to the DWR servlet */ private Remoter remoter; /** * Are we supporting streaming? */ private ServerLoadMonitor serverLoadMonitor; }