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