Java tutorial
/* * Adito * * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package com.adito.replacementproxy; import java.net.MalformedURLException; import java.net.URL; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.StringTokenizer; import java.util.Vector; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.adito.boot.HttpConstants; import com.adito.boot.PropertyList; import com.adito.boot.RequestHandlerRequest; import com.adito.boot.Util; import com.adito.core.RequestParameterMap; import com.adito.core.RequestParameterMap.ProxyURIDetails; import com.adito.core.stringreplacement.VariableReplacement; import com.adito.policyframework.LaunchSession; import com.adito.security.SessionInfo; import com.adito.webforwards.ReplacementProxyWebForward; /** * This class handles the first stage in the replacement proxy process in that * it gathers information sent from the clients browser, locates the session * the request is attached to and extracts the parameters required for passing * on to the next stage (the {@link ProxiedRequestDispatcher}). */ public class RequestProcessor { final static Log log = LogFactory.getLog(RequestProcessor.class); private ContentCache cache; private boolean getFromCache; private ReplacementProxyWebForward webForward; private RequestParameterMap requestParameters; private RequestHandlerRequest request; private HeaderMap headerMap; private LaunchSession launchSession; private URL requestBaseURL; private ProxyURIDetails proxyURIDetails; /** * Constructor. * * @param cache cache for storing cacheable pages * @param maxAge maximum age of objects in the cach * @param request the request * @param launchSession the session the web forward was launched under * @param proxiedUrl the proxied (or target) URL */ public RequestProcessor(ContentCache cache, int maxAge, RequestHandlerRequest request, LaunchSession launchSession) throws MalformedURLException { this.cache = cache; this.request = request; this.launchSession = launchSession; this.webForward = (ReplacementProxyWebForward) launchSession.getResource(); /* Get the base URL as requested by the client (i.e. the location of the * Adito server as the client sees it */ StringBuffer buf = new StringBuffer(); buf.append(request.isSecure() ? "https" : "http"); buf.append("://"); buf.append(request.getHost()); if (request.getPort() > 0 && ((request.isSecure() && request.getPort() != 443) || (!request.isSecure() && request.getPort() != 80))) { buf.append(":"); buf.append(request.getPort()); } requestBaseURL = new URL(buf.toString()); } /** * Get the base URL as requested by the client (i.e. the location of the * Adito server as the client sees it * * @return request base URL */ public URL getRequestBaseURL() { return requestBaseURL; } /** * Get the ID of the {@link LaunchSession} this web forward was launched * under. * * @return launch ID */ public String getLaunchId() { return launchSession.getId(); } public LaunchSession getLaunchSession() { return launchSession; } /** * Get the HTTP method used by the client (e.g. GET or POST). * * @return method */ public String getMethod() { return request.getMethod(); } /** * Get the request. * * @return request */ public RequestHandlerRequest getRequest() { return request; } /** * Get the session this request was made under. * * @return session */ public SessionInfo getSessionInfo() { return launchSession.getSession(); } /** * Get the request parameter map. * * @return request parameter map. */ public RequestParameterMap getRequestParameters() { return requestParameters; } /** * Get if the page may be retrieved from the cache. * @return */ public boolean isGetFromCache() { return getFromCache; } /** * Get the path of the URI for the request, including any request * parameters. * * @return base URI */ public String getUriEncoded() { String uriEncoded = Util .isNullOrTrimmedBlank(requestParameters.getProxiedURIDetails().getProxiedURL().getFile()) ? "/" : requestParameters.getProxiedURIDetails().getProxiedURL().getFile(); if (log.isDebugEnabled()) log.debug("Returning URI " + uriEncoded); return uriEncoded; } public void processRequest() throws Exception { // Create our own map of headers so they can be edited headerMap = new HeaderMap(); for (Enumeration e = request.getFieldNames(); e.hasMoreElements();) { String n = (String) e.nextElement(); for (Enumeration e2 = request.getFieldValues(n); e2.hasMoreElements();) { String v = (String) e2.nextElement(); headerMap.putHeader(n, v); } } // Build up the parameter map requestParameters = new RequestParameterMap(request); proxyURIDetails = requestParameters.getProxiedURIDetails(); VariableReplacement r = new VariableReplacement(); r.setRequest(request); r.setSession(launchSession.getSession()); r.setPolicy(launchSession.getPolicy()); String actualURL = r.replace(webForward.getDestinationURL()); if (proxyURIDetails.getProxiedURL() == null) { throw new Exception("No sslex_url parameter provided."); } if (log.isDebugEnabled()) log.debug("Proxying [" + request.getMethod() + "] " + proxyURIDetails.getProxiedURL()); URL proxiedURLBase = proxyURIDetails.getProxiedURLBase(); if (log.isDebugEnabled()) log.debug("Proxied URL base " + proxiedURLBase.toExternalForm()); // The web forward may restrict access to the target URL PropertyList restrictTo = webForward.getRestrictToHosts(); if (!restrictTo.isEmpty()) { boolean found = proxiedURLBase.getHost().equals(new URL(actualURL).getHost()); for (Iterator i = restrictTo.iterator(); !found && i.hasNext();) { String host = (String) i.next(); if (proxiedURLBase.getHost().matches(Util.parseSimplePatternToRegExp(host))) { found = true; } } if (!found) { throw new Exception("This resource (" + proxiedURLBase.toExternalForm() + ") is restricted to a list of target hosts. This host is not in the list."); } } // Determine if the page can be retrieved from cache getFromCache = false; Date expiryDate = null; if (cache != null && HttpConstants.METHOD_GET.equals(request.getMethod()) && cache.contains(proxyURIDetails.getProxiedURL())) { getFromCache = true; // HTTP 1.0 String cacheControl = request.getField(HttpConstants.HDR_PRAGMA); if (cacheControl != null && cacheControl.equalsIgnoreCase("no-cache")) { getFromCache = false; } else { String ifModifiedSince = request.getField(HttpConstants.HDR_IF_MODIFIED_SINCE); if (ifModifiedSince != null) { try { // Dont get from cache if getFromCache = false; } catch (Exception e) { } } } // HTTP 1.1 if (getFromCache) { cacheControl = request.getField(HttpConstants.HDR_CACHE_CONTROL); if (cacheControl != null) { StringTokenizer tok = new StringTokenizer(cacheControl, ";"); while (tok.hasMoreTokens()) { String t = tok.nextToken().trim(); String tl = t.toLowerCase(); if (t.startsWith("no-cache") || t.startsWith("no-store")) { getFromCache = false; } else if (tl.startsWith("max-age")) { expiryDate = new Date(); try { expiryDate.setTime( expiryDate.getTime() - (Integer.parseInt(Util.valueOfNameValuePair(tl)))); } catch (Exception e) { } } } } } // Check expiry if (getFromCache) { CacheingOutputStream cos = (CacheingOutputStream) cache.retrieve(proxyURIDetails.getProxiedURL()); if (expiryDate == null || (expiryDate != null && cos.getCachedDate().after(expiryDate))) { // Still ok } else { if (log.isDebugEnabled()) log.debug("Page expired"); getFromCache = false; } } else { if (log.isDebugEnabled()) log.debug("Not using cached page."); } } } public ReplacementProxyWebForward getWebForward() { return webForward; } /** * @return */ public String getRequestMethod() { return request.getMethod(); } /** * @return */ public HttpSession getSession() { return getSessionInfo().getHttpSession(); } /** * @param hdr * @return */ public String getHeader(String hdr) { Enumeration e = headerMap.getHeaders(hdr); return e == null ? null : (String) e.nextElement(); } /** * @return */ public Enumeration getHeaderNames() { return headerMap.keys(); } /** * @param hdr * @return */ public Enumeration getHeaders(String hdr) { return headerMap.getHeaders(hdr); } class HeaderMap extends Hashtable { private static final long serialVersionUID = -6768313767635812871L; HeaderMap() { } void putHeader(String name, String value) { Vector l = (Vector) get(name); if (l == null) { l = new Vector(); put(name, l); } l.addElement(value); } void setHeader(String name, String value) { Vector l = new Vector(); l.addElement(value); put(name, l); } Enumeration getHeaders(String hdr) { Vector l = (Vector) get(hdr); return l == null ? null : l.elements(); } } }