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