1 package com.atlassian.sal.core.net;
2
3 import java.net.URI;
4 import java.net.URISyntaxException;
5
6 import com.atlassian.sal.api.net.NonMarshallingRequestFactory;
7 import org.apache.commons.httpclient.HttpClient;
8 import org.apache.commons.httpclient.UsernamePasswordCredentials;
9 import org.apache.commons.httpclient.auth.AuthScope;
10 import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
11 import org.apache.commons.lang.StringUtils;
12 import org.apache.log4j.Logger;
13
14 import com.atlassian.sal.api.net.Request.MethodType;
15 import com.atlassian.sal.api.user.UserManager;
16 import com.atlassian.sal.core.trusted.CertificateFactory;
17
18
19
20
21
22 public class HttpClientRequestFactory implements NonMarshallingRequestFactory<HttpClientRequest>
23 {
24 private static final Logger log = Logger.getLogger(HttpClientRequestFactory.class);
25
26 private final CertificateFactory certificateFactory;
27 private final UserManager userManager;
28
29 public HttpClientRequestFactory(final CertificateFactory certificateFactory, final UserManager userManager)
30 {
31 this.certificateFactory = certificateFactory;
32 this.userManager = userManager;
33 }
34
35
36
37
38 public static final int DEFAULT_SOCKET_TIMEOUT=Integer.parseInt(System.getProperty("http.socketTimeout", "10000"));
39
40
41
42
43 public static final int DEFAULT_CONNECTION_TIMEOUT=Integer.parseInt(System.getProperty("http.connectionTimeout", "10000"));
44
45
46
47
48 public HttpClientRequest createRequest(final MethodType methodType, final String url)
49 {
50 final HttpClient httpClient = getHttpClient(url);
51 return new HttpClientRequest(httpClient, methodType, url, certificateFactory, userManager);
52 }
53
54
55
56
57
58 protected HttpClient getHttpClient(final String url)
59 {
60 final HttpClient httpClient = new HttpClient();
61 configureProxy(httpClient, url);
62 configureConnectionParameters(httpClient);
63 return httpClient;
64 }
65
66
67
68
69
70
71 protected void configureConnectionParameters(final HttpClient httpClient)
72 {
73 final HttpConnectionManagerParams params = httpClient.getHttpConnectionManager().getParams();
74 params.setSoTimeout(DEFAULT_SOCKET_TIMEOUT);
75 params.setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT);
76 }
77
78
79
80
81
82 protected void configureProxy(final HttpClient client, final String remoteUrl)
83 {
84 final String proxyHost = System.getProperty("http.proxyHost");
85
86 URI uri;
87 try
88 {
89 uri = new URI(remoteUrl);
90 } catch (final URISyntaxException e)
91 {
92 log.warn("Invalid url: " + remoteUrl, e);
93 return;
94 }
95 if (proxyHost != null && !isNonProxyHost(uri.getHost()))
96 {
97 int port = 80;
98 try
99 {
100 port = Integer.parseInt(System.getProperty("http.proxyPort", "80"));
101 }
102 catch (final NumberFormatException e)
103 {
104 log.warn("System property 'http.proxyPort' is not a number. Defaulting to 80.");
105 }
106
107 client.getHostConfiguration().setProxy(proxyHost, port);
108 if(proxyAuthenticationRequired())
109 {
110 client.getState().setProxyCredentials(new AuthScope(proxyHost,port),
111 new UsernamePasswordCredentials(System.getProperty("http.proxyUser"),
112 System.getProperty("http.proxyPassword")));
113 }
114 }
115 }
116
117
118
119
120
121
122
123 private boolean proxyAuthenticationRequired()
124 {
125 return System.getProperty("http.proxyUser") != null;
126 }
127
128 private boolean isNonProxyHost(final String host)
129 {
130 final String httpNonProxyHosts = System.getProperty("http.nonProxyHosts");
131 if (StringUtils.isBlank(httpNonProxyHosts))
132 {
133
134 if (StringUtils.isBlank(System.getProperty("http.nonProxyHost")))
135 {
136 log.warn("The system property http.nonProxyHost is set. You probably meant to set http.nonProxyHosts.");
137 }
138 return false;
139 }
140 final String[] nonProxyHosts = httpNonProxyHosts.split("\\|");
141 for (final String nonProxyHost : nonProxyHosts) {
142 if (nonProxyHost.startsWith("*")) {
143 if (host.endsWith(nonProxyHost.substring(1))) {
144 return true;
145 }
146 } else if (host.equals(nonProxyHost)) {
147 return true;
148 }
149 }
150 return false;
151 }
152
153 public boolean supportsHeader()
154 {
155 return true;
156 }
157 }