View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.vfs2.provider.http;
18  
19  import org.apache.commons.httpclient.Cookie;
20  import org.apache.commons.httpclient.HostConfiguration;
21  import org.apache.commons.httpclient.HttpClient;
22  import org.apache.commons.httpclient.HttpConnectionManager;
23  import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
24  import org.apache.commons.httpclient.UsernamePasswordCredentials;
25  import org.apache.commons.httpclient.auth.AuthScope;
26  import org.apache.commons.httpclient.params.HttpClientParams;
27  import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
28  import org.apache.commons.lang3.StringUtils;
29  import org.apache.commons.lang3.time.DurationUtils;
30  import org.apache.commons.vfs2.FileSystemException;
31  import org.apache.commons.vfs2.FileSystemOptions;
32  import org.apache.commons.vfs2.UserAuthenticationData;
33  import org.apache.commons.vfs2.UserAuthenticator;
34  import org.apache.commons.vfs2.util.UserAuthenticatorUtils;
35  
36  /**
37   * Create a HttpClient instance.
38   */
39  public final class HttpClientFactory {
40  
41      /**
42       * Creates a new connection to the server.
43       *
44       * @param builder The HttpFileSystemConfigBuilder.
45       * @param scheme The protocol.
46       * @param hostname The hostname.
47       * @param port The port number.
48       * @param username The username.
49       * @param password The password
50       * @param fileSystemOptions The file system options.
51       * @return a new HttpClient connection.
52       * @throws FileSystemException if an error occurs.
53       * @since 2.0
54       */
55      public static HttpClient createConnection(final HttpFileSystemConfigBuilder builder, final String scheme,
56              final String hostname, final int port, final String username, final String password,
57          final FileSystemOptions fileSystemOptions) throws FileSystemException {
58          final HttpClient client;
59          try {
60              final HttpConnectionManager mgr = new MultiThreadedHttpConnectionManager();
61              final HttpConnectionManagerParams connectionMgrParams = mgr.getParams();
62  
63              client = new HttpClient(mgr);
64  
65              final HostConfiguration config = new HostConfiguration();
66              config.setHost(hostname, port, scheme);
67  
68              if (fileSystemOptions != null) {
69                  final String proxyHost = builder.getProxyHost(fileSystemOptions);
70                  final int proxyPort = builder.getProxyPort(fileSystemOptions);
71  
72                  if (!StringUtils.isEmpty(proxyHost) && proxyPort > 0) {
73                      config.setProxy(proxyHost, proxyPort);
74                  }
75  
76                  final UserAuthenticator proxyAuth = builder.getProxyAuthenticator(fileSystemOptions);
77                  if (proxyAuth != null) {
78                      final UserAuthenticationData authData = UserAuthenticatorUtils.authenticate(proxyAuth,
79                          new UserAuthenticationData.Type[] {UserAuthenticationData.USERNAME,
80                              UserAuthenticationData.PASSWORD});
81  
82                      if (authData != null) {
83                          final UsernamePasswordCredentials proxyCreds = new UsernamePasswordCredentials(
84                              UserAuthenticatorUtils.toString(
85                                  UserAuthenticatorUtils.getData(authData, UserAuthenticationData.USERNAME, null)),
86                              UserAuthenticatorUtils.toString(
87                                  UserAuthenticatorUtils.getData(authData, UserAuthenticationData.PASSWORD, null)));
88  
89                          final AuthScope scope = new AuthScope(proxyHost, AuthScope.ANY_PORT);
90                          client.getState().setProxyCredentials(scope, proxyCreds);
91                      }
92  
93                      if (builder.isPreemptiveAuth(fileSystemOptions)) {
94                          final HttpClientParams httpClientParams = new HttpClientParams();
95                          httpClientParams.setAuthenticationPreemptive(true);
96                          client.setParams(httpClientParams);
97                      }
98                  }
99  
100                 final Cookie[] cookies = builder.getCookies(fileSystemOptions);
101                 if (cookies != null) {
102                     client.getState().addCookies(cookies);
103                 }
104             }
105             /*
106              * ConnectionManager set methods must be called after the host & port and proxy host & port are set in the
107              * HostConfiguration. They are all used as part of the key when HttpConnectionManagerParams tries to locate
108              * the host configuration.
109              */
110             connectionMgrParams.setMaxConnectionsPerHost(config, builder.getMaxConnectionsPerHost(fileSystemOptions));
111             connectionMgrParams.setMaxTotalConnections(builder.getMaxTotalConnections(fileSystemOptions));
112 
113             connectionMgrParams.setConnectionTimeout(
114                 DurationUtils.toMillisInt(builder.getConnectionTimeoutDuration(fileSystemOptions)));
115             connectionMgrParams
116                 .setSoTimeout(DurationUtils.toMillisInt(builder.getSoTimeoutDuration(fileSystemOptions)));
117 
118             client.setHostConfiguration(config);
119 
120             if (username != null) {
121                 final UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
122                 final AuthScope scope = new AuthScope(hostname, AuthScope.ANY_PORT);
123                 client.getState().setCredentials(scope, creds);
124             }
125         } catch (final Exception exc) {
126             throw new FileSystemException("vfs.provider.http/connect.error", exc, hostname);
127         }
128 
129         return client;
130     }
131 
132     public static HttpClient createConnection(final String scheme, final String hostname, final int port,
133             final String username, final String password, final FileSystemOptions fileSystemOptions)
134             throws FileSystemException {
135         return createConnection(HttpFileSystemConfigBuilder.getInstance(), scheme, hostname, port, username, password,
136                 fileSystemOptions);
137     }
138 
139     private HttpClientFactory() {
140     }
141 
142 }