001: /*
002: * Copyright 2001-2006 C:1 Financial Services GmbH
003: *
004: * This software is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License Version 2.1, as published by the Free Software Foundation.
007: *
008: * This software is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
011: * Lesser General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public
014: * License along with this library; if not, write to the Free Software
015: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
016: */
017:
018: package de.finix.contelligent.core;
019:
020: import java.io.File;
021: import java.io.UnsupportedEncodingException;
022: import java.util.Enumeration;
023: import java.util.HashMap;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.Map;
027:
028: import javax.servlet.ServletContext;
029: import javax.servlet.http.Cookie;
030: import javax.servlet.http.HttpServletRequest;
031: import javax.servlet.http.HttpServletResponse;
032:
033: import org.apache.commons.fileupload.DiskFileUpload;
034: import org.apache.commons.fileupload.FileItem;
035: import org.apache.commons.fileupload.FileUpload;
036: import org.apache.commons.fileupload.FileUploadException;
037:
038: import de.finix.contelligent.Contelligent;
039: import de.finix.contelligent.HTTPCallData;
040: import de.finix.contelligent.Session;
041: import de.finix.contelligent.util.HTTPUtils;
042:
043: /**
044: * This is an extension of the CallData interface for HTTP requests.
045: */
046: public class HTTPCallDataImpl extends AbstractCallDataImpl implements
047: HTTPCallData {
048:
049: // Set upload parameters
050: static final int MAX_UPLOAD_SIZE = 1024 * 1024 * 500; // 500 MB
051:
052: static final int MAX_MEMORY_SIZE = 1024 * 50; // 50 kB
053:
054: final private HttpServletRequest httpServletRequest;
055:
056: final private HttpServletResponse httpServletResponse;
057:
058: final private String baseURL;
059:
060: final private String secureBaseURL;
061:
062: final private String httpAuthBaseURL;
063:
064: final private String httpAuthSecureBaseURL;
065:
066: final private String currentBaseURL;
067:
068: final private String wholeURL;
069:
070: final private boolean currentProtocolHttps;
071:
072: final private boolean currentHttpAuth;
073:
074: private Map parameters;
075:
076: private Map fileParameters;
077:
078: private String requestBody;
079:
080: private ServletContext servletContext;
081:
082: private boolean allowHeaderAccess = true;
083:
084: public HTTPCallDataImpl(Session contelligentSession,
085: String baseURL, String httpAuthBaseURL,
086: boolean currentProtocolHttps, boolean currentHttpAuth,
087: HttpServletRequest httpServletRequest,
088: HttpServletResponse httpServletResponse,
089: ServletContext context, boolean createParameters) {
090: this (contelligentSession, baseURL, httpAuthBaseURL, "", "",
091: currentProtocolHttps, currentHttpAuth,
092: httpServletRequest, httpServletResponse, context,
093: createParameters);
094: }
095:
096: public HTTPCallDataImpl(Session contelligentSession,
097: String baseURL, String httpAuthBaseURL, String httpPort,
098: String httpsPort, boolean currentProtocolHttps,
099: boolean currentHttpAuth,
100: HttpServletRequest httpServletRequest,
101: HttpServletResponse httpServletResponse,
102: ServletContext context, boolean createParameters) {
103: super (contelligentSession);
104: this .httpServletRequest = httpServletRequest;
105: this .httpServletResponse = httpServletResponse;
106: this .currentProtocolHttps = currentProtocolHttps;
107: this .currentHttpAuth = currentHttpAuth;
108: this .servletContext = context;
109: this .wholeURL = javax.servlet.http.HttpUtils.getRequestURL(
110: httpServletRequest).toString();
111: // should be (Servlet API 2.3)
112: // this.wholeURL = httpServletRequest.getRequestURL().toString();
113: parameters = new HashMap();
114: fileParameters = new HashMap();
115: if (createParameters) {
116: fillParameterMaps(httpServletRequest);
117: }
118: boolean supportSecure = ContelligentImpl.getInstance()
119: .supportSecureComponents();
120: if (!supportSecure) {
121: this .baseURL = baseURL;
122: secureBaseURL = baseURL;
123: this .httpAuthBaseURL = httpAuthBaseURL;
124: this .httpAuthSecureBaseURL = httpAuthBaseURL;
125:
126: if (currentHttpAuth) {
127: this .currentBaseURL = httpAuthBaseURL;
128: } else {
129: this .currentBaseURL = baseURL;
130: }
131: } else {
132: StringBuffer buffer = new StringBuffer("https://");
133: buffer.append(httpServletRequest.getServerName());
134: if (httpsPort.length() != 0) {
135: buffer.append(":");
136: buffer.append(httpsPort);
137: }
138: this .httpAuthSecureBaseURL = buffer.toString()
139: + httpAuthBaseURL;
140:
141: buffer.append(baseURL);
142: this .secureBaseURL = buffer.toString();
143:
144: buffer = new StringBuffer("http://");
145: buffer.append(httpServletRequest.getServerName());
146: if (httpPort.length() != 0) {
147: buffer.append(":");
148: buffer.append(httpPort);
149: }
150: this .httpAuthBaseURL = buffer.toString() + httpAuthBaseURL;
151:
152: buffer.append(baseURL);
153: this .baseURL = buffer.toString();
154:
155: if (currentHttpAuth && currentProtocolHttps) {
156: this .currentBaseURL = this .httpAuthSecureBaseURL;
157: } else if (currentHttpAuth && !currentProtocolHttps) {
158: this .currentBaseURL = this .httpAuthBaseURL;
159: } else if (!currentHttpAuth && currentProtocolHttps) {
160: this .currentBaseURL = this .secureBaseURL;
161: } else if (!currentHttpAuth && !currentProtocolHttps) {
162: this .currentBaseURL = this .baseURL;
163: } else {
164: throw new IllegalStateException(
165: "currentBaseURL could not be defined!");
166: }
167: }
168: }
169:
170: private void fillParameterMaps(HttpServletRequest request) {
171: parseRequest(request);
172: if (isMultipart(request)) {
173: parseMultipartRequest(request);
174: }
175: }
176:
177: public String getWebApp() {
178: if (httpServletRequest != null) {
179: String webApp = httpServletRequest.getContextPath();
180: if (webApp.endsWith("/"))
181: return webApp.substring(0, webApp.length() - 1);
182: return webApp;
183: }
184: return null;
185: }
186:
187: public HttpServletRequest getHttpServletRequest() {
188: return httpServletRequest;
189: }
190:
191: public HttpServletResponse getHttpServletResponse() {
192: return httpServletResponse;
193: }
194:
195: public ServletContext getServletContext() {
196: return this .servletContext;
197: }
198:
199: public String getBaseURL() {
200: return this .getBaseURL(currentHttpAuth);
201: }
202:
203: public String getBaseURL(boolean withHttpAuth) {
204: if (withHttpAuth) {
205: return this .httpAuthBaseURL;
206: } else {
207: return this .baseURL;
208: }
209: }
210:
211: public String getSecureBaseURL() {
212: return this .getSecureBaseURL(currentHttpAuth);
213: }
214:
215: public String getSecureBaseURL(boolean withHttpAuth) {
216: if (withHttpAuth) {
217: return this .httpAuthSecureBaseURL;
218: } else {
219: return this .secureBaseURL;
220: }
221: }
222:
223: public String getCurrentBaseURL() {
224: return this .currentBaseURL;
225: }
226:
227: public String getWholeURL() {
228: return wholeURL;
229: }
230:
231: // MANAGING PARAMETERS AND ATTRIBUTES
232:
233: public Map getParameters() {
234: return parameters;
235: }
236:
237: public void setParameters(Map parameters) {
238: this .parameters = new HashMap(parameters);
239: }
240:
241: public Map getFileParameters() {
242: return new HashMap(fileParameters);
243: }
244:
245: // returns a single String value, first it searches in url parameters
246: // without counter, than among those with counter, ant at the end among
247: // standard parameters, if none parameter is found returns null
248: public String getParameter(String key) {
249: // XXX: should use correct encoding
250: return HTTPUtils.getParameter(key, parameters);
251: }
252:
253: // collecst all values from parameters with given key, the parameters
254: // are inserted into a single table, if none parameter is found returns
255: // null
256: public String[] getParameterValues(String key) {
257: return HTTPUtils.getParameterValues(key, parameters);
258: }
259:
260: // PERSISTENT PARAMETERS
261:
262: // returns a single String value, first a persistent parameter without
263: // counter
264: // is searched, then one with counter, if nothing is found returns null
265: public String getPersistentParameter(String key) {
266: return HTTPUtils.getPersistentParameter(key, parameters);
267: }
268:
269: // returns array build up of elements from counted and not counted
270: // parameters, not counted parameter values are first in the table
271: public String[] getPersistentParameterValues(String key) {
272: return HTTPUtils.getPersistentParameterValues(key, parameters);
273: }
274:
275: // if given liveTime is equal to 0 the new parameter will be without counter
276: public void setPersistentParameter(String key, String value,
277: int liveTime) {
278: HTTPUtils.setPersistentParameter(key, value, liveTime,
279: parameters);
280: }
281:
282: // if given liveTime is equal to 0 the new parameter will be without counter
283: public void setPersistentParameterValues(String key,
284: int parameterType, String[] values, int liveTime) {
285: HTTPUtils.setPersistentParameterValues(key, values, liveTime,
286: parameters);
287: }
288:
289: // removes counted and not counted parameters with given key
290: public void removePersistentParameter(String key, int parameterType) {
291: HTTPUtils.removePersistentParameter(key, parameters);
292: }
293:
294: // REQUEST ATTRIBUTES (objects)
295: public void setRequestAttribute(String key, Object value) {
296: getHttpServletRequest().setAttribute(key, value);
297: }
298:
299: public Object getRequestAttribute(String key) {
300: return getHttpServletRequest().getAttribute(key);
301: }
302:
303: public void removeRequestAttribute(String key) {
304: getHttpServletRequest().removeAttribute(key);
305: }
306:
307: /**
308: * Answer true if the request was sent via https:
309: */
310: public boolean secureTransfer() {
311: return currentProtocolHttps;
312: }
313:
314: private void parseRequest(HttpServletRequest request) {
315: Enumeration enumeration = request.getParameterNames();
316:
317: while (enumeration.hasMoreElements()) {
318: String key = (String) enumeration.nextElement();
319: parameters.put(key, recodeParameterValues(request
320: .getParameterValues(key)));
321: }
322: }
323:
324: private String[] recodeParameterValues(String[] values) {
325: String defEnc = ContelligentImpl.getInstance()
326: .getDefaultEncoding();
327: String paramEnc = ContelligentImpl.getInstance()
328: .getParameterEncoding();
329: if (defEnc.equals(paramEnc)) {
330: return values;
331: } else {
332: try {
333: String[] answer = new String[values.length];
334: for (int i = 0; i < values.length; i++) {
335: byte[] bytes = values[i].getBytes(paramEnc);
336: answer[i] = new String(bytes, defEnc);
337: }
338: return answer;
339: } catch (UnsupportedEncodingException e) {
340: System.err
341: .println("HTTPCallDataImpl.recodeParameterValues() - UnsupportedEncodingException: "
342: + e);
343: return values;
344: }
345: }
346: }
347:
348: public String getRequestBody() {
349: return requestBody;
350: }
351:
352: public void setRequestBody(String requestBody) {
353: this .requestBody = requestBody;
354: }
355:
356: public String encodeURL(String url) {
357: if (isSearchEngineSpider()) {
358: // Make sure search engines are never presented with
359: // jsessionid parameters.
360: return url;
361: } else {
362: return httpServletResponse.encodeURL(url);
363: }
364: }
365:
366: public String encodeRedirectURL(String url) {
367: if (isSearchEngineSpider()) {
368: // Make sure search engines are never presented with
369: // jsessionid parameters.
370: return url;
371: } else {
372: return httpServletResponse.encodeRedirectURL(url);
373: }
374: }
375:
376: public FileItem getFileItem(String source) {
377: return (FileItem) fileParameters.get(source);
378: }
379:
380: private void parseMultipartRequest(HttpServletRequest request) {
381: String uploadDirectoryName = ContelligentImpl.getInstance()
382: .getContelligentDir(
383: Contelligent.DIR_WORK + File.separator
384: + "tmpUpload");
385: (new File(uploadDirectoryName)).mkdirs();
386: // Create a new file upload handler
387: DiskFileUpload upload = new DiskFileUpload();
388: upload.setSizeMax(MAX_UPLOAD_SIZE);
389: upload.setSizeThreshold(MAX_MEMORY_SIZE);
390: upload.setRepositoryPath(uploadDirectoryName);
391:
392: try {
393: // Parse the request
394: List items = upload.parseRequest(request);
395:
396: // Process the uploaded fields
397: Iterator iter = items.iterator();
398: while (iter.hasNext()) {
399: FileItem item = (FileItem) iter.next();
400:
401: if (item.isFormField()) {
402: parameters.put(item.getFieldName(),
403: new String[] { item
404: .getString(ContelligentImpl
405: .getInstance()
406: .getParameterEncoding()) });
407: } else {
408: fileParameters.put(item.getFieldName(), item);
409: }
410: }
411: } catch (FileUploadException e) {
412: // ignore
413: } catch (UnsupportedEncodingException e) {
414: // UTF-8 is supported
415: }
416: }
417:
418: private boolean isMultipart(HttpServletRequest request) {
419: return FileUpload.isMultipartContent(request);
420: }
421:
422: public Cookie[] getCookies() {
423: return httpServletRequest.getCookies();
424: }
425:
426: public void setAllowHeaderAccess(boolean enabled) {
427: allowHeaderAccess = enabled;
428: }
429:
430: public boolean getAllowHeaderAccess() {
431: return allowHeaderAccess;
432: }
433:
434: public void setHeader(String name, String value) {
435: if (allowHeaderAccess) {
436: httpServletResponse.setHeader(name, value);
437: } // XXX: Possibly store value otherwise?
438: }
439:
440: public void setContentLength(int length) {
441: if (allowHeaderAccess) {
442: httpServletResponse.setContentLength(length);
443: } // XXX: Possibly store value otherwise?
444: }
445:
446: public boolean isCurrentProtocolHttps() {
447: return currentProtocolHttps;
448: }
449:
450: public boolean isCurrentHttpAuth() {
451: return currentHttpAuth;
452: }
453:
454: }
|