KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > replacementproxy > RequestProcessor


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.sslexplorer.replacementproxy;
21
22 import java.net.MalformedURLException JavaDoc;
23 import java.net.URL JavaDoc;
24 import java.util.Date JavaDoc;
25 import java.util.Enumeration JavaDoc;
26 import java.util.Hashtable JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29 import java.util.Vector JavaDoc;
30
31 import javax.servlet.http.HttpSession JavaDoc;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35
36 import com.sslexplorer.boot.HttpConstants;
37 import com.sslexplorer.boot.PropertyList;
38 import com.sslexplorer.boot.RequestHandlerRequest;
39 import com.sslexplorer.boot.Util;
40 import com.sslexplorer.core.CoreEvent;
41 import com.sslexplorer.core.CoreServlet;
42 import com.sslexplorer.core.RequestParameterMap;
43 import com.sslexplorer.core.stringreplacement.VariableReplacement;
44 import com.sslexplorer.policyframework.LaunchSession;
45 import com.sslexplorer.policyframework.ResourceAccessEvent;
46 import com.sslexplorer.security.SessionInfo;
47 import com.sslexplorer.webforwards.ReplacementProxyWebForward;
48 import com.sslexplorer.webforwards.WebForwardEventConstants;
49
50
51
52 /**
53  * This class handles the first stage in the replacement proxy process in that
54  * it gathers information sent from the clients browser, locates the session
55  * the request is attached to and extracts the parameters required for passing
56  * on to the next stage (the {@link ProxiedRequestDispatcher}).
57  *
58  *
59  * @author Brett Smith <a HREF="mailto: brett@3sp.com">&lt;brett@3sp.com&gt;</a>
60  */

61 public class RequestProcessor {
62     final static Log log = LogFactory.getLog(RequestProcessor.class);
63
64     private ContentCache cache;
65     private boolean getFromCache;
66     private ReplacementProxyWebForward webForward;
67     private RequestParameterMap requestParameters ;
68     private RequestHandlerRequest request;
69     private HeaderMap headerMap;
70     private LaunchSession launchSession;
71     private URL JavaDoc requestBaseURL;
72
73     /**
74      * Constructor.
75      *
76      * @param cache cache for storing cacheable pages
77      * @param maxAge maximum age of objects in the cach
78      * @param request the request
79      * @param launchSession the session the web forward was launched under * @param proxiedUrl the proxied (or target) URL
80      */

81     public RequestProcessor(ContentCache cache,
82                             int maxAge,
83                             RequestHandlerRequest request,
84                             LaunchSession launchSession) throws MalformedURLException JavaDoc {
85         this.cache = cache;
86         this.request = request;
87         this.launchSession = launchSession;
88         this.webForward = (ReplacementProxyWebForward)launchSession.getResource();
89
90         /* Get the base URL as requested by the client (i.e. the location of the
91          * SSL-Explorer server as the client sees it
92          */

93         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
94         buf.append(request.isSecure() ? "https" : "http");
95         buf.append("://");
96         buf.append(request.getHost());
97         if( request.getPort() > 0 && ( ( request.isSecure() && request.getPort() != 443 ) ||
98             ( !request.isSecure() && request.getPort() != 80 ) ) ) {
99             buf.append(":");
100             buf.append(request.getPort());
101         }
102         requestBaseURL = new URL JavaDoc(buf.toString());
103     }
104     
105     /**
106      * Get the base URL as requested by the client (i.e. the location of the
107      * SSL-Explorer server as the client sees it
108      *
109      * @return request base URL
110      */

111     public URL JavaDoc getRequestBaseURL() {
112         return requestBaseURL;
113     }
114
115     /**
116      * Get the ID of the {@link LaunchSession} this web forward was launched
117      * under.
118      *
119      * @return launch ID
120      */

121     public String JavaDoc getLaunchId() {
122         return launchSession.getId();
123     }
124     
125     public LaunchSession getLaunchSession() {
126         return launchSession;
127     }
128
129     /**
130      * Get the HTTP method used by the client (e.g. GET or POST).
131      *
132      * @return method
133      */

134     public String JavaDoc getMethod() {
135         return request.getMethod();
136     }
137
138     /**
139      * Get the request.
140      *
141      * @return request
142      */

143     public RequestHandlerRequest getRequest() {
144         return request;
145     }
146
147     /**
148      * Get the session this request was made under.
149      *
150      * @return session
151      */

152     public SessionInfo getSessionInfo() {
153         return launchSession.getSession();
154     }
155
156     /**
157      * Get the request parameter map.
158      *
159      * @return request parameter map.
160      */

161     public RequestParameterMap getRequestParameters() {
162         return requestParameters;
163     }
164
165     /**
166      * Get if the page may be retrieved from the cache.
167      * @return
168      */

169     public boolean isGetFromCache() {
170         return getFromCache;
171     }
172
173     /**
174      * Get the path of the URI for the request, including any request
175      * parameters.
176      *
177      * @return base URI
178      */

179     public String JavaDoc getUriEncoded() {
180         String JavaDoc uriEncoded = Util.isNullOrTrimmedBlank(requestParameters.getProxiedURLBase().getFile()) ? "/" : requestParameters.getProxiedURLBase().getFile();
181         if (log.isDebugEnabled())
182             log.debug("Returning URI " + uriEncoded);
183         return uriEncoded;
184     }
185     
186     public void processRequest() throws Exception JavaDoc {
187
188         // Create our own map of headers so they can be edited
189
headerMap = new HeaderMap();
190         for(Enumeration JavaDoc e = request.getFieldNames(); e.hasMoreElements(); ) {
191             String JavaDoc n = (String JavaDoc)e.nextElement();
192             for(Enumeration JavaDoc e2 = request.getFieldValues(n); e2.hasMoreElements(); ) {
193                 String JavaDoc v = (String JavaDoc)e2.nextElement();
194                 headerMap.putHeader(n, v);
195             }
196         }
197
198         // Build up the parameter map
199
requestParameters = new RequestParameterMap(request);
200
201         VariableReplacement r = new VariableReplacement();
202         r.setRequest(request);
203         r.setSession(launchSession.getSession());
204         r.setPolicy(launchSession.getPolicy());
205         String JavaDoc actualURL = r.replace(webForward.getDestinationURL());
206         
207         if (requestParameters.getProxiedURL() == null) {
208             throw new Exception JavaDoc("No sslex_url parameter provided.");
209         }
210         
211         if (log.isDebugEnabled())
212             log.debug("Proxying [" + request.getMethod() + "] " + requestParameters.getProxiedURL());
213
214         URL JavaDoc proxiedURLBase = requestParameters.getProxiedURLBase();
215         if (log.isDebugEnabled())
216             log.debug("Proxied URL base " + proxiedURLBase.toExternalForm());
217         
218         CoreServlet.getServlet().fireCoreEvent(new ResourceAccessEvent(this,
219                         WebForwardEventConstants.WEB_FORWARD_RESOURCE_LOADED, webForward, launchSession.getPolicy(), launchSession.getSession(), CoreEvent.STATE_SUCCESSFUL).
220                         addAttribute(WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_URL, proxiedURLBase.toExternalForm()));
221
222         // The web forward may restrict access to the target URL
223
PropertyList restrictTo = webForward.getRestrictToHosts();
224         if(!restrictTo.isEmpty()) {
225             boolean found = proxiedURLBase.getHost().equals(new URL JavaDoc(actualURL).getHost());
226             for(Iterator JavaDoc i = restrictTo.iterator(); !found && i.hasNext(); ) {
227                 String JavaDoc host = (String JavaDoc)i.next();
228                 if(proxiedURLBase.getHost().matches(Util.parseSimplePatternToRegExp(host))) {
229                     found = true;
230                 }
231             }
232             if(!found) {
233                 throw new Exception JavaDoc("This resource (" + proxiedURLBase.toExternalForm() + ") is restricted to a list of target hosts. This host is not in the list.");
234             }
235
236         }
237
238         // Determine if the page can be retrieved from cache
239

240         getFromCache = false;
241         Date JavaDoc expiryDate = null;
242         if (cache != null && HttpConstants.METHOD_GET.equals(request.getMethod()) && cache.contains(requestParameters.getProxiedURL())) {
243             getFromCache = true;
244
245             // HTTP 1.0
246
String JavaDoc cacheControl = request.getField(HttpConstants.HDR_PRAGMA);
247             if (cacheControl != null && cacheControl.equalsIgnoreCase("no-cache")) {
248                 getFromCache = false;
249             } else {
250                 String JavaDoc ifModifiedSince = request.getField(HttpConstants.HDR_IF_MODIFIED_SINCE);
251                 if (ifModifiedSince != null) {
252                     try {
253                         // Dont get from cache if
254
getFromCache = false;
255                     } catch (Exception JavaDoc e) {
256                     }
257                 }
258             }
259
260             // HTTP 1.1
261
if (getFromCache) {
262                 cacheControl = request.getField(HttpConstants.HDR_CACHE_CONTROL);
263                 if (cacheControl != null) {
264                     StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(cacheControl, ";");
265                     while (tok.hasMoreTokens()) {
266                         String JavaDoc t = tok.nextToken().trim();
267                         String JavaDoc tl = t.toLowerCase();
268                         if (t.startsWith("no-cache") || t.startsWith("no-store")) {
269                             getFromCache = false;
270                         } else if (tl.startsWith("max-age")) {
271                             expiryDate = new Date JavaDoc();
272                             try {
273                                 expiryDate.setTime(expiryDate.getTime() - (Integer.parseInt(Util.valueOfNameValuePair(tl))));
274                             } catch (Exception JavaDoc e) {
275                             }
276                         }
277                     }
278                 }
279             }
280
281             // Check expiry
282
if(getFromCache) {
283                 CacheingOutputStream cos = (CacheingOutputStream) cache.retrieve(requestParameters.getProxiedURL());
284                 if(expiryDate == null || ( expiryDate != null && cos.getCachedDate().after(expiryDate) ) ) {
285                     // Still ok
286
}
287                 else {
288                     if (log.isDebugEnabled())
289                         log.debug("Page expired");
290                     getFromCache = false;
291                 }
292             }
293             else {
294                 if (log.isDebugEnabled())
295                     log.debug("Not using cached page.");
296             }
297         }
298     }
299
300     public ReplacementProxyWebForward getWebForward() {
301         return webForward;
302     }
303
304     /**
305      * @return
306      */

307     public String JavaDoc getRequestMethod() {
308         return request.getMethod();
309     }
310
311     /**
312      * @return
313      */

314     public HttpSession JavaDoc getSession() {
315         return getSessionInfo().getHttpSession();
316     }
317
318     /**
319      * @param hdr
320      * @return
321      */

322     public String JavaDoc getHeader(String JavaDoc hdr) {
323         Enumeration JavaDoc e = headerMap.getHeaders(hdr);
324         return e == null ? null : (String JavaDoc)e.nextElement();
325     }
326
327     /**
328      * @return
329      */

330     public Enumeration JavaDoc getHeaderNames() {
331         return headerMap.keys();
332     }
333
334     /**
335      * @param hdr
336      * @return
337      */

338     public Enumeration JavaDoc getHeaders(String JavaDoc hdr) {
339         return headerMap.getHeaders(hdr);
340     }
341
342     class HeaderMap extends Hashtable JavaDoc {
343
344         private static final long serialVersionUID = -6768313767635812871L;
345
346         HeaderMap() {
347
348         }
349
350         void putHeader(String JavaDoc name, String JavaDoc value) {
351             Vector JavaDoc l = (Vector JavaDoc)get(name);
352             if(l == null) {
353                 l = new Vector JavaDoc();
354                 put(name, l);
355             }
356             l.addElement(value);
357         }
358
359         void setHeader(String JavaDoc name, String JavaDoc value) {
360             Vector JavaDoc l = new Vector JavaDoc();
361             l.addElement(value);
362             put(name, l);
363         }
364
365         Enumeration JavaDoc getHeaders(String JavaDoc hdr) {
366             Vector JavaDoc l = (Vector JavaDoc)get(hdr);
367             return l == null ? null : l.elements();
368
369         }
370     }
371 }
372
Popular Tags