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