1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.submit.transports.http;
14
15 import java.net.InetAddress;
16 import java.util.ArrayList;
17 import java.util.List;
18
19 import org.apache.commons.httpclient.Header;
20 import org.apache.commons.httpclient.HostConfiguration;
21 import org.apache.commons.httpclient.HttpClient;
22 import org.apache.commons.httpclient.HttpMethodBase;
23 import org.apache.commons.httpclient.HttpState;
24 import org.apache.commons.httpclient.URI;
25 import org.apache.log4j.Logger;
26
27 import com.eviware.soapui.SoapUI;
28 import com.eviware.soapui.impl.support.AbstractHttpRequestInterface;
29 import com.eviware.soapui.impl.support.http.HttpRequestInterface;
30 import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
31 import com.eviware.soapui.impl.wsdl.WsdlProject;
32 import com.eviware.soapui.impl.wsdl.submit.RequestFilter;
33 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.MimeMessageResponse;
34 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedDeleteMethod;
35 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedGetMethod;
36 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedHeadMethod;
37 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedOptionsMethod;
38 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedPostMethod;
39 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedPutMethod;
40 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedTraceMethod;
41 import com.eviware.soapui.impl.wsdl.support.PathUtils;
42 import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport;
43 import com.eviware.soapui.impl.wsdl.support.http.SoapUIHostConfiguration;
44 import com.eviware.soapui.impl.wsdl.support.wss.WssCrypto;
45 import com.eviware.soapui.model.iface.Request;
46 import com.eviware.soapui.model.iface.Response;
47 import com.eviware.soapui.model.iface.SubmitContext;
48 import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
49 import com.eviware.soapui.model.settings.Settings;
50 import com.eviware.soapui.model.support.ModelSupport;
51 import com.eviware.soapui.settings.HttpSettings;
52 import com.eviware.soapui.support.StringUtils;
53 import com.eviware.soapui.support.types.StringToStringMap;
54 import com.eviware.soapui.support.types.StringToStringsMap;
55
56 /***
57 * HTTP transport that uses HttpClient to send/receive SOAP messages
58 *
59 * @author Ole.Matzura
60 */
61
62 public class HttpClientRequestTransport implements BaseHttpRequestTransport
63 {
64 private List<RequestFilter> filters = new ArrayList<RequestFilter>();
65 private final static Logger log = Logger.getLogger( HttpClientRequestTransport.class );
66
67 public HttpClientRequestTransport()
68 {
69 }
70
71 public void addRequestFilter( RequestFilter filter )
72 {
73 filters.add( filter );
74 }
75
76 public void removeRequestFilter( RequestFilter filter )
77 {
78 filters.remove( filter );
79 }
80
81 public void abortRequest( SubmitContext submitContext )
82 {
83 HttpMethodBase postMethod = ( HttpMethodBase )submitContext.getProperty( HTTP_METHOD );
84 if( postMethod != null )
85 postMethod.abort();
86 }
87
88 public Response sendRequest( SubmitContext submitContext, Request request ) throws Exception
89 {
90 AbstractHttpRequestInterface<?> httpRequest = ( AbstractHttpRequestInterface<?> )request;
91
92 HttpClient httpClient = HttpClientSupport.getHttpClient();
93 ExtendedHttpMethod httpMethod = createHttpMethod( httpRequest );
94 boolean createdState = false;
95
96 HttpState httpState = ( HttpState )submitContext.getProperty( SubmitContext.HTTP_STATE_PROPERTY );
97 if( httpState == null )
98 {
99 httpState = new HttpState();
100 submitContext.setProperty( SubmitContext.HTTP_STATE_PROPERTY, httpState );
101 createdState = true;
102 }
103
104 HostConfiguration hostConfiguration = new HostConfiguration();
105
106 String localAddress = System.getProperty( "soapui.bind.address", httpRequest.getBindAddress() );
107 if( localAddress == null || localAddress.trim().length() == 0 )
108 localAddress = SoapUI.getSettings().getString( HttpSettings.BIND_ADDRESS, null );
109
110 if( localAddress != null && localAddress.trim().length() > 0 )
111 {
112 try
113 {
114 hostConfiguration.setLocalAddress( InetAddress.getByName( localAddress ) );
115 }
116 catch( Exception e )
117 {
118 SoapUI.logError( e );
119 }
120 }
121
122 submitContext.removeProperty( RESPONSE );
123 submitContext.setProperty( HTTP_METHOD, httpMethod );
124 submitContext.setProperty( POST_METHOD, httpMethod );
125 submitContext.setProperty( HTTP_CLIENT, httpClient );
126 submitContext.setProperty( REQUEST_CONTENT, httpRequest.getRequestContent() );
127 submitContext.setProperty( HOST_CONFIGURATION, hostConfiguration );
128 submitContext.setProperty( WSDL_REQUEST, httpRequest );
129 submitContext.setProperty( RESPONSE_PROPERTIES, new StringToStringMap() );
130
131 for( RequestFilter filter : filters )
132 {
133 filter.filterRequest( submitContext, httpRequest );
134 }
135
136 try
137 {
138 Settings settings = httpRequest.getSettings();
139
140
141 StringToStringsMap headers = httpRequest.getRequestHeaders();
142
143
144 for( String header : headers.keySet() )
145 {
146 httpMethod.removeRequestHeader( header );
147 }
148
149
150 for( String header : headers.keySet() )
151 {
152 for( String headerValue : headers.get( header ) )
153 {
154 headerValue = PropertyExpander.expandProperties( submitContext, headerValue );
155 httpMethod.addRequestHeader( header, headerValue );
156 }
157 }
158
159
160 WsdlProject project = ( WsdlProject )ModelSupport.getModelItemProject( httpRequest );
161 WssCrypto crypto = null;
162 if( project != null && project.getWssContainer() != null )
163 {
164 crypto = project.getWssContainer().getCryptoByName(
165 PropertyExpander.expandProperties( submitContext, httpRequest.getSslKeystore() ) );
166 }
167
168 if( crypto != null && WssCrypto.STATUS_OK.equals( crypto.getStatus() ) )
169 {
170 hostConfiguration.getParams().setParameter( SoapUIHostConfiguration.SOAPUI_SSL_CONFIG,
171 crypto.getSource() + " " + crypto.getPassword() );
172 }
173
174
175 httpMethod.setDumpFile( PathUtils.expandPath( httpRequest.getDumpFile(),
176 ( AbstractWsdlModelItem<?> )httpRequest, submitContext ) );
177
178
179 URI uri = ( URI )submitContext.getProperty( BaseHttpRequestTransport.REQUEST_URI );
180 if( uri != null && uri.isAbsoluteURI() )
181 {
182 hostConfiguration.setHost( uri.getHost(), uri.getPort() );
183 String str = uri.toString();
184 int ix = str.indexOf( '/', str.indexOf( "//" ) + 2 );
185 if( ix != -1 )
186 {
187 uri = new URI( str.substring( ix ), true );
188 String qs = httpMethod.getQueryString();
189 httpMethod.setURI( uri );
190 if( StringUtils.hasContent( qs ) )
191 httpMethod.setQueryString( qs );
192
193 submitContext.setProperty( BaseHttpRequestTransport.REQUEST_URI, uri );
194 }
195 }
196
197
198 if( settings.getBoolean( HttpSettings.INCLUDE_REQUEST_IN_TIME_TAKEN ) )
199 httpMethod.initStartTime();
200
201
202 httpClient.executeMethod( hostConfiguration, httpMethod, httpState );
203 httpMethod.getTimeTaken();
204 }
205 catch( Throwable t )
206 {
207 httpMethod.setFailed( t );
208
209 if( t instanceof Exception )
210 throw ( Exception )t;
211
212 SoapUI.logError( t );
213 throw new Exception( t );
214 }
215 finally
216 {
217 for( int c = filters.size() - 1; c >= 0; c-- )
218 {
219 filters.get( c ).afterRequest( submitContext, httpRequest );
220 }
221
222 if( !submitContext.hasProperty( RESPONSE ) )
223 {
224 createDefaultResponse( submitContext, httpRequest, httpMethod );
225 }
226
227 Response response = ( Response )submitContext.getProperty( BaseHttpRequestTransport.RESPONSE );
228 StringToStringMap responseProperties = ( StringToStringMap )submitContext
229 .getProperty( BaseHttpRequestTransport.RESPONSE_PROPERTIES );
230
231 for( String key : responseProperties.keySet() )
232 {
233 response.setProperty( key, responseProperties.get( key ) );
234 }
235
236 if( httpMethod != null )
237 {
238 httpMethod.releaseConnection();
239 }
240 else
241 log.error( "PostMethod is null" );
242
243 if( createdState )
244 {
245 submitContext.setProperty( SubmitContext.HTTP_STATE_PROPERTY, null );
246 }
247 }
248
249 return ( Response )submitContext.getProperty( BaseHttpRequestTransport.RESPONSE );
250 }
251
252 private void createDefaultResponse( SubmitContext submitContext, AbstractHttpRequestInterface<?> httpRequest,
253 ExtendedHttpMethod httpMethod )
254 {
255 String requestContent = ( String )submitContext.getProperty( BaseHttpRequestTransport.REQUEST_CONTENT );
256
257
258 Header responseContentTypeHeader = httpMethod.getResponseHeader( "Content-Type" );
259 Response response = null;
260
261 if( responseContentTypeHeader != null
262 && responseContentTypeHeader.getValue().toUpperCase().startsWith( "MULTIPART" ) )
263 {
264 response = new MimeMessageResponse( httpRequest, httpMethod, requestContent, submitContext );
265 }
266 else
267 {
268 response = new SinglePartHttpResponse( httpRequest, httpMethod, requestContent, submitContext );
269 }
270
271 submitContext.setProperty( BaseHttpRequestTransport.RESPONSE, response );
272 }
273
274 private ExtendedHttpMethod createHttpMethod( AbstractHttpRequestInterface<?> httpRequest )
275 {
276 if( httpRequest instanceof HttpRequestInterface<?> )
277 {
278 HttpRequestInterface<?> restRequest = ( HttpRequestInterface<?> )httpRequest;
279 switch( restRequest.getMethod() )
280 {
281 case GET :
282 return new ExtendedGetMethod();
283 case HEAD :
284 return new ExtendedHeadMethod();
285 case DELETE :
286 return new ExtendedDeleteMethod();
287 case PUT :
288 return new ExtendedPutMethod();
289 case OPTIONS :
290 return new ExtendedOptionsMethod();
291 case TRACE :
292 return new ExtendedTraceMethod();
293 }
294 }
295
296 ExtendedPostMethod extendedPostMethod = new ExtendedPostMethod();
297
298 extendedPostMethod.setAfterRequestInjection( httpRequest.getAfterRequestInjection() );
299 return extendedPostMethod;
300 }
301
302 }