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