diff options
Diffstat (limited to 'src/main/java/com/btr/proxy/util')
-rw-r--r-- | src/main/java/com/btr/proxy/util/EmptyXMLResolver.java | 26 | ||||
-rw-r--r-- | src/main/java/com/btr/proxy/util/Logger.java | 87 | ||||
-rw-r--r-- | src/main/java/com/btr/proxy/util/PListParser.java | 544 | ||||
-rw-r--r-- | src/main/java/com/btr/proxy/util/PlatformUtil.java | 114 | ||||
-rw-r--r-- | src/main/java/com/btr/proxy/util/ProxyException.java | 50 | ||||
-rw-r--r-- | src/main/java/com/btr/proxy/util/ProxyUtil.java | 84 | ||||
-rw-r--r-- | src/main/java/com/btr/proxy/util/UriFilter.java | 21 |
7 files changed, 926 insertions, 0 deletions
diff --git a/src/main/java/com/btr/proxy/util/EmptyXMLResolver.java b/src/main/java/com/btr/proxy/util/EmptyXMLResolver.java new file mode 100644 index 0000000..9330556 --- /dev/null +++ b/src/main/java/com/btr/proxy/util/EmptyXMLResolver.java @@ -0,0 +1,26 @@ +package com.btr.proxy.util; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/***************************************************************************** + * This resolver is used to prevent network lookups of DTD or XML schemas. + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + +public class EmptyXMLResolver implements EntityResolver { + + /************************************************************************* + * Overwritten to return an empty entity. + * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String) + ************************************************************************/ + + public InputSource resolveEntity( String arg0, String arg1 ) throws SAXException, IOException { + return new InputSource( new ByteArrayInputStream("".getBytes())); + } + +} diff --git a/src/main/java/com/btr/proxy/util/Logger.java b/src/main/java/com/btr/proxy/util/Logger.java new file mode 100644 index 0000000..f434699 --- /dev/null +++ b/src/main/java/com/btr/proxy/util/Logger.java @@ -0,0 +1,87 @@ +package com.btr.proxy.util; + +import java.text.MessageFormat; + +/***************************************************************************** + * Simple logging support for the framework. + * You need to add an logging listener that needs to send the logging events + * to an backend. + * + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + +public class Logger { + + public enum LogLevel {ERROR, WARNING, INFO, TRACE, DEBUG} + + /***************************************************************************** + * Interface for an logging backend that can be attached to the logger. + ****************************************************************************/ + + public interface LogBackEnd { + + /************************************************************************* + * Invoked for every logging event. + * @param clazz the class that sends the log message. + * @param loglevel the logging level. + * @param msg the message format string. + * @param params the message parameters for the format string. + ************************************************************************/ + + public void log(Class<?> clazz, LogLevel loglevel, String msg, Object ...params); + + /************************************************************************* + * Can be used to test if a given logging level is enabled. + * @param logLevel the loglevel to test. + * @return true if enabled, else false. + ************************************************************************/ + + public boolean isLogginEnabled(LogLevel logLevel); + } + + private static LogBackEnd backend; + + /************************************************************************* + * Gets the currently attached logging backend. + * @return Returns the backend. + ************************************************************************/ + + public static LogBackEnd getBackend() { + return backend; + } + + /************************************************************************* + * Attaches a new logging backend replacing the existing one. + * @param backend The backend to set. + ************************************************************************/ + + public static void setBackend(LogBackEnd backend) { + Logger.backend = backend; + } + + /************************************************************************* + * Logs a message. + * @param clazz the class that sends the log message. + * @param loglevel the logging level. + * @param msg the message format string. + * @param params the message parameters for the format string. + ************************************************************************/ + + public static void log(Class<?> clazz, LogLevel loglevel, String msg, Object ...params) { + System.out.println(MessageFormat.format(msg, params)); + } + + /************************************************************************* + * Can be used to test if a given logging level is enabled. + * @param logLevel the loglevel to test. + * @return true if enabled, else false. + ************************************************************************/ + + public static boolean isLogginEnabled(LogLevel logLevel) { + if (backend != null) { + return backend.isLogginEnabled(logLevel); + } + return false; + } + +} diff --git a/src/main/java/com/btr/proxy/util/PListParser.java b/src/main/java/com/btr/proxy/util/PListParser.java new file mode 100644 index 0000000..b678900 --- /dev/null +++ b/src/main/java/com/btr/proxy/util/PListParser.java @@ -0,0 +1,544 @@ +package com.btr.proxy.util; + +import java.io.Closeable; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TimeZone; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Plist xml handling (serialization and deserialization) + * <p> + * <em>The xml plist dtd can be found at http://www.apple.com/DTDs/PropertyList-1.0.dtd</em> + * <p> + * The plist spec handles 8 types of objects: booleans, real, integers, dates, binary data, + * strings, arrays (lists) and dictionaries (maps). + * <p> + * The java Plist lib handles converting xml plists to a nested {@code Map<String, Object>} + * that can be trivially read from java. It also provides a simple way to convert a nested + * {@code Map<String, Object>} into an xml plist representation. + * <p> + * The following mapping will be done when converting from plist to <tt>Map</tt>: + * <pre> + * true/false -> Boolean + * real -> Double + * integer -> Integer/Long (depends on size, values exceeding an int will be rendered as longs) + * data -> byte[] + * string -> String + * array -> List + * dict -> Map + * </pre> + * <p> + * When converting from Map -> plist the conversion is as follows: + * <pre> + * Boolean -> true/false + * Float/Double -> real + * Byte/Short/Integer/Long -> integer + * byte[] -> data + * List -> array + * Map -> dict + * </pre> + * + * @author Christoffer Lerno / Modified by Bernd Rosstauscher + */ +public final class PListParser +{ + /***************************************************************************** + * Exception is used for XML parse problems. + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + + public static class XmlParseException extends Exception { + + /** Comment for <code>serialVersionUID</code>*/ + private static final long serialVersionUID = 1L; + + /************************************************************************* + * Constructor + ************************************************************************/ + + public XmlParseException() { + super(); + } + + /************************************************************************* + * Constructor + * @param msg the error message + ************************************************************************/ + + public XmlParseException(String msg) { + super(msg); + } + + /************************************************************************* + * Constructor + * @param msg error message + * @param e the cause. + ************************************************************************/ + + public XmlParseException(String msg, Exception e) { + super(msg, e); + } + + } + + /***************************************************************************** + * Small helper class representing a tree node. + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + + public static class Dict implements Iterable<Map.Entry<String, Object>> { + private Map<String, Object> children; + + /************************************************************************* + * Constructor + ************************************************************************/ + + public Dict() { + super(); + this.children = new HashMap<String, Object>(); + } + + /************************************************************************* + * @param key of the child node. + * @return the child node, null if not existing. + ************************************************************************/ + + public Object get(String key) { + return this.children.get(key); + } + + /************************************************************************* + * iterator + * @see java.lang.Iterable#iterator() + ************************************************************************/ + + public Iterator<Entry<String, Object>> iterator() { + return this.children.entrySet().iterator(); + } + + /************************************************************************* + * @return the size of this dictionary. + ************************************************************************/ + + public int size() { + return this.children.size(); + } + + /************************************************************************* + * Dumps a dictionary with all sub-nodes to the console. + ************************************************************************/ + + public void dump() { + System.out.println("PList"); + dumpInternal(this, 1); + } + + /************************************************************************* + * @param plist + * @param indent + ************************************************************************/ + + private static void dumpInternal(Dict plist, int indent) { + for (Map.Entry<String, Object> child : plist) { + if (child.getValue() instanceof Dict) { + for (int j = 0; j < indent; j++) { + System.out.print(" "); + } + System.out.println(child.getKey()); + dumpInternal((Dict) child.getValue(), indent+1); + } else { + for (int j = 0; j < indent; j++) { + System.out.print(" "); + } + System.out.println(child.getKey()+" = "+child.getValue()); + } + } + + } + + /************************************************************************* + * Get a node at a given path. + * @param path a / separated path into the plist hirarchy. + * @return the object located at the given path, null if it does not exist. + ************************************************************************/ + + public Object getAtPath(String path) { + Dict currentNode = this; + + String[] pathSegments = path.trim().split("/"); + for (int i = 0; i < pathSegments.length; i++) { + String segment = pathSegments[i].trim(); + if (segment.length() == 0) { + continue; + } + Object o = currentNode.get(segment); + if (i >= pathSegments.length-1) { + return o; + } + if (o == null || !(o instanceof Dict)){ + break; + } + currentNode = (Dict) o; + } + return null; + } + + } + + /** + * Singleton instance. + */ + private final static PListParser PLIST = new PListParser(); + + /** + * All element types possible for a plist. + */ + private static enum ElementType + { + INTEGER, + STRING, + REAL, + DATA, + DATE, + DICT, + ARRAY, + TRUE, + FALSE, + } + + private static final String BASE64_STRING + = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + private static final char[] BASE64_CHARS = BASE64_STRING.toCharArray(); + private final DateFormat m_dateFormat; + private final Map<Class<?>, ElementType> m_simpleTypes; + + /** + * Utility method to close a closeable. + * + * @param closeable or null. + */ + static void silentlyClose(Closeable closeable) + { + try + { + if (closeable != null) { + closeable.close(); + } + } + catch (IOException e) + { + // Ignore + } + } + + /************************************************************************* + * @param input + * @return + * @throws XmlParseException + ************************************************************************/ + + private static Dict parse(InputSource input) + throws XmlParseException { + try { + DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + documentBuilder.setEntityResolver(new EmptyXMLResolver()); + Document doc = documentBuilder.parse(input); + Element element = doc.getDocumentElement(); + return PLIST.parse(element); + } catch (ParserConfigurationException e) { + throw new XmlParseException("Error reading input", e); + } catch (SAXException e) { + throw new XmlParseException("Error reading input", e); + } catch (IOException e) { + throw new XmlParseException("Error reading input", e); + } + } + + /** + * Create a nested {@code map<String, Object>} from a plist xml file using the default mapping. + * + * @param file the File containing the the plist xml. + * @return the resulting map as read from the plist data. + * @throws XmlParseException if the plist could not be properly parsed. + * @throws IOException if there was an issue reading the plist file. + */ + public static Dict load(File file) throws XmlParseException, IOException + { + FileInputStream byteStream = new FileInputStream(file); + try { + InputSource input = new InputSource(byteStream); + return parse(input); + } finally { + silentlyClose(byteStream); + } + } + + /** + * Create a plist handler. + */ + PListParser() + { + this.m_dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + this.m_dateFormat.setTimeZone(TimeZone.getTimeZone("Z")); + this.m_simpleTypes = new HashMap<Class<?>, ElementType>(); + this.m_simpleTypes.put(Integer.class, ElementType.INTEGER); + this.m_simpleTypes.put(Byte.class, ElementType.INTEGER); + this.m_simpleTypes.put(Short.class, ElementType.INTEGER); + this.m_simpleTypes.put(Short.class, ElementType.INTEGER); + this.m_simpleTypes.put(Long.class, ElementType.INTEGER); + this.m_simpleTypes.put(String.class, ElementType.STRING); + this.m_simpleTypes.put(Float.class, ElementType.REAL); + this.m_simpleTypes.put(Double.class, ElementType.REAL); + this.m_simpleTypes.put(byte[].class, ElementType.DATA); + this.m_simpleTypes.put(Boolean.class, ElementType.TRUE); + this.m_simpleTypes.put(Date.class, ElementType.DATE); + } + + /** + * Parses a plist top element into a map dictionary containing all the data + * in the plist. + * + * @param element the top plist element. + * @return the resulting data tree structure. + * @throws XmlParseException if there was any error parsing the xml. + */ + Dict parse(Element element) throws XmlParseException + { + if (!"plist".equalsIgnoreCase(element.getNodeName())) { + throw new XmlParseException("Expected plist top element, was: " + element.getNodeName()); + } + + Node n = element.getFirstChild(); + while (n != null && !n.getNodeName().equals("dict")) { + n = n.getNextSibling(); + } + + Dict result = (Dict) parseElement(n); + return result; + } + + /** + * Parses a (non-top) xml element. + * + * @param element the element to parse. + * @return the resulting object. + * @throws XmlParseException if there was some error in the xml. + */ + private Object parseElement(Node element) throws XmlParseException + { + try + { + return parseElementRaw(element); + } + catch (Exception e) + { + throw new XmlParseException("Failed to parse: " + element.getNodeName(), e); + } + } + + + /** + * Parses a (non-top) xml element. + * + * @param element the element to parse. + * @return the resulting object. + * @throws ParseException if there was some error parsing the xml. + */ + private Object parseElementRaw(Node element) throws ParseException + { + ElementType type = ElementType.valueOf(element.getNodeName().toUpperCase()); + switch (type) + { + case INTEGER: + return parseInt(getValue(element)); + case REAL: + return Double.valueOf(getValue(element)); + case STRING: + return getValue(element); + case DATE: + return this.m_dateFormat.parse(getValue(element)); + case DATA: + return base64decode(getValue(element)); + case ARRAY: + return parseArray(element.getChildNodes()); + case TRUE: + return Boolean.TRUE; + case FALSE: + return Boolean.FALSE; + case DICT: + return parseDict(element.getChildNodes()); + default: + throw new RuntimeException("Unexpected type: " + element.getNodeName()); + } + } + + /************************************************************************* + * @param n + * @return + ************************************************************************/ + + private String getValue(Node n) { + StringBuilder sb = new StringBuilder(); + Node c = n.getFirstChild(); + while (c != null) { + if (c.getNodeType() == Node.TEXT_NODE) { + sb.append(c.getNodeValue()); + } + c = c.getNextSibling(); + } + return sb.toString(); + } + + /** + * Parses a string into a Long or Integer depending on size. + * + * @param value the value as a string. + * @return the long value of this string is the value doesn't fit in an integer, + * otherwise the int value of the string. + */ + private Number parseInt(String value) + { + Long l = Long.valueOf(value); + if (l.intValue() == l) { + return l.intValue(); + } + return l; + } + + /** + * Parse a list of xml elements as a plist dict. + * + * @param elements the elements to parse. + * @return the dict deserialized as a map. + * @throws ParseException if there are any problems deserializing the map. + */ + private Dict parseDict(NodeList elements) throws ParseException + { + Dict dict = new Dict(); + for (int i = 0; i < elements.getLength(); i++) { + Node key = elements.item(i); + if (key.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + if (!"key".equals(key.getNodeName())) { + throw new ParseException("Expected key but was " + key.getNodeName(), -1); + } + i++; + Node value = elements.item(i); + while (value.getNodeType() != Node.ELEMENT_NODE) { + i++; + value = elements.item(i); + } + Object o = parseElementRaw(value); + String dictName = getValue(key); + dict.children.put(dictName, o); + } + return dict; + } + + /** + * Parse a list of xml elements as a plist array. + * + * @param elements the elements to parse. + * @return the array deserialized as a list. + * @throws ParseException if there are any problems deserializing the list. + */ + private List<Object> parseArray(NodeList elements) throws ParseException + { + ArrayList<Object> list = new ArrayList<Object>(); + for (int i = 0; i < elements.getLength(); i++) { + Node o = elements.item(i); + if (o.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + list.add(parseElementRaw(o)); + } + return list; + } + + /** + * Encode an array of bytes to a string using base64 encoding. + * + * @param bytes the bytes to convert. + * @return the base64 representation of the bytes. + */ + static String base64encode(byte[] bytes) + { + StringBuilder builder = new StringBuilder(((bytes.length + 2)/ 3) * 4); + for (int i = 0; i < bytes.length; i += 3) + { + byte b0 = bytes[i]; + byte b1 = i < bytes.length - 1 ? bytes[i + 1] : 0; + byte b2 = i < bytes.length - 2 ? bytes[i + 2] : 0; + builder.append(BASE64_CHARS[(b0 & 0xFF) >> 2]); + builder.append(BASE64_CHARS[((b0 & 0x03) << 4) | ((b1 & 0xF0) >> 4)]); + builder.append(i < bytes.length - 1 ? BASE64_CHARS[((b1 & 0x0F) << 2) | ((b2 & 0xC0) >> 6)] : "="); + builder.append(i < bytes.length - 2 ? BASE64_CHARS[b2 & 0x3F] : "="); + } + return builder.toString(); + } + + /** + * Converts a string to a byte array assuming the string uses base64-encoding. + * + * @param base64 the string to convert. + * @return the resulting byte array. + */ + static byte[] base64decode(String base64) + { + base64 = base64.trim(); + int endTrim = base64.endsWith("==") ? 2 : base64.endsWith("=") ? 1 : 0; + int length = (base64.length() / 4) * 3 - endTrim; + base64 = base64.replace('=', 'A'); + byte[] result = new byte[length]; + int stringLength = base64.length(); + int index = 0; + for (int i = 0; i < stringLength; i += 4) + { + int i0 = BASE64_STRING.indexOf(base64.charAt(i)); + int i1 = BASE64_STRING.indexOf(base64.charAt(i + 1)); + int i2 = BASE64_STRING.indexOf(base64.charAt(i + 2)); + int i3 = BASE64_STRING.indexOf(base64.charAt(i + 3)); + byte b0 = (byte) ((i0 << 2) | (i1 >> 4)); + byte b1 = (byte) ((i1 << 4) | (i2 >> 2)); + byte b2 = (byte) ((i2 << 6) | i3); + result[index++] = b0; + if (index < length) + { + result[index++] = b1; + if (index < length) + { + result[index++] = b2; + } + } + } + return result; + } + + + + +} + diff --git a/src/main/java/com/btr/proxy/util/PlatformUtil.java b/src/main/java/com/btr/proxy/util/PlatformUtil.java new file mode 100644 index 0000000..39de5d2 --- /dev/null +++ b/src/main/java/com/btr/proxy/util/PlatformUtil.java @@ -0,0 +1,114 @@ +package com.btr.proxy.util; + +import com.btr.proxy.util.Logger.LogLevel; + +/***************************************************************************** + * Defines some helper methods to find the correct platform. + * + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + +public class PlatformUtil { + + public enum Platform {WIN, LINUX, MAC_OS, SOLARIS, OTHER} + public enum Desktop {WIN, KDE, GNOME, MAC_OS, OTHER} + public enum Browser {IE, FIREFOX} + + /************************************************************************* + * Gets the platform we are currently running on. + * @return a platform code. + ************************************************************************/ + + public static Platform getCurrentPlattform() { + String osName = System.getProperty("os.name"); + Logger.log(PlatformUtil.class, LogLevel.TRACE, "Detecting platform. Name is: {0}", osName); + + if (osName.toLowerCase().contains("windows")) { + Logger.log(PlatformUtil.class, LogLevel.TRACE, "Detected Windows platform: {0}", osName); + return Platform.WIN; + } + if (osName.toLowerCase().contains("linux")) { + Logger.log(PlatformUtil.class, LogLevel.TRACE, "Detected Linux platform: {0}", osName); + return Platform.LINUX; + } + if (osName.startsWith("Mac OS")) { + Logger.log(PlatformUtil.class, LogLevel.TRACE, "Detected Mac OS platform: {0}", osName); + return Platform.MAC_OS; + } + if (osName.startsWith("SunOS")) { + Logger.log(PlatformUtil.class, LogLevel.TRACE, "Detected Solaris platform: {0}", osName); + return Platform.SOLARIS; + } + + return Platform.OTHER; + } + + /************************************************************************* + * Gets the ID for the platform default browser. + * @return a browser ID, null if no supported browser was detected. + ************************************************************************/ + + public static Browser getDefaultBrowser() { + // Use better logic to detect default browser? + if (getCurrentPlattform() == Platform.WIN) { + Logger.log(PlatformUtil.class, LogLevel.TRACE, "Detected Browser is InternetExplorer"); + return Browser.IE; + } else { + Logger.log(PlatformUtil.class, LogLevel.TRACE, "Detected Browser Firefox. Fallback?"); + return Browser.FIREFOX; + } + } + + /************************************************************************* + * Gets the desktop that we are running on. + * @return the desktop identifier. + ************************************************************************/ + + public static Desktop getCurrentDesktop() { + Platform platf = getCurrentPlattform(); + + if (platf == Platform.WIN) { + Logger.log(PlatformUtil.class, LogLevel.TRACE, "Detected Windows desktop"); + return Desktop.WIN; + } + if (platf == Platform.MAC_OS) { + Logger.log(PlatformUtil.class, LogLevel.TRACE, "Detected Mac OS desktop"); + return Desktop.MAC_OS; + } + + if (platf == Platform.LINUX + || platf == Platform.SOLARIS + || platf == Platform.OTHER) { + + if (isKDE()) { + Logger.log(PlatformUtil.class, LogLevel.TRACE, "Detected KDE desktop"); + return Desktop.KDE; + } + if (isGnome()) { + Logger.log(PlatformUtil.class, LogLevel.TRACE, "Detected Gnome desktop"); + return Desktop.GNOME; + } + } + Logger.log(PlatformUtil.class, LogLevel.TRACE, "Detected Unknown desktop"); + return Desktop.OTHER; + } + + /************************************************************************* + * Checks if we are currently running under Gnome desktop. + * @return true if it is a Gnome else false. + ************************************************************************/ + + private static boolean isGnome() { + return System.getenv("GNOME_DESKTOP_SESSION_ID") != null; + } + + /************************************************************************* + * Checks if we are currently running under KDE desktop. + * @return true if it is a KDE else false. + ************************************************************************/ + + private static boolean isKDE() { + return System.getenv("KDE_SESSION_VERSION") != null; + } + +} diff --git a/src/main/java/com/btr/proxy/util/ProxyException.java b/src/main/java/com/btr/proxy/util/ProxyException.java new file mode 100644 index 0000000..a3c1424 --- /dev/null +++ b/src/main/java/com/btr/proxy/util/ProxyException.java @@ -0,0 +1,50 @@ +package com.btr.proxy.util; + +/***************************************************************************** + * Indicates an exception in the proxy framework. + * + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + +public class ProxyException extends Exception { + + private static final long serialVersionUID = 1L; + + /************************************************************************* + * Constructor + ************************************************************************/ + + public ProxyException() { + super(); + } + + /************************************************************************* + * Constructor + * @param message the error message + * @param cause the causing exception for chaining exceptions. + ************************************************************************/ + + public ProxyException(String message, Throwable cause) { + super(message, cause); + } + + /************************************************************************* + * Constructor + * @param message the error message + ************************************************************************/ + + public ProxyException(String message) { + super(message); + } + + /************************************************************************* + * Constructor + * @param cause the causing exception for chaining exceptions. + ************************************************************************/ + + public ProxyException(Throwable cause) { + super(cause); + } + + +} diff --git a/src/main/java/com/btr/proxy/util/ProxyUtil.java b/src/main/java/com/btr/proxy/util/ProxyUtil.java new file mode 100644 index 0000000..aad9293 --- /dev/null +++ b/src/main/java/com/btr/proxy/util/ProxyUtil.java @@ -0,0 +1,84 @@ +package com.btr.proxy.util; + +import java.net.Proxy; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.btr.proxy.selector.fixed.FixedProxySelector; +import com.btr.proxy.selector.pac.PacProxySelector; +import com.btr.proxy.selector.pac.PacScriptSource; +import com.btr.proxy.selector.pac.UrlPacScriptSource; + +/***************************************************************************** + * Small helper class for some common utility methods. + * + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + +public class ProxyUtil { + + public static final int DEFAULT_PROXY_PORT = 80; + + private static List<Proxy> noProxyList; + private static Pattern pattern = Pattern.compile("\\w*?:?/*([^:/]+):?(\\d*)/?"); + + /************************************************************************* + * Parse host and port out of a proxy variable. + * @param proxyVar the proxy string. example: http://192.168.10.9:8080/ + * @return a FixedProxySelector using this settings, null on parse error. + ************************************************************************/ + + public static FixedProxySelector parseProxySettings(String proxyVar) { + if (proxyVar == null || proxyVar.trim().length() == 0) { + return null; + } + Matcher matcher = pattern.matcher(proxyVar); + if (matcher.matches()) { + String host = matcher.group(1); + int port; + if (!"".equals(matcher.group(2))) { + port = Integer.parseInt(matcher.group(2)); + } else { + port = DEFAULT_PROXY_PORT; + } + return new FixedProxySelector(host.trim(), port); + } else { + return null; + } + } + + /************************************************************************* + * Gets an unmodifiable proxy list that will have as it's only entry an DIRECT proxy. + * @return a list with a DIRECT proxy in it. + ************************************************************************/ + + public static synchronized List<Proxy> noProxyList() { + if (noProxyList == null) { + ArrayList<Proxy> list = new ArrayList<Proxy>(1); + list.add(Proxy.NO_PROXY); + noProxyList = Collections.unmodifiableList(list); + } + return noProxyList; + } + + /************************************************************************* + * Build a PAC proxy selector for the given URL. + * @param url to fetch the PAC script from. + * @return a PacProxySelector or null if it is not possible to build a working + * selector. + ************************************************************************/ + + public static PacProxySelector buildPacSelectorForUrl(String url) { + PacProxySelector result = null; + PacScriptSource pacSource = new UrlPacScriptSource(url); + if (pacSource.isScriptValid()) { + result = new PacProxySelector(pacSource); + } + return result; + } + + +} diff --git a/src/main/java/com/btr/proxy/util/UriFilter.java b/src/main/java/com/btr/proxy/util/UriFilter.java new file mode 100644 index 0000000..8145e0e --- /dev/null +++ b/src/main/java/com/btr/proxy/util/UriFilter.java @@ -0,0 +1,21 @@ +package com.btr.proxy.util; + +import java.net.URI; + +/***************************************************************************** + * Interface for an URI filter. + * + * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009 + ****************************************************************************/ + +public interface UriFilter { + + /************************************************************************* + * Tests an URI against a given matching criteria. + * @param uri the URI to test. + * @return true if it matches the criteria else false. + ************************************************************************/ + + public abstract boolean accept(URI uri); + +} |