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