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