1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.submit.filters;
14
15 import java.io.File;
16 import java.io.UnsupportedEncodingException;
17 import java.net.URLEncoder;
18 import java.util.ArrayList;
19 import java.util.List;
20
21 import javax.activation.DataHandler;
22 import javax.activation.FileDataSource;
23 import javax.mail.MessagingException;
24 import javax.mail.internet.MimeBodyPart;
25 import javax.mail.internet.MimeMessage;
26 import javax.mail.internet.MimeMultipart;
27 import javax.mail.internet.PreencodedMimeBodyPart;
28
29 import org.apache.commons.httpclient.HttpMethod;
30 import org.apache.commons.httpclient.URI;
31 import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
32 import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
33 import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
34 import org.apache.commons.httpclient.methods.StringRequestEntity;
35 import org.apache.xmlbeans.XmlBoolean;
36
37 import com.eviware.soapui.SoapUI;
38 import com.eviware.soapui.impl.rest.RestRequest;
39 import com.eviware.soapui.impl.rest.support.RestParamProperty;
40 import com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder;
41 import com.eviware.soapui.impl.support.http.HttpRequestInterface;
42 import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
43 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.AttachmentDataSource;
44 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.AttachmentUtils;
45 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.RestRequestDataSource;
46 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.RestRequestMimeMessageRequestEntity;
47 import com.eviware.soapui.impl.wsdl.support.PathUtils;
48 import com.eviware.soapui.model.iface.Attachment;
49 import com.eviware.soapui.model.iface.SubmitContext;
50 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
51 import com.eviware.soapui.support.StringUtils;
52 import com.eviware.soapui.support.editor.inspectors.attachments.ContentTypeHandler;
53 import com.eviware.soapui.support.types.StringToStringMap;
54
55 /***
56 * RequestFilter that adds SOAP specific headers
57 *
58 * @author Ole.Matzura
59 */
60
61 public class HttpRequestFilter extends AbstractRequestFilter
62 {
63 @SuppressWarnings( "deprecation" )
64 @Override
65 public void filterHttpRequest( SubmitContext context, HttpRequestInterface<?> request )
66 {
67 HttpMethod httpMethod = ( HttpMethod )context.getProperty( BaseHttpRequestTransport.HTTP_METHOD );
68
69 String path = PropertyExpansionUtils.expandProperties( context, request.getPath() );
70 StringBuffer query = new StringBuffer();
71
72 StringToStringMap responseProperties = ( StringToStringMap )context
73 .getProperty( BaseHttpRequestTransport.RESPONSE_PROPERTIES );
74
75 MimeMultipart formMp = "multipart/form-data".equals( request.getMediaType() )
76 && httpMethod instanceof EntityEnclosingMethod ? new MimeMultipart() : null;
77
78 RestParamsPropertyHolder params = request.getParams();
79 for( int c = 0; c < params.getPropertyCount(); c++ )
80 {
81 RestParamProperty param = params.getPropertyAt( c );
82
83 String value = PropertyExpansionUtils.expandProperties( context, param.getValue() );
84 responseProperties.put( param.getName(), value );
85
86 if( value != null
87 {
88 try
89 {
90 String encoding = System.getProperty( "soapui.request.encoding", request.getEncoding() );
91
92 if( StringUtils.hasContent( encoding ) )
93 value = URLEncoder.encode( value, encoding );
94 else
95 value = URLEncoder.encode( value );
96 }
97 catch( UnsupportedEncodingException e1 )
98 {
99 SoapUI.logError( e1 );
100 value = URLEncoder.encode( value );
101 }
102 }
103
104 if( !StringUtils.hasContent( value ) && !param.getRequired() )
105 continue;
106
107 switch( param.getStyle() )
108 {
109 case HEADER :
110 httpMethod.setRequestHeader( param.getName(), value );
111 break;
112 case QUERY :
113 if( formMp == null || !request.isPostQueryString() )
114 {
115 if( query.length() > 0 )
116 query.append( '&' );
117
118 query.append( URLEncoder.encode( param.getName() ) );
119 query.append( '=' );
120 if( StringUtils.hasContent( value ) )
121 query.append( value );
122 }
123 else
124 {
125 try
126 {
127 addFormMultipart( request, formMp, param.getName(), value );
128 }
129 catch( MessagingException e )
130 {
131 e.printStackTrace();
132 }
133 }
134
135 break;
136 case TEMPLATE :
137 path = path.replaceAll( "//{" + param.getName() + "//}", value );
138 break;
139 case MATRIX :
140 if( param.getType().equals( XmlBoolean.type.getName() ) )
141 {
142 if( value.toUpperCase().equals( "TRUE" ) || value.equals( "1" ) )
143 {
144 path += ";" + param.getName();
145 }
146 }
147 else
148 {
149 path += ";" + param.getName();
150 if( StringUtils.hasContent( value ) )
151 {
152 path += "=" + value;
153 }
154 }
155 case PLAIN :
156 break;
157 }
158 }
159
160 if( PathUtils.isHttpPath( path ) )
161 {
162 try
163 {
164 httpMethod.setURI( new URI( path ) );
165 }
166 catch( Exception e )
167 {
168 e.printStackTrace();
169 }
170 }
171 else if( StringUtils.hasContent( path ) )
172 {
173 httpMethod.setPath( path );
174 }
175
176 if( query.length() > 0 && !request.isPostQueryString() )
177 {
178 httpMethod.setQueryString( query.toString() );
179 }
180
181 if( request instanceof RestRequest )
182 {
183 String acceptEncoding = ((RestRequest)request).getAccept();
184 if( StringUtils.hasContent( acceptEncoding ) )
185 {
186 httpMethod.setRequestHeader( "Accept", acceptEncoding );
187 }
188 }
189
190 String encoding = System.getProperty( "soapui.request.encoding", StringUtils.unquote( request.getEncoding() ) );
191
192 if( formMp != null )
193 {
194
195 try
196 {
197 if( request.hasRequestBody() && httpMethod instanceof EntityEnclosingMethod )
198 {
199 String requestContent = PropertyExpansionUtils.expandProperties( context, request.getRequestContent(),
200 request.isEntitizeProperties() );
201 if( StringUtils.hasContent( requestContent ) )
202 {
203 initRootPart( request, requestContent, formMp );
204 }
205 }
206
207 for( Attachment attachment : request.getAttachments() )
208 {
209 MimeBodyPart part = new PreencodedMimeBodyPart( "binary" );
210 part.setDisposition( "form-data; name=\"" + attachment.getName() + "\"" );
211 part.setDataHandler( new DataHandler( new AttachmentDataSource( attachment ) ) );
212
213 formMp.addBodyPart( part );
214 }
215
216 MimeMessage message = new MimeMessage( AttachmentUtils.JAVAMAIL_SESSION );
217 message.setContent( formMp );
218 message.saveChanges();
219 RestRequestMimeMessageRequestEntity mimeMessageRequestEntity = new RestRequestMimeMessageRequestEntity(
220 message, request );
221 ( ( EntityEnclosingMethod )httpMethod ).setRequestEntity( mimeMessageRequestEntity );
222 httpMethod.setRequestHeader( "Content-Type", mimeMessageRequestEntity.getContentType() );
223 httpMethod.setRequestHeader( "MIME-Version", "1.0" );
224 }
225 catch( Throwable e )
226 {
227 SoapUI.logError( e );
228 }
229 }
230 else if( request.hasRequestBody() && httpMethod instanceof EntityEnclosingMethod )
231 {
232 httpMethod.setRequestHeader( "Content-Type", request.getMediaType() );
233
234 if( request.isPostQueryString() )
235 {
236 ( ( EntityEnclosingMethod )httpMethod ).setRequestEntity( new StringRequestEntity( query.toString() ) );
237 }
238 else
239 {
240 String requestContent = PropertyExpansionUtils.expandProperties( context, request.getRequestContent(),
241 request.isEntitizeProperties() );
242 List<Attachment> attachments = new ArrayList<Attachment>();
243
244 for( Attachment attachment : request.getAttachments() )
245 {
246 if( attachment.getContentType().equals( request.getMediaType() ) )
247 {
248 attachments.add( attachment );
249 }
250 }
251
252 if( StringUtils.hasContent( requestContent ) && attachments.isEmpty() )
253 {
254 try
255 {
256 byte[] content = encoding == null ? requestContent.getBytes() : requestContent.getBytes( encoding );
257 ( ( EntityEnclosingMethod )httpMethod ).setRequestEntity( new ByteArrayRequestEntity( content ) );
258 }
259 catch( UnsupportedEncodingException e )
260 {
261 ( ( EntityEnclosingMethod )httpMethod ).setRequestEntity( new ByteArrayRequestEntity( requestContent
262 .getBytes() ) );
263 }
264 }
265 else if( attachments.size() > 0 )
266 {
267 try
268 {
269 MimeMultipart mp = null;
270
271 if( StringUtils.hasContent( requestContent ) )
272 {
273 mp = new MimeMultipart();
274 initRootPart( request, requestContent, mp );
275 }
276 else if( attachments.size() == 1 )
277 {
278 ( ( EntityEnclosingMethod )httpMethod ).setRequestEntity( new InputStreamRequestEntity(
279 attachments.get( 0 ).getInputStream() ) );
280
281 httpMethod.setRequestHeader( "Content-Type", request.getMediaType() );
282 }
283
284 if( ( ( EntityEnclosingMethod )httpMethod ).getRequestEntity() == null )
285 {
286 if( mp == null )
287 mp = new MimeMultipart();
288
289
290 AttachmentUtils.addMimeParts( request, attachments, mp, new StringToStringMap() );
291
292
293 MimeMessage message = new MimeMessage( AttachmentUtils.JAVAMAIL_SESSION );
294 message.setContent( mp );
295 message.saveChanges();
296 RestRequestMimeMessageRequestEntity mimeMessageRequestEntity = new RestRequestMimeMessageRequestEntity(
297 message, request );
298 ( ( EntityEnclosingMethod )httpMethod ).setRequestEntity( mimeMessageRequestEntity );
299 httpMethod.setRequestHeader( "Content-Type", mimeMessageRequestEntity.getContentType() );
300 httpMethod.setRequestHeader( "MIME-Version", "1.0" );
301 }
302 }
303 catch( Exception e )
304 {
305 e.printStackTrace();
306 }
307 }
308 }
309 }
310 }
311
312 @SuppressWarnings({ "deprecation" })
313 private void addFormMultipart( HttpRequestInterface<?> request, MimeMultipart formMp, String name, String value )
314 throws MessagingException
315 {
316 MimeBodyPart part = new MimeBodyPart();
317
318 if( value.startsWith( "file:" ) )
319 {
320 String fileName = value.substring( 5 );
321 File file = new File( fileName );
322 part.setDisposition( "form-data; name=\"" + name + "\"; filename=\"" + file.getName() + "\"" );
323 if( file.exists() )
324 {
325 part.setDataHandler( new DataHandler( new FileDataSource( file ) ) );
326 }
327 else
328 {
329 for( Attachment attachment : request.getAttachments() )
330 {
331 if( attachment.getName().equals( fileName ) )
332 {
333 part.setDataHandler( new DataHandler( new AttachmentDataSource( attachment ) ) );
334 break;
335 }
336 }
337 }
338
339 part.setHeader( "Content-Type", ContentTypeHandler.getContentTypeFromFilename( file.getName() ) );
340 part.setHeader( "Content-Transfer-Encoding", "binary" );
341 }
342 else
343 {
344 part.setDisposition( "form-data; name=\"" + name + "\"" );
345 part.setText( value, System
346 .getProperty( "soapui.request.encoding", request.getEncoding() ) );
347 }
348
349 if( part != null )
350 {
351 formMp.addBodyPart( part );
352 }
353 }
354
355 protected void initRootPart( HttpRequestInterface<?> wsdlRequest, String requestContent, MimeMultipart mp )
356 throws MessagingException
357 {
358 MimeBodyPart rootPart = new PreencodedMimeBodyPart( "8bit" );
359
360 mp.addBodyPart( rootPart, 0 );
361
362 DataHandler dataHandler = new DataHandler( new RestRequestDataSource( wsdlRequest, requestContent ) );
363 rootPart.setDataHandler( dataHandler );
364 }
365 }