View Javadoc

1   package com.atlassian.sal.core.net;
2   
3   import com.atlassian.sal.api.net.NonMarshallingRequestFactory;
4   import com.atlassian.sal.api.net.Request.MethodType;
5   import org.apache.http.HttpHeaders;
6   import org.apache.http.HttpHost;
7   import org.apache.http.auth.AuthScope;
8   import org.apache.http.auth.Credentials;
9   import org.apache.http.auth.MalformedChallengeException;
10  import org.apache.http.auth.UsernamePasswordCredentials;
11  import org.apache.http.client.AuthCache;
12  import org.apache.http.client.CredentialsProvider;
13  import org.apache.http.client.protocol.HttpClientContext;
14  import org.apache.http.conn.HttpClientConnectionManager;
15  import org.apache.http.conn.routing.HttpRoutePlanner;
16  import org.apache.http.impl.auth.BasicScheme;
17  import org.apache.http.impl.client.BasicCredentialsProvider;
18  import org.apache.http.impl.client.CloseableHttpClient;
19  import org.apache.http.impl.client.HttpClients;
20  import org.apache.http.message.BasicHeader;
21  import org.apache.http.protocol.HttpRequestExecutor;
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  
25  /**
26   * Does NOT support json/xml object marshalling. Use the atlassian-rest implementation of {@link
27   * com.atlassian.sal.api.net.RequestFactory} instead.
28   */
29  public class HttpClientRequestFactory implements NonMarshallingRequestFactory<HttpClientRequest<?, ?>> {
30      private static final Logger log = LoggerFactory.getLogger(HttpClientRequestFactory.class);
31  
32  
33      /* (non-Javadoc)
34       * @see com.atlassian.sal.api.net.RequestFactory#createMethod(com.atlassian.sal.api.net.Request.MethodType, java.lang.String)
35       */
36      public HttpClientRequest createRequest(final MethodType methodType, final String url) {
37          final ProxyConfig proxyConfig = new SystemPropertiesProxyConfig();
38          log.debug("Creating HttpClientRequest with proxy config:", proxyConfig);
39  
40          final CloseableHttpClient httpClient = createHttpClient(proxyConfig);
41          final HttpClientContext clientContext = createClientContext(proxyConfig);
42          return new HttpClientRequest(httpClient, clientContext, methodType, url);
43      }
44  
45      protected CloseableHttpClient createHttpClient(final ProxyConfig proxyConfig) {
46          return HttpClients.custom()
47                  .useSystemProperties()
48                  .setRoutePlanner(getRoutePlanner(proxyConfig))
49                  .setRequestExecutor(getRequestExecutor())
50                  .setConnectionManager(getConnectionManager())
51                  .build();
52      }
53  
54      protected HttpClientContext createClientContext(final ProxyConfig proxyConfig) {
55          final HttpClientContext httpClientContext = HttpClientContext.create();
56          final AuthCache authCache = new AllPortsAuthCache();
57          final CredentialsProvider basicCredentialsProvider = new BasicCredentialsProvider();
58  
59          if (proxyConfig.requiresAuthentication()) {
60              HttpHost proxyHost = new HttpHost(proxyConfig.getHost(), proxyConfig.getPort());
61              final AuthScope proxyAuthScope = new AuthScope(proxyHost);
62              final Credentials proxyCredentials = new UsernamePasswordCredentials(proxyConfig.getUser(),
63                      proxyConfig.getPassword());
64              basicCredentialsProvider.setCredentials(proxyAuthScope, proxyCredentials);
65  
66              // This ensures that proxy authentication is preemptive.
67              BasicScheme proxyScheme = new BasicScheme();
68              try {
69                  proxyScheme.processChallenge(
70                          new BasicHeader(HttpHeaders.PROXY_AUTHENTICATE, "Basic "));
71              } catch (MalformedChallengeException e) {
72                  throw new IllegalStateException(e);
73              }
74              authCache.put(proxyHost, proxyScheme);
75          }
76  
77          httpClientContext.setCredentialsProvider(basicCredentialsProvider);
78          httpClientContext.setAuthCache(authCache);
79          return httpClientContext;
80      }
81  
82      public boolean supportsHeader() {
83          return true;
84      }
85  
86      protected HttpRoutePlanner getRoutePlanner(ProxyConfig proxyConfig) {
87          return proxyConfig.isSet() ? new ProxyRoutePlanner(proxyConfig) : null;
88      }
89  
90      /**
91       * We can override the to override the request execution behaviour. This is useful for testing, but potentially
92       * also useful in other scenarious.
93       *
94       * @return HttpRequestExecutor
95       */
96      protected HttpRequestExecutor getRequestExecutor() {
97          return null;
98      }
99  
100     protected HttpClientConnectionManager getConnectionManager() {
101         return null;
102     }
103 
104 }