001: /*
002: * Copyright 2005 Joe Walker
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.directwebremoting.servlet;
017:
018: import java.io.IOException;
019: import java.util.HashMap;
020: import java.util.Map;
021:
022: import javax.servlet.http.HttpServletRequest;
023: import javax.servlet.http.HttpServletResponse;
024:
025: import org.directwebremoting.WebContextFactory;
026: import org.directwebremoting.extend.DwrConstants;
027: import org.directwebremoting.extend.Remoter;
028: import org.directwebremoting.extend.ServerLoadMonitor;
029: import org.directwebremoting.util.MimeConstants;
030: import org.directwebremoting.util.VersionUtil;
031:
032: /**
033: * A Handler that supports requests for engine.js
034: * @author Joe Walker [joe at getahead dot ltd dot uk]
035: */
036: public class EngineHandler extends JavaScriptHandler {
037: /**
038: * Setup the {@link JavaScriptHandler} defaults
039: */
040: public EngineHandler() {
041: setMimeType(MimeConstants.MIME_JS);
042: }
043:
044: /* (non-Javadoc)
045: * @see org.directwebremoting.servlet.TemplateHandler#generateTemplate(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
046: */
047: @Override
048: protected String generateTemplate(HttpServletRequest request,
049: HttpServletResponse response) throws IOException {
050: return readResource(DwrConstants.PACKAGE + "/engine.js");
051: }
052:
053: /* (non-Javadoc)
054: * @see org.directwebremoting.servlet.FileHandler#getSearchReplacePairs()
055: */
056: @Override
057: public Map<String, String> getSearchReplacePairs() {
058: HttpServletRequest request = WebContextFactory.get()
059: .getHttpServletRequest();
060: Map<String, String> replace = new HashMap<String, String>();
061:
062: // If we are dynamic then we might need to pre-configure some variables.
063: boolean streaming = true;
064:
065: // If the maxWaitAfterWrite time is less than half a second then we
066: // count ourselves to be not streaming, and use the simple XHR
067: // connection method.
068: if (maxWaitAfterWrite > -1 && maxWaitAfterWrite < 500) {
069: streaming = false;
070: }
071:
072: // If the ServerLoadMonitor says no streaming, then obviously ...
073: if (!serverLoadMonitor.supportsStreaming()) {
074: streaming = false;
075: }
076:
077: // Poll using XHR (to avoid IE clicking) if we close
078: // the connection than 1sec after output happens.
079: String pollWithXhr = streaming ? "false" : "true";
080: replace.put("${pollWithXhr}", pollWithXhr);
081:
082: // What is the replacement field we use to tell engine.js what we are using
083: // for script tag hack protection
084: String contextServletPath = request.getContextPath()
085: + request.getServletPath();
086: String pathToDwrServlet = remoter
087: .getPathToDwrServlet(contextServletPath);
088: replace.put("${pathToDwrServlet}", pathToDwrServlet);
089:
090: // Under what cookie name is the session id stored?
091: replace.put("${sessionCookieName}", sessionCookieName);
092:
093: // Does engine.js do GETs for Safari
094: replace.put("${allowGetForSafariButMakeForgeryEasier}", String
095: .valueOf(allowGetForSafariButMakeForgeryEasier));
096:
097: // What is the replacement field we use to tell engine.js what we are
098: // using for script tag hack protection
099: replace.put("${scriptTagProtection}", scriptTagProtection);
100:
101: // engine.js needs to know the URLs to send requests to:
102: replace.put("${plainCallHandlerUrl}", plainCallHandlerUrl);
103: replace.put("${plainPollHandlerUrl}", plainPollHandlerUrl);
104: replace.put("${htmlCallHandlerUrl}", htmlCallHandlerUrl);
105: replace.put("${htmlPollHandlerUrl}", htmlPollHandlerUrl);
106:
107: // Do we start off with everything in Sjax mode?
108: replace
109: .put("${defaultToAsync}", String
110: .valueOf(defaultToAsync));
111:
112: // Version numbers so clients can sort out what they're up against
113: replace.put("${versionMajor}", String.valueOf(VersionUtil
114: .getMajor()));
115: replace.put("${versionMinor}", String.valueOf(VersionUtil
116: .getMinor()));
117: replace.put("${versionRevision}", String.valueOf(VersionUtil
118: .getRevision()));
119: replace.put("${versionBuild}", String.valueOf(VersionUtil
120: .getBuild()));
121: replace.put("${versionTitle}", String.valueOf(VersionUtil
122: .getTitle()));
123: replace.put("${versionLabel}", String.valueOf(VersionUtil
124: .getLabel()));
125:
126: return replace;
127: }
128:
129: /**
130: * Are we supporting streaming?
131: * @param serverLoadMonitor the serverLoadMonitor to set
132: */
133: public void setServerLoadMonitor(ServerLoadMonitor serverLoadMonitor) {
134: this .serverLoadMonitor = serverLoadMonitor;
135: }
136:
137: /**
138: * @param allowGetForSafariButMakeForgeryEasier Do we reduce security to help Safari
139: */
140: public void setAllowGetForSafariButMakeForgeryEasier(
141: boolean allowGetForSafariButMakeForgeryEasier) {
142: this .allowGetForSafariButMakeForgeryEasier = allowGetForSafariButMakeForgeryEasier;
143: }
144:
145: /**
146: * What is the string we use for script tag hack protection
147: * @param scriptTagProtection the scriptTagProtection to set
148: */
149: public void setScriptTagProtection(String scriptTagProtection) {
150: this .scriptTagProtection = scriptTagProtection;
151: }
152:
153: /**
154: * Alter the session cookie name from the default JSESSIONID.
155: * @param sessionCookieName the sessionCookieName to set
156: */
157: public void setSessionCookieName(String sessionCookieName) {
158: this .sessionCookieName = sessionCookieName;
159: }
160:
161: /**
162: * Sometimes with proxies, you need to close the stream all the time to
163: * make the flush work. A value of -1 indicated that we do not do early
164: * closing after writes.
165: * @param maxWaitAfterWrite the maxWaitAfterWrite to set
166: */
167: public void setMaxWaitAfterWrite(int maxWaitAfterWrite) {
168: this .maxWaitAfterWrite = maxWaitAfterWrite;
169: }
170:
171: /**
172: * @param plainCallHandlerUrl the plainCallHandlerUrl to set
173: */
174: public void setPlainCallHandlerUrl(String plainCallHandlerUrl) {
175: this .plainCallHandlerUrl = plainCallHandlerUrl;
176: }
177:
178: /**
179: * @param plainPollHandlerUrl the plainPollHandlerUrl to set
180: */
181: public void setPlainPollHandlerUrl(String plainPollHandlerUrl) {
182: this .plainPollHandlerUrl = plainPollHandlerUrl;
183: }
184:
185: /**
186: * @param htmlCallHandlerUrl the htmlCallHandlerUrl to set
187: */
188: public void setHtmlCallHandlerUrl(String htmlCallHandlerUrl) {
189: this .htmlCallHandlerUrl = htmlCallHandlerUrl;
190: }
191:
192: /**
193: * @param htmlPollHandlerUrl the htmlPollHandlerUrl to set
194: */
195: public void setHtmlPollHandlerUrl(String htmlPollHandlerUrl) {
196: this .htmlPollHandlerUrl = htmlPollHandlerUrl;
197: }
198:
199: /**
200: * @param remoter the remoter to set
201: */
202: public void setRemoter(Remoter remoter) {
203: this .remoter = remoter;
204: }
205:
206: /**
207: * URL that engine.js makes calls into
208: */
209: private String plainCallHandlerUrl;
210:
211: /**
212: * URL that engine.js makes calls into
213: */
214: private String plainPollHandlerUrl;
215:
216: /**
217: * URL that engine.js makes calls into
218: */
219: private String htmlCallHandlerUrl;
220:
221: /**
222: * URL that engine.js makes calls into
223: */
224: private String htmlPollHandlerUrl;
225:
226: /**
227: * The session cookie name
228: */
229: private String sessionCookieName = "JSESSIONID";
230:
231: /**
232: * Sometimes with proxies, you need to close the stream all the time to
233: * make the flush work. A value of -1 indicated that we do not do early
234: * closing after writes.
235: * See also: org.directwebremoting.dwrp.PollHandler.maxWaitAfterWrite
236: */
237: private int maxWaitAfterWrite = -1;
238:
239: /**
240: * By default we disable GET, but this hinders old Safaris
241: */
242: private boolean allowGetForSafariButMakeForgeryEasier = false;
243:
244: /**
245: * What is the string we use for script tag hack protection
246: */
247: private String scriptTagProtection = DwrConstants.SCRIPT_TAG_PROTECTION;
248:
249: /**
250: * Does DWR by default use synchronous XHR - i.e. Sjax
251: */
252: private boolean defaultToAsync = true;
253:
254: /**
255: * So we can correctly calculate the path to the DWR servlet
256: */
257: private Remoter remoter;
258:
259: /**
260: * Are we supporting streaming?
261: */
262: private ServerLoadMonitor serverLoadMonitor;
263: }
|