1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.support.wsdl;
14
15 import com.eviware.soapui.SoapUI;
16 import com.eviware.soapui.impl.support.definition.DefinitionLoader;
17 import com.eviware.soapui.impl.wsdl.support.CompressionSupport;
18 import com.eviware.soapui.impl.wsdl.support.PathUtils;
19 import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport;
20 import com.eviware.soapui.impl.wsdl.support.http.ProxyUtils;
21 import com.eviware.soapui.model.ModelItem;
22 import com.eviware.soapui.model.propertyexpansion.DefaultPropertyExpansionContext;
23 import com.eviware.soapui.model.settings.Settings;
24 import com.eviware.soapui.settings.HttpSettings;
25 import com.eviware.soapui.support.UISupport;
26 import com.eviware.soapui.support.swing.SwingWorker;
27 import com.eviware.soapui.support.types.StringToStringMap;
28 import com.eviware.x.form.XForm;
29 import com.eviware.x.form.XFormDialog;
30 import com.eviware.x.form.XFormDialogBuilder;
31 import com.eviware.x.form.XFormFactory;
32 import org.apache.commons.httpclient.*;
33 import org.apache.commons.httpclient.auth.*;
34 import org.apache.commons.httpclient.methods.GetMethod;
35
36 import java.io.ByteArrayInputStream;
37 import java.io.File;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.net.URL;
41 import java.util.HashMap;
42 import java.util.Map;
43
44 /***
45 * WsdlLoader for URLs
46 *
47 * @author ole.matzura
48 */
49
50 public class UrlWsdlLoader extends WsdlLoader implements DefinitionLoader
51 {
52 private HttpState state;
53 protected GetMethod getMethod;
54 private boolean aborted;
55 protected Map<String, byte[]> urlCache = new HashMap<String, byte[]>();
56 protected boolean finished;
57 private boolean useWorker;
58 private ModelItem contextModelItem;
59
60 public UrlWsdlLoader( String url )
61 {
62 this( url, null );
63 }
64
65 public UrlWsdlLoader( String url, ModelItem contextModelItem )
66 {
67 super( url );
68 this.contextModelItem = contextModelItem;
69 state = new HttpState();
70 }
71
72 public boolean isUseWorker()
73 {
74 return useWorker;
75 }
76
77 public void setUseWorker( boolean useWorker )
78 {
79 this.useWorker = useWorker;
80 }
81
82 public InputStream load() throws Exception
83 {
84 return load( getBaseURI() );
85 }
86
87 public synchronized InputStream load( String url ) throws Exception
88 {
89 if( !PathUtils.isHttpPath( url ) )
90 {
91 try
92 {
93 File file = new File( url.replace( '/', File.separatorChar ) );
94 if( file.exists() )
95 url = file.toURI().toURL().toString();
96 }
97 catch( Exception e )
98 {
99 }
100 }
101
102 if( urlCache.containsKey( url ) )
103 {
104 setNewBaseURI( url );
105 return new ByteArrayInputStream( urlCache.get( url ) );
106 }
107
108 if( url.startsWith( "file:" ) )
109 {
110 return handleFile( url );
111 }
112
113 log.debug( "Getting wsdl component from [" + url + "]" );
114
115 createGetMethod( url );
116
117 if( aborted )
118 return null;
119
120 LoaderWorker worker = new LoaderWorker();
121 if( useWorker )
122 worker.start();
123 else
124 worker.construct();
125
126 while( !aborted && !finished )
127 {
128 Thread.sleep( 200 );
129 }
130
131
132 while( !aborted && getMethod.getResponseBody() == null )
133 {
134 Thread.sleep( 200 );
135 }
136
137 try
138 {
139 if( aborted )
140 {
141 throw new Exception( "Load of url [" + url + "] was aborted" );
142 }
143 else
144 {
145 byte[] content = getMethod.getResponseBody();
146 if( content != null )
147 {
148 String compressionAlg = HttpClientSupport.getResponseCompressionType( getMethod );
149 if( compressionAlg != null )
150 content = CompressionSupport.decompress( compressionAlg, content );
151
152 urlCache.put( url, content );
153 String newUrl = getMethod.getURI().getURI();
154 if( !url.equals( newUrl ) )
155 log.info( "BaseURI was redirected to [" + newUrl + "]" );
156 setNewBaseURI( newUrl );
157 urlCache.put( newUrl, content );
158 return new ByteArrayInputStream( content );
159 }
160 else
161 {
162 throw new Exception( "Failed to load url; " + getMethod.getStatusCode() + " - " + getMethod.getStatusText() );
163 }
164 }
165 }
166
167 finally
168 {
169 getMethod.releaseConnection();
170 }
171 }
172
173 protected InputStream handleFile( String url )
174 throws IOException
175 {
176 setNewBaseURI( url );
177 return new URL( url ).openStream();
178 }
179
180 protected void createGetMethod( String url )
181 {
182 getMethod = new GetMethod( url );
183 getMethod.setDoAuthentication( true );
184 getMethod.getParams().setParameter( CredentialsProvider.PROVIDER, new WsdlCredentialsProvider() );
185
186 if( SoapUI.getSettings().getBoolean( HttpSettings.AUTHENTICATE_PREEMPTIVELY ) )
187 {
188 HttpClientSupport.getHttpClient().getParams().setAuthenticationPreemptive( true );
189 }
190 else
191 {
192 HttpClientSupport.getHttpClient().getParams().setAuthenticationPreemptive( false );
193 }
194 }
195
196 public final class LoaderWorker extends SwingWorker
197 {
198 public Object construct()
199 {
200 HttpClient httpClient = HttpClientSupport.getHttpClient();
201 try
202 {
203 Settings soapuiSettings = SoapUI.getSettings();
204
205 HttpClientSupport.applyHttpSettings( getMethod, soapuiSettings );
206 HostConfiguration hostConfiguration = ProxyUtils.initProxySettings( soapuiSettings, state,
207 new HostConfiguration(), getMethod.getURI().toString(),
208 contextModelItem == null ? null : new DefaultPropertyExpansionContext( contextModelItem ) );
209
210 httpClient.executeMethod( hostConfiguration, getMethod, state );
211 }
212 catch( Exception e )
213 {
214 return e;
215 }
216 finally
217 {
218 finished = true;
219 }
220
221 return null;
222 }
223 }
224
225 public boolean abort()
226 {
227 if( getMethod != null )
228 getMethod.abort();
229
230 aborted = true;
231
232 return true;
233 }
234
235 public boolean isAborted()
236 {
237 return aborted;
238 }
239
240 /***
241 * CredentialsProvider for providing login information during WSDL loading
242 *
243 * @author ole.matzura
244 */
245
246 public final class WsdlCredentialsProvider implements CredentialsProvider
247 {
248 private XFormDialog basicDialog;
249 private XFormDialog ntDialog;
250
251 public WsdlCredentialsProvider()
252 {
253 }
254
255 public Credentials getCredentials( final AuthScheme authscheme, final String host, int port, boolean proxy )
256 throws CredentialsNotAvailableException
257 {
258 if( authscheme == null )
259 {
260 return null;
261 }
262 try
263 {
264 String pw = getPassword();
265 if( pw == null )
266 pw = "";
267
268 if( authscheme instanceof NTLMScheme )
269 {
270 if( hasCredentials() )
271 {
272 log.info( "Returning url credentials" );
273 return new NTCredentials( getUsername(), pw, host, null );
274 }
275
276 log.info( host + ":" + port + " requires Windows authentication" );
277 if( ntDialog == null )
278 {
279 buildNtDialog();
280 }
281
282 StringToStringMap values = new StringToStringMap();
283 values.put( "Info", "Authentication required for [" + host + ":" + port + "]" );
284 ntDialog.setValues( values );
285
286 if( ntDialog.show() )
287 {
288 values = ntDialog.getValues();
289 return new NTCredentials( values.get( "Username" ), values.get( "Password" ), host, values.get( "Domain" ) );
290 }
291 else
292 throw new CredentialsNotAvailableException( "Operation cancelled" );
293 }
294 else if( authscheme instanceof RFC2617Scheme )
295 {
296 if( hasCredentials() )
297 {
298 log.info( "Returning url credentials" );
299 return new UsernamePasswordCredentials( getUsername(), pw );
300 }
301
302 log.info( host + ":" + port + " requires authentication with the realm '" + authscheme.getRealm() + "'" );
303 if( basicDialog == null )
304 buildBasicDialog();
305
306 StringToStringMap values = new StringToStringMap();
307 values.put( "Info", "Authentication required for [" + host + ":" + port + "]" );
308 basicDialog.setValues( values );
309 if( basicDialog.show() )
310 {
311 values = basicDialog.getValues();
312 return new UsernamePasswordCredentials( values.get( "Username" ), values.get( "Password" ) );
313 }
314 else
315 throw new CredentialsNotAvailableException( "Operation cancelled" );
316
317 }
318 else
319 {
320 throw new CredentialsNotAvailableException( "Unsupported authentication scheme: "
321 + authscheme.getSchemeName() );
322 }
323 }
324 catch( IOException e )
325 {
326 throw new CredentialsNotAvailableException( e.getMessage(), e );
327 }
328 }
329
330 private void buildBasicDialog()
331 {
332 XFormDialogBuilder builder = XFormFactory.createDialogBuilder( "Basic Authentication" );
333 XForm mainForm = builder.createForm( "Basic" );
334 mainForm.addLabel( "Info", "" );
335 mainForm.addTextField( "Username", "Username for authentication", XForm.FieldType.TEXT );
336 mainForm.addTextField( "Password", "Password for authentication", XForm.FieldType.PASSWORD );
337
338 basicDialog = builder.buildDialog( builder.buildOkCancelActions(),
339 "Specify Basic Authentication Credentials", UISupport.OPTIONS_ICON );
340 }
341
342 private void buildNtDialog()
343 {
344 XFormDialogBuilder builder = XFormFactory.createDialogBuilder( "NT Authentication" );
345 XForm mainForm = builder.createForm( "Basic" );
346 mainForm.addLabel( "Info", "" );
347 mainForm.addTextField( "Username", "Username for authentication", XForm.FieldType.TEXT );
348 mainForm.addTextField( "Password", "Password for authentication", XForm.FieldType.PASSWORD );
349 mainForm.addTextField( "Domain", "NT Domain for authentication", XForm.FieldType.TEXT );
350
351 ntDialog = builder.buildDialog( builder.buildOkCancelActions(),
352 "Specify NT Authentication Credentials", UISupport.OPTIONS_ICON );
353 }
354 }
355
356 public void close()
357 {
358 }
359 }