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.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.adito.boot.Replacer; import com.adito.boot.Util; import com.adito.core.RequestParameterMap.ProxyURIDetails; import com.adito.util.Utils; /** */ public class ProxyReplacer implements Replacer { final static Log log = LogFactory.getLog(ProxyReplacer.class); private RequestProcessor requestProcessor; private BaseSearch baseSearch; private ProxyURIDetails proxyDetails; /** * */ public ProxyReplacer(RequestProcessor requestProcessor, BaseSearch baseSearch) { super(); this.requestProcessor = requestProcessor; this.baseSearch = baseSearch; proxyDetails = requestProcessor.getRequestParameters().getProxiedURIDetails(); } public String getProxiedPath(URL context, String path, String base) { // TODO leave alone? if (path.startsWith("#")) { return path; } // Some types we do not want to proxy at all String lc = path.toLowerCase(); if (lc.startsWith("mailto:") || lc.startsWith("javascript:") || lc.startsWith("ftp:") || lc.startsWith("news")) { return path; } // Strip the reference of the path (either as a URL or a relative path) // and // store it for // later appending to the proxied path URL pathURL = null; String ref = ""; try { pathURL = new URL(path); if (pathURL.getRef() != null) { ref = "#" + pathURL.getRef(); int idx = path.lastIndexOf('#'); path = path.substring(0, idx); pathURL = new URL(path); } } catch (MalformedURLException murle) { int idx = path.lastIndexOf('#'); if (idx != -1) { ref = "#" + path.substring(idx + 1); path = path.substring(0, idx); } } // The web forward may restrict access to the target URL // if (requestProcessor.getWebForward().getRestrictToURL()) { // try { // URL webForwardURL = new URL(requestProcessor.getWebForward().getDestinationURL()); // if (!(InetAddress.getByName(pathURL.getHost()).equals(InetAddress.getByName(webForwardURL.getHost())))) { // throw new Exception("Restricted."); // } // } catch (Exception e) { // return "javascript: void();"; // } // // } /** * LDP - We have to unescape any HTML entities because our client will not process them * otherwise when a request is received. */ String newPath = null; try { if (base != null) { if (pathURL != null) { //newPath = "/replacementProxyEngine?" + LaunchSession.LONG_LAUNCH_ID + "=" + requestProcessor.getLaunchId() + "&sslex_url=" + Util.urlEncode(Utils.htmlunescape(pathURL.toExternalForm())) + ref; newPath = "/replacementProxyEngine/" + requestProcessor.getLaunchId() + "/" + Util.urlEncode(Utils.htmlunescape(pathURL.toExternalForm())) + ref; } else { // Relative so we need to prepend the base if (path.startsWith("./")) { path = path.substring(2); } try { URL baseURL = new URL(base); URL actual = new URL(baseURL, path); //newPath = "/replacementProxyEngine?" + LaunchSession.LONG_LAUNCH_ID + "=" + requestProcessor.getLaunchId() + "&sslex_url=" + Util.urlEncode(Utils.htmlunescape(actual.toExternalForm())) + ref; newPath = "/replacementProxyEngine/" + requestProcessor.getLaunchId() + "/" + Util.urlEncode(Utils.htmlunescape(actual.toExternalForm())) + ref; } catch (MalformedURLException murle) { log.error("Invalidate base URL.", murle); } } } else { URL actual = new URL(context, path); //newPath = "/replacementProxyEngine?" + LaunchSession.LONG_LAUNCH_ID + "=" + requestProcessor.getLaunchId() + "&sslex_url=" + Util.urlEncode(Utils.htmlunescape(actual.toExternalForm())) + ref; newPath = "/replacementProxyEngine/" + requestProcessor.getLaunchId() + "/" + Util.urlEncode(Utils.htmlunescape(actual.toExternalForm())) + ref; } } catch (MalformedURLException ex) { log.error("Could not convert path from '" + path + "' using " + context.toExternalForm(), ex); newPath = path; } if (newPath == null) { log.warn("Failed to proxy path " + path + ", using original."); newPath = path; } if (log.isDebugEnabled()) log.debug("Created proxy path " + newPath); // Unescape the last encoded path int idx = newPath.lastIndexOf("%2F"); newPath = newPath.substring(0, idx) + "/" + newPath.substring(idx + 3); return newPath; } public String getReplacement(Pattern pattern, Matcher matcher, String replacementPattern) { StringBuffer buf = new StringBuffer(); char ch; boolean esc = false; try { for (int i = 0; i < replacementPattern.length(); i++) { ch = replacementPattern.charAt(i); if (esc) { buf.append(ch); esc = false; } else { if (ch == '\\') { esc = true; } else if (ch == '%') { i++; ch = replacementPattern.charAt(i); int group = Integer.parseInt(String.valueOf(ch)); String groupText = matcher.group(group); if (groupText != null && !groupText.equals("")) { buf.append(getProxiedPath(proxyDetails.getProxiedURLBase(), groupText, baseSearch.getBase())); } } else if (ch == '$') { i++; ch = replacementPattern.charAt(i); int group = Integer.parseInt(String.valueOf(ch)); String groupText = matcher.group(group); if (groupText != null && !groupText.equals("")) { buf.append(groupText); } } else if (ch == '^') { i++; ch = replacementPattern.charAt(i); if (ch == 'T') { buf.append(requestProcessor.getLaunchId()); } else { int group = Integer.parseInt(String.valueOf(ch)); String groupText = matcher.group(group); if (groupText != null && !groupText.equals("")) { buf.append(new URL(proxyDetails.getProxiedURLBase(), groupText).toExternalForm()); } } } else if (ch == '~') { i++; ch = replacementPattern.charAt(i); int group = Integer.parseInt(String.valueOf(ch)); String groupText = matcher.group(group); if (groupText != null && !groupText.equals("")) { groupText = groupText.replaceAll("\\\\", ""); buf.append(getProxiedPath(proxyDetails.getProxiedURLBase(), groupText, baseSearch.getBase())); } } else { buf.append(ch); } } } return buf.toString(); } catch (Throwable t) { log.warn("Invalid replacement pattern " + replacementPattern, t); } return replacementPattern; } }