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 javax.activation.DataHandler;
20 import javax.mail.MessagingException;
21 import javax.mail.internet.MimeBodyPart;
22 import javax.mail.internet.MimeMessage;
23 import javax.mail.internet.MimeMultipart;
24 import javax.mail.internet.PreencodedMimeBodyPart;
25
26 import org.apache.commons.httpclient.Header;
27 import org.apache.commons.httpclient.HostConfiguration;
28 import org.apache.commons.httpclient.HttpClient;
29 import org.apache.commons.httpclient.HttpState;
30 import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
31 import org.apache.log4j.Logger;
32
33 import com.eviware.soapui.SoapUI;
34 import com.eviware.soapui.impl.wsdl.WsdlOperation;
35 import com.eviware.soapui.impl.wsdl.WsdlRequest;
36 import com.eviware.soapui.impl.wsdl.submit.RequestFilter;
37 import com.eviware.soapui.impl.wsdl.support.MessageXmlObject;
38 import com.eviware.soapui.impl.wsdl.support.MessageXmlPart;
39 import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport;
40 import com.eviware.soapui.model.iface.Response;
41 import com.eviware.soapui.model.iface.SubmitContext;
42 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
43 import com.eviware.soapui.model.settings.Settings;
44 import com.eviware.soapui.settings.HttpSettings;
45 import com.eviware.soapui.support.StringUtils;
46 import com.eviware.soapui.support.types.StringToStringMap;
47
48 /***
49 * HTTP transport that uses HttpClient to send/receive SOAP messages
50 *
51 * @author Ole.Matzura
52 */
53
54 public class HttpClientRequestTransport implements BaseHttpRequestTransport
55 {
56 private List<RequestFilter> filters = new ArrayList<RequestFilter>();
57 private final static Logger log = Logger.getLogger(HttpClientRequestTransport.class);
58
59 public HttpClientRequestTransport()
60 {
61 for( RequestFilter filter : SoapUI.getListenerRegistry().getListeners( RequestFilter.class ))
62 {
63 addRequestFilter( filter );
64 }
65 }
66
67 public void addRequestFilter(RequestFilter filter)
68 {
69 filters.add( filter );
70 }
71
72 public void removeRequestFilter(RequestFilter filter)
73 {
74 filters.remove( filter );
75 }
76
77 public void abortRequest( SubmitContext submitContext )
78 {
79 TimeablePostMethod postMethod = (TimeablePostMethod) submitContext.getProperty( POST_METHOD );
80 if( postMethod != null )
81 postMethod.abort();
82 }
83
84 public Response sendRequest( SubmitContext submitContext, WsdlRequest wsdlRequest ) throws Exception
85 {
86 HttpClient httpClient = HttpClientSupport.getHttpClient();
87 TimeablePostMethod postMethod = new TimeablePostMethod();
88 boolean createdState = false;
89
90 HttpState httpState = (HttpState) submitContext.getProperty(SubmitContext.HTTP_STATE_PROPERTY);
91 if( httpState == null )
92 {
93 httpState = new HttpState();
94 submitContext.setProperty( SubmitContext.HTTP_STATE_PROPERTY, httpState );
95 createdState = true;
96 }
97
98 HostConfiguration hostConfiguration = new HostConfiguration();
99
100 String localAddress = System.getProperty( "soapui.bind.address", wsdlRequest.getBindAddress() );
101 if( localAddress == null || localAddress.trim().length() == 0 )
102 localAddress = SoapUI.getSettings().getString( HttpSettings.BIND_ADDRESS, null );
103
104 if( localAddress != null && localAddress.trim().length() > 0 )
105 {
106 try
107 {
108 hostConfiguration.setLocalAddress( InetAddress.getByName( localAddress ));
109 }
110 catch( Exception e )
111 {
112 SoapUI.logError( e );
113 }
114 }
115
116 submitContext.setProperty( POST_METHOD, postMethod );
117 submitContext.setProperty( HTTP_CLIENT, httpClient );
118 submitContext.setProperty( REQUEST_CONTENT, wsdlRequest.getRequestContent() );
119 submitContext.setProperty( HOST_CONFIGURATION, hostConfiguration );
120 submitContext.setProperty( WSDL_REQUEST, wsdlRequest );
121
122 for( RequestFilter filter : filters )
123 {
124 filter.filterRequest( submitContext, wsdlRequest );
125 }
126
127 Response response = null;
128
129 try
130 {
131 Settings settings = wsdlRequest.getSettings();
132
133
134 String requestContent = (String) submitContext.getProperty(REQUEST_CONTENT);
135
136
137 requestContent = initRequest(wsdlRequest, postMethod, requestContent);
138
139
140 StringToStringMap headers = wsdlRequest.getRequestHeaders();
141 for( String header : headers.keySet() )
142 {
143 String headerValue = headers.get( header );
144 headerValue = PropertyExpansionUtils.expandProperties( submitContext, headerValue );
145 postMethod.setRequestHeader( header, headerValue );
146 }
147
148
149 if (settings.getBoolean(HttpSettings.INCLUDE_REQUEST_IN_TIME_TAKEN))
150 postMethod.initStartTime();
151
152
153 httpClient.executeMethod(hostConfiguration, postMethod, httpState);
154
155 Header responseContentTypeHeader = postMethod.getResponseHeader( "Content-Type" );
156
157 if( !settings.getBoolean( WsdlRequest.INLINE_RESPONSE_ATTACHMENTS ) &&
158 responseContentTypeHeader != null &&
159 responseContentTypeHeader.getValue().toUpperCase().startsWith( "MULTIPART" ))
160 {
161 response = new MimeMessageResponse( wsdlRequest, postMethod, requestContent, submitContext );
162 }
163 else
164 {
165 response = new SinglePartHttpResponse( wsdlRequest, postMethod, requestContent, submitContext );
166 }
167
168 return response;
169 }
170 finally
171 {
172 for( RequestFilter filter : filters )
173 {
174 filter.afterRequest( submitContext, response );
175 }
176
177 if (postMethod != null)
178 {
179 postMethod.releaseConnection();
180 }
181 else log.error( "PostMethod is null");
182
183 if( createdState )
184 submitContext.setProperty( SubmitContext.HTTP_STATE_PROPERTY, null );
185 }
186 }
187
188 private String initRequest(WsdlRequest wsdlRequest, TimeablePostMethod postMethod, String requestContent) throws Exception
189 {
190 MimeMultipart mp = null;
191
192 StringToStringMap contentIds = new StringToStringMap();
193 boolean isXOP = wsdlRequest.isMtomEnabled() && wsdlRequest.isForceMtom();
194
195
196 if( wsdlRequest.isMtomEnabled() || wsdlRequest.isInlineFilesEnabled() || wsdlRequest.getAttachmentCount() > 0 )
197 {
198 try
199 {
200 mp = new MimeMultipart();
201
202 MessageXmlObject requestXmlObject = new MessageXmlObject(( WsdlOperation ) wsdlRequest.getOperation(),
203 requestContent, true);
204 MessageXmlPart[] requestParts = requestXmlObject.getMessageParts();
205 for (MessageXmlPart requestPart : requestParts)
206 {
207 if (AttachmentUtils.prepareMessagePart(wsdlRequest, mp, requestPart, contentIds))
208 isXOP = true;
209 }
210 requestContent = requestXmlObject.getMessageContent();
211 }
212 catch (Exception e)
213 {
214 log.warn( "Failed to process inline/MTOM attachments; " + e );
215 }
216 }
217
218
219 if( !isXOP && (mp == null || mp.getCount() == 0 ) && wsdlRequest.getAttachmentCount() == 0 )
220 {
221 String encoding = StringUtils.unquote( wsdlRequest.getEncoding());
222 byte[] content = encoding == null ? requestContent.getBytes() : requestContent.getBytes(encoding);
223 postMethod.setRequestEntity(new ByteArrayRequestEntity(content));
224 }
225 else
226 {
227
228 if( mp == null )
229 mp = new MimeMultipart();
230
231
232 initRootPart(wsdlRequest, requestContent, mp, isXOP);
233
234
235 AttachmentUtils.addMimeParts(wsdlRequest, mp, contentIds);
236
237
238 MimeMessage message = new MimeMessage( AttachmentUtils.JAVAMAIL_SESSION );
239 message.setContent( mp );
240 message.saveChanges();
241 MimeMessageRequestEntity mimeMessageRequestEntity = new MimeMessageRequestEntity( message, isXOP, wsdlRequest );
242 postMethod.setRequestEntity( mimeMessageRequestEntity );
243 postMethod.setRequestHeader( "Content-Type", mimeMessageRequestEntity.getContentType() );
244 postMethod.setRequestHeader( "MIME-Version", "1.0" );
245 }
246
247 return requestContent;
248 }
249
250 /***
251 * Creates root BodyPart containing message
252 */
253
254 private void initRootPart(WsdlRequest wsdlRequest, String requestContent, MimeMultipart mp, boolean isXOP) throws MessagingException
255 {
256 MimeBodyPart rootPart = new PreencodedMimeBodyPart( "8bit" );
257 rootPart.setContentID( AttachmentUtils.ROOTPART_SOAPUI_ORG );
258 mp.addBodyPart( rootPart, 0 );
259
260 DataHandler dataHandler = new DataHandler( new WsdlRequestDataSource( wsdlRequest, requestContent, isXOP ) );
261 rootPart.setDataHandler( dataHandler);
262 }
263
264
265 }