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