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