View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
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 /*&& formMp == null*/ && !param.isDisableUrlEncoding() )
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 			// create request message
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 							// init mimeparts
290 							AttachmentUtils.addMimeParts( request, attachments, mp, new StringToStringMap() );
291 
292 							// create request message
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 		// rootPart.setContentID( AttachmentUtils.ROOTPART_SOAPUI_ORG );
360 		mp.addBodyPart( rootPart, 0 );
361 
362 		DataHandler dataHandler = new DataHandler( new RestRequestDataSource( wsdlRequest, requestContent ) );
363 		rootPart.setDataHandler( dataHandler );
364 	}
365 }