summaryrefslogtreecommitdiffstats
path: root/src/main/java/com/btr/proxy/search/java/JavaProxySearchStrategy.java
blob: f1853b75fc0334970cfd6830ca555d42df889a0f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package com.btr.proxy.search.java;

import java.net.Proxy;
import java.net.ProxySelector;

import com.btr.proxy.search.ProxySearchStrategy;
import com.btr.proxy.selector.fixed.FixedProxySelector;
import com.btr.proxy.selector.misc.ProtocolDispatchSelector;
import com.btr.proxy.selector.whitelist.ProxyBypassListSelector;
import com.btr.proxy.util.Logger;
import com.btr.proxy.util.Logger.LogLevel;

/*****************************************************************************
 * Reads some java system properties and extracts the proxy settings from them.
 * The following variables are read:
 * <ul>
 * <li><i>http.proxyHost</i> (default: none)</li>
 * <li><i>http.proxyPort</i> (default: 80 if http.proxyHost specified)</li>
 * <li><i>http.nonProxyHosts</i> (default: none)</li>
 * </ul>
 * <ul>
 * <li><i>https.proxyHost</i> (default: none)</li>
 * <li><i>https.proxyPort</i> (default: 443 if https.proxyHost specified)</li>
 * </ul>
 * <ul>
 * <li><i>ftp.proxyHost</i> (default: none)</li>
 * <li><i>ftp.proxyPort</i> (default: 80 if ftp.proxyHost specified)</li>
 * <li><i>ftp.nonProxyHosts</i> (default: none)</li> 
 * </ul>
 * <ul>
 * <li><i>socksProxyHost</i></li>
 * <li><i>socksProxyPort</i> (default: 1080)</li>
 * </ul>
 * <p>
 * This is based on information found here: <br/>
 * http://download.oracle.com/javase/6/docs/technotes/guides/net/proxies.html
 * </p>
 * If the "http.proxyHost" property is not set then the no proxy selector is setup
 * This property is used as marker to signal that the System settings should be used. 
 *  
 * @author Bernd Rosstauscher (proxyvole@rosstauscher.de) Copyright 2009
 ****************************************************************************/

public class JavaProxySearchStrategy implements ProxySearchStrategy {
	
	/*************************************************************************
	 * Constructor
	 * Will use the default environment variables.
	 ************************************************************************/
	
	public JavaProxySearchStrategy() {
		super();
	}
	
	/*************************************************************************
	 * Loads the proxy settings from environment variables.
	 * @return a configured ProxySelector, null if none is found.
	 ************************************************************************/

	public ProxySelector getProxySelector() {
		ProtocolDispatchSelector ps = new ProtocolDispatchSelector();
		
		if (!proxyPropertyPresent()) {
			return null;
		}
		Logger.log(getClass(), LogLevel.TRACE, "Using settings from Java System Properties");
		
		
		setupProxyForProtocol(ps, "http", 80);
		setupProxyForProtocol(ps, "https", 443);
		setupProxyForProtocol(ps, "ftp", 80);
		setupProxyForProtocol(ps, "ftps", 80);
		setupSocktProxy(ps);
		
		return ps;
	}

	/*************************************************************************
	 * @return true if the http.proxyHost is available as system property.
	 ************************************************************************/
	
	private boolean proxyPropertyPresent() {
		return System.getProperty("http.proxyHost") != null 
				&& System.getProperty("http.proxyHost").trim().length() > 0;
	}

	/*************************************************************************
	 * Parse SOCKS settings
	 * @param ps
	 * @throws NumberFormatException
	 ************************************************************************/
	
	
	private void setupSocktProxy(ProtocolDispatchSelector ps) {
		String host = System.getProperty("socksProxyHost");
		String port = System.getProperty("socksProxyPort", "1080");
		if (host != null && host.trim().length() > 0) {
			Logger.log(getClass(), LogLevel.TRACE, "Socks proxy {0}:{1} found", host, port);
			ps.setSelector("socks", new FixedProxySelector(Proxy.Type.SOCKS, host, Integer.parseInt(port)));
		}
	}

	/*************************************************************************
	 * Parse properties for the given protocol.
	 * @param ps
	 * @param protocol
	 * @throws NumberFormatException
	 ************************************************************************/
	
	private void setupProxyForProtocol(ProtocolDispatchSelector ps, String protocol, int defaultPort) {
		String host = System.getProperty(protocol+".proxyHost");
		String port = System.getProperty(protocol+".proxyPort", ""+defaultPort);
		String whiteList = System.getProperty(protocol+".nonProxyHosts", "").replace('|', ',');
		
		if ("https".equalsIgnoreCase(protocol)) { // This is dirty but https has no own property for it.
			whiteList = System.getProperty("http.nonProxyHosts", "").replace('|', ',');
		}

		if (host == null || host.trim().length() == 0) {
			return;
		}
		
		Logger.log(getClass(), LogLevel.TRACE, protocol.toUpperCase()+" proxy {0}:{1} found using whitelist: {2}", host, port, whiteList);
		
		ProxySelector protocolSelector = new FixedProxySelector(Proxy.Type.HTTP, host, Integer.parseInt(port));
		if (whiteList.trim().length() > 0) {
			protocolSelector = new ProxyBypassListSelector(whiteList, protocolSelector);
		}
	
		ps.setSelector(protocol, protocolSelector);
	}

}