View Javadoc

1   package com.atlassian.sal.core.net;
2   
3   import java.net.URI;
4   import java.net.URISyntaxException;
5   
6   import org.apache.commons.httpclient.HttpClient;
7   import org.apache.commons.httpclient.UsernamePasswordCredentials;
8   import org.apache.commons.httpclient.auth.AuthScope;
9   import org.apache.commons.lang.StringUtils;
10  import org.slf4j.Logger;
11  import org.slf4j.LoggerFactory;
12  
13  /**
14   * Configures the proxy on the HttpClient instance, reads the proxy configuration
15   * from the following system properties:
16   *
17   *<ul>
18   *     <li><b>http.proxyHost</b></li>
19   *     <li><b>http.proxyPort</b> (optional, default to 80)</li>
20   *</ul>
21   * A list of excluded hosts can be provided to bypass the proxy:
22   *<ul>
23   *     <li><b>http.nonProxyHosts</b> (format: www.atlassian.com|*.example.com) - The only wildcard supported is the simple suffix match.</li>
24   *</ul>
25   * If the proxy needs authentication, the credentials must be provided using:
26   *<ul>
27   *     <li><b>http.proxyUser</b></li>
28   *     <li><b>http.proxyPassword</b></li>
29   *</ul>
30   */
31  public class HttpClientProxyConfig
32  {
33  
34      private static final Logger log = LoggerFactory.getLogger(HttpClientProxyConfig.class);
35  
36      /**
37       * @param client The client to configure the proxy of
38       * @param remoteUrl The remote URL
39       */
40      protected void configureProxy(final HttpClient client, final String remoteUrl)
41      {
42          if (client == null)
43          {
44              throw new IllegalArgumentException("Please provide a valid HttpClient instance");
45          }
46          final String proxyHost = System.getProperty("http.proxyHost");
47  
48          URI uri;
49          try
50          {
51              uri = new URI(remoteUrl);
52          } catch (final URISyntaxException e)
53          {
54              log.warn("Invalid url: " + remoteUrl, e);
55              return;
56          }
57          if (!StringUtils.isBlank(proxyHost) && !isNonProxyHost(uri.getHost()))
58          {
59              int port = 80;
60              try
61              {
62                  port = Integer.parseInt(System.getProperty("http.proxyPort", "80"));
63              }
64              catch (final NumberFormatException e)
65              {
66                  log.warn("System property 'http.proxyPort' is not a number. Defaulting to 80.");
67              }
68  
69              client.getHostConfiguration().setProxy(proxyHost, port);
70              if(proxyAuthenticationRequired())
71              {
72                  client.getState().setProxyCredentials(new AuthScope(proxyHost,port),
73                          new UsernamePasswordCredentials(System.getProperty("http.proxyUser"),
74                                  System.getProperty("http.proxyPassword")));
75              }
76          }
77      }
78  
79      /**
80       * Discover whether or not proxy authentication is required; if we are behind a proxy then it is required,
81       * otherwise it isn't
82       *
83       * @return true if proxy authentication is required, false otherwise
84       */
85      private boolean proxyAuthenticationRequired()
86      {
87          return System.getProperty("http.proxyUser") != null;
88      }
89  
90      private boolean isNonProxyHost(final String host)
91      {
92          if (StringUtils.isBlank(host))
93          {
94              return true;
95          }
96          final String httpNonProxyHosts = System.getProperty("http.nonProxyHosts");
97          if (StringUtils.isBlank(httpNonProxyHosts))
98          {
99              // checking if property was misspelt, notice there is no 's' at the end of this property
100             if (StringUtils.isBlank(System.getProperty("http.nonProxyHost")))
101             {
102                 log.warn("The system property http.nonProxyHost is set. You probably meant to set http.nonProxyHosts.");
103             }
104             return false;
105         }
106         final String[] nonProxyHosts = httpNonProxyHosts.split("\\|");
107         for (final String nonProxyHost : nonProxyHosts) {
108             if (nonProxyHost.startsWith("*")) {
109                 if (host.endsWith(nonProxyHost.substring(1))) {
110                     return true;
111                 }
112             } else if (host.equals(nonProxyHost)) {
113                 return true;
114             }
115         }
116         return false;
117     }
118 
119 }