summaryrefslogtreecommitdiffstats
path: root/src/main/java/com/btr/proxy/search/wpad/WpadProxySearchStrategy.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/btr/proxy/search/wpad/WpadProxySearchStrategy.java')
-rw-r--r--src/main/java/com/btr/proxy/search/wpad/WpadProxySearchStrategy.java234
1 files changed, 234 insertions, 0 deletions
diff --git a/src/main/java/com/btr/proxy/search/wpad/WpadProxySearchStrategy.java b/src/main/java/com/btr/proxy/search/wpad/WpadProxySearchStrategy.java
new file mode 100644
index 0000000..cf01fd3
--- /dev/null
+++ b/src/main/java/com/btr/proxy/search/wpad/WpadProxySearchStrategy.java
@@ -0,0 +1,234 @@
+package com.btr.proxy.search.wpad;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.Socket;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.UnknownHostException;
+import java.util.List;
+import java.util.Properties;
+
+import com.btr.proxy.search.ProxySearchStrategy;
+import com.btr.proxy.util.Logger;
+import com.btr.proxy.util.Logger.LogLevel;
+import com.btr.proxy.util.ProxyException;
+import com.btr.proxy.util.ProxyUtil;
+
+
+/*****************************************************************************
+ * Uses automatic proxy script search (WPAD) to find an PAC file automatically.
+ * <p>
+ * Note: at the moment only the DNS name guessing schema is implemented.
+ * All others are missing.
+ * </p><p>
+ * For more information about WPAD:
+ * <a href="http://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol">Web_Proxy_Autodiscovery_Protocol</a>
+ * </p><p>
+ * Outdated RFC draft:
+ * <a href="http://www.web-cache.com/Writings/Internet-Drafts/draft-ietf-wrec-wpad-01.txt">draft-ietf-wrec-wpad-01.txt</a>
+ * </p>
+ * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009
+ ****************************************************************************/
+
+public class WpadProxySearchStrategy implements ProxySearchStrategy {
+
+ /*************************************************************************
+ * Constructor
+ ************************************************************************/
+
+ public WpadProxySearchStrategy() {
+ super();
+ }
+
+ /*************************************************************************
+ * Loads the proxy settings from a PAC file.
+ * The location of the PAC file is determined automatically.
+ * @return a configured ProxySelector, null if none is found.
+ * @throws ProxyException on error.
+ ************************************************************************/
+
+ public ProxySelector getProxySelector() throws ProxyException {
+ try {
+ Logger.log(getClass(), LogLevel.TRACE, "Using WPAD to find a proxy");
+
+ String pacScriptUrl = detectScriptUrlPerDHCP();
+ if (pacScriptUrl == null) {
+ pacScriptUrl = detectScriptUrlPerDNS();
+ }
+ if (pacScriptUrl == null) {
+ return null;
+ }
+ Logger.log(getClass(), LogLevel.TRACE, "PAC script url found: {0}", pacScriptUrl);
+ return ProxyUtil.buildPacSelectorForUrl(pacScriptUrl);
+ } catch (IOException e) {
+ Logger.log(getClass(), LogLevel.ERROR, "Error during WPAD search.", e);
+ throw new ProxyException(e);
+ }
+ }
+
+ /*************************************************************************
+ * Loads the settings and stores them in a properties map.
+ * @return the settings.
+ ************************************************************************/
+
+ public Properties readSettings() {
+ try {
+ String pacScriptUrl = detectScriptUrlPerDHCP();
+ if (pacScriptUrl == null) {
+ pacScriptUrl = detectScriptUrlPerDNS();
+ }
+ if (pacScriptUrl == null) {
+ return null;
+ }
+ Properties result = new Properties();
+ result.setProperty("url", pacScriptUrl);
+ return result;
+ } catch (IOException e) {
+ // Ignore and return empty properties.
+ return new Properties();
+ }
+ }
+
+ /*************************************************************************
+ * Uses DNS to find the script URL.
+ * Attention: this detection method is known to have some severe security issues.
+ * @return the URL, null if not found.
+ ************************************************************************/
+
+ private String detectScriptUrlPerDNS() throws IOException {
+ String result = null;
+ // String fqdn = InetAddress.getLocalHost().getCanonicalHostName();
+
+ Logger.log(getClass(), LogLevel.TRACE, "Searching per DNS guessing.");
+ // Logger.log(getClass(), LogLevel.INFO, "fqdn: ", fqdn);
+
+ /** Reading address from "/etc/resolv.conf"; file looks like:
+ *
+ # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
+ # DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
+ nameserver 127.0.1.1
+ search ruf.uni-freiburg.de lp.ruf.uni-freiburg.de
+ */
+
+ FileReader fr = new FileReader("/etc/resolv.conf");
+ BufferedReader br = new BufferedReader(fr);
+
+ String input;
+ String[] addresses = null;
+ // using the 4th line of the file.
+ while ((input = br.readLine()) != null) {
+ if (input.startsWith("search")) {
+ // the first one is "search" and afterwards addresses are following.
+ addresses = input.substring(6).split(" ");
+ break;
+ }
+ }
+
+ if (addresses == null) {
+ addresses = new String[]{""};
+ }
+
+
+ for (int i = 0; i < addresses.length; ++i) {
+ String address = addresses[i];
+ int index = -1;
+ do {
+ if (index != -1) {
+ address = address.substring(index);
+ } else {
+ address = "";
+ }
+
+ // Try to connect to URL
+ try {
+ address = ".uni-freiburg.de";
+ URL lookupURL = new URL("http://wpad"+ address +"/wpad.dat");
+ Logger.log(getClass(), LogLevel.TRACE, "Trying url: {0}", lookupURL);
+
+ HttpURLConnection con = (HttpURLConnection) lookupURL.openConnection(Proxy.NO_PROXY);
+ con.setInstanceFollowRedirects(true);
+ con.setRequestProperty("accept", "application/x-ns-proxy-autoconfig");
+ if (con.getResponseCode() == 200) {
+ result = lookupURL.toString();
+ return result;
+ }
+ con.disconnect();
+ } catch (UnknownHostException e) {
+ Logger.log(getClass(), LogLevel.DEBUG, "Not available!");
+ // Not a real error, try next address
+ }
+ if (address.length() == 0) {
+ break;
+ }
+ index = address.indexOf('.', 1);
+ } while (true);
+ }
+
+ return null;
+ }
+
+ /*************************************************************************
+ * Uses DHCP to find the script URL.
+ * @return the URL, null if not found.
+ ************************************************************************/
+
+ private String detectScriptUrlPerDHCP() {
+ Logger.log(getClass(), LogLevel.DEBUG, "Searching per DHCP not supported yet.");
+ // TODO Rossi 28.04.2009 Not implemented yet.
+ return null;
+ }
+
+ // Main method for testing.
+ public static void main( String[] args ) throws IOException {
+ WpadProxySearchStrategy wPSS = new WpadProxySearchStrategy();
+// System.setProperty("com.btr.proxy.pac.overrideLocalIP", "10.0.0.1");
+ try {
+ ProxySelector pS = wPSS.getProxySelector();
+ ProxySelector.setDefault(pS);
+ List<Proxy> proxyList = pS.select(new URI("http://www.google.de"));
+
+ if (proxyList.isEmpty()) {
+ Logger.log(WpadProxySearchStrategy.class, LogLevel.INFO, "ProxyList is empty!");
+ } else {
+ Logger.log(WpadProxySearchStrategy.class, LogLevel.INFO, "proxyList contains: {0}", proxyList.toString());
+ }
+ } catch (ProxyException e) {
+ // TODO bjoern 28.10.2014 Auto-generated catch block
+ e.printStackTrace();
+ } catch (URISyntaxException e) {
+ // TODO bjoern 28.10.2014 Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ URL test = new URL("http://www.google.de");
+ URLConnection uc = test.openConnection();
+ BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream()));
+
+ String inputLine;
+ while ((inputLine = br.readLine()) != null) {
+ System.out.println(inputLine);
+ }
+
+ Socket socket = new Socket("www.google.de", 80);
+ BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
+ bw.write("GET / HTTP/1.1\r\nHost: www.google.de\r\nConnection: close\r\nAccept-Encoding: *\r\n\r\n");
+ bw.flush();
+
+ br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ while ((inputLine = br.readLine()) != null) {
+ System.out.println(inputLine);
+ }
+
+ }
+
+}