1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.support.http;
14
15 import java.io.File;
16 import java.io.IOException;
17 import java.security.GeneralSecurityException;
18 import java.security.KeyManagementException;
19 import java.security.KeyStoreException;
20 import java.security.NoSuchAlgorithmException;
21 import java.security.cert.CertificateException;
22
23 import org.apache.commons.httpclient.Header;
24 import org.apache.commons.httpclient.HttpClient;
25 import org.apache.commons.httpclient.HttpMethod;
26 import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory;
27 import org.apache.commons.httpclient.protocol.Protocol;
28 import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
29 import org.apache.commons.ssl.KeyMaterial;
30 import org.apache.log4j.Logger;
31
32 import com.eviware.soapui.SoapUI;
33 import com.eviware.soapui.impl.wsdl.support.CompressionSupport;
34 import com.eviware.soapui.model.settings.Settings;
35 import com.eviware.soapui.model.settings.SettingsListener;
36 import com.eviware.soapui.settings.HttpSettings;
37 import com.eviware.soapui.settings.SSLSettings;
38 import com.eviware.soapui.support.StringUtils;
39
40 /***
41 * HttpClient related tools
42 *
43 * @author Ole.Matzura
44 */
45
46 public class HttpClientSupport
47 {
48 private final static Helper helper = new Helper();
49
50 /***
51 * Internal helper to ensure synchronized access..
52 */
53
54 private static class Helper
55 {
56 private HttpClient httpClient;
57 private final static Logger log = Logger.getLogger( HttpClientSupport.Helper.class );
58 private SoapUIEasySSLProtocolSocketFactory easySSL;
59 private SoapUIMultiThreadedHttpConnectionManager connectionManager;
60
61 public Helper()
62 {
63 try
64 {
65 easySSL = new SoapUIEasySSLProtocolSocketFactory();
66 initSSL( easySSL );
67
68 Protocol easyhttps = new Protocol( "https", ( ProtocolSocketFactory )easySSL, 443 );
69 Protocol.registerProtocol( "https", easyhttps );
70 }
71 catch( Throwable e )
72 {
73 SoapUI.log( e );
74 }
75
76 Settings settings = SoapUI.getSettings();
77
78 connectionManager = new SoapUIMultiThreadedHttpConnectionManager();
79 connectionManager.getParams().setDefaultMaxConnectionsPerHost(
80 ( int )settings.getLong( HttpSettings.MAX_CONNECTIONS_PER_HOST, 500 ) );
81 connectionManager.getParams().setMaxTotalConnections(
82 ( int )settings.getLong( HttpSettings.MAX_TOTAL_CONNECTIONS, 2000 ) );
83 httpClient = new HttpClient( connectionManager );
84
85 settings.addSettingsListener( new SSLSettingsListener() );
86 }
87
88 private void initSSL( EasySSLProtocolSocketFactory easySSL ) throws IOException, GeneralSecurityException
89 {
90 initKeyMaterial( easySSL );
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 }
113
114 private void initKeyMaterial( EasySSLProtocolSocketFactory easySSL ) throws IOException,
115 NoSuchAlgorithmException, KeyStoreException, KeyManagementException, CertificateException
116 {
117 Settings settings = SoapUI.getSettings();
118
119 String keyStore = settings.getString( SSLSettings.KEYSTORE, null );
120 keyStore = keyStore != null ? keyStore.trim() : "";
121 String pass = settings.getString( SSLSettings.KEYSTORE_PASSWORD, "" );
122 char[] pwd = pass.toCharArray();
123 if( !"".equals( keyStore ) )
124 {
125 log.info( "Initializing KeyStore" );
126
127 File f = new File( keyStore );
128 if( f.exists() )
129 {
130 KeyMaterial km = null;
131 try
132 {
133 km = new KeyMaterial( keyStore, pwd );
134 log.info( "Set KeyMaterial from file [" + keyStore + "]" );
135 }
136 catch( GeneralSecurityException gse )
137 {
138 SoapUI.logError( gse );
139 }
140 if( km != null )
141 {
142 easySSL.setKeyMaterial( km );
143 }
144 }
145 }
146 else
147 {
148 easySSL.setKeyMaterial( null );
149 }
150 }
151
152 public HttpClient getHttpClient()
153 {
154 return httpClient;
155 }
156
157 public final class SSLSettingsListener implements SettingsListener
158 {
159 public void settingChanged( String name, String newValue, String oldValue )
160 {
161 if( !StringUtils.hasContent( newValue ) )
162 return;
163
164 if( name.equals( SSLSettings.KEYSTORE ) || name.equals( SSLSettings.KEYSTORE_PASSWORD ) )
165 {
166 try
167 {
168 log.info( "Updating keyStore.." );
169 initKeyMaterial( easySSL );
170 }
171 catch( Throwable e )
172 {
173 SoapUI.logError( e );
174 }
175 }
176 else if( name.equals( HttpSettings.MAX_CONNECTIONS_PER_HOST ) )
177 {
178 log.info( "Updating max connections per host to " + newValue );
179 connectionManager.getParams().setDefaultMaxConnectionsPerHost( Integer.parseInt( newValue ) );
180 }
181 else if( name.equals( HttpSettings.MAX_TOTAL_CONNECTIONS ) )
182 {
183 log.info( "Updating max total connections host to " + newValue );
184 connectionManager.getParams().setMaxTotalConnections( Integer.parseInt( newValue ) );
185 }
186 }
187
188 @Override
189 public void settingsReloaded()
190 {
191 try
192 {
193 log.info( "Updating keyStore.." );
194 initKeyMaterial( easySSL );
195 }
196 catch( Throwable e )
197 {
198 SoapUI.logError( e );
199 }
200 }
201 }
202
203 }
204
205 public static HttpClient getHttpClient()
206 {
207 return helper.getHttpClient();
208 }
209
210 public static void applyHttpSettings( HttpMethod httpMethod, Settings settings )
211 {
212
213 String userAgent = settings.getString( HttpSettings.USER_AGENT, null );
214 if( userAgent != null && userAgent.length() > 0 )
215 httpMethod.setRequestHeader( "User-Agent", userAgent );
216
217
218 long timeout = settings.getLong( HttpSettings.SOCKET_TIMEOUT, HttpSettings.DEFAULT_SOCKET_TIMEOUT );
219 httpMethod.getParams().setSoTimeout( ( int )timeout );
220 }
221
222 public static String getResponseCompressionType( HttpMethod method )
223 {
224 Header contentType = method.getResponseHeader( "Content-Type" );
225 Header contentEncoding = method.getResponseHeader( "Content-Encoding" );
226
227 return getCompressionType( contentType == null ? null : contentType.getValue(), contentEncoding == null ? null
228 : contentEncoding.getValue() );
229 }
230
231 public static String getCompressionType( String contentType, String contentEncoding )
232 {
233 String compressionAlg = contentType == null ? null : CompressionSupport.getAvailableAlgorithm( contentType );
234 if( compressionAlg != null )
235 return compressionAlg;
236
237 if( contentEncoding == null )
238 return null;
239 else
240 return CompressionSupport.getAvailableAlgorithm( contentEncoding );
241 }
242
243 public static void addSSLListener( Settings settings )
244 {
245 settings.addSettingsListener( helper.new SSLSettingsListener() );
246 }
247 }