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