View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 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 com.eviware.soapui.impl.rest.RestRequest;
16  import com.eviware.soapui.impl.rest.support.XmlBeansRestParamsTestPropertyHolder;
17  import com.eviware.soapui.impl.rest.support.XmlBeansRestParamsTestPropertyHolder.RestParamProperty;
18  import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
19  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.AttachmentUtils;
20  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.RestRequestDataSource;
21  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.RestRequestMimeMessageRequestEntity;
22  import com.eviware.soapui.impl.wsdl.support.PathUtils;
23  import com.eviware.soapui.model.iface.Attachment;
24  import com.eviware.soapui.model.iface.SubmitContext;
25  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
26  import com.eviware.soapui.support.StringUtils;
27  import com.eviware.soapui.support.types.StringToStringMap;
28  import org.apache.commons.httpclient.HttpMethod;
29  import org.apache.commons.httpclient.URI;
30  import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
31  import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
32  import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
33  import org.apache.commons.httpclient.methods.StringRequestEntity;
34  import org.apache.xmlbeans.XmlBoolean;
35  
36  import javax.activation.DataHandler;
37  import javax.mail.MessagingException;
38  import javax.mail.internet.MimeBodyPart;
39  import javax.mail.internet.MimeMessage;
40  import javax.mail.internet.MimeMultipart;
41  import javax.mail.internet.PreencodedMimeBodyPart;
42  import java.io.UnsupportedEncodingException;
43  import java.net.URLEncoder;
44  import java.util.ArrayList;
45  import java.util.List;
46  
47  /***
48   * RequestFilter that adds SOAP specific headers
49   *
50   * @author Ole.Matzura
51   */
52  
53  public class RestRequestFilter extends AbstractRequestFilter
54  {
55     @SuppressWarnings( "deprecation" )
56     @Override
57     public void filterRestRequest( SubmitContext context, RestRequest request )
58     {
59        HttpMethod httpMethod = (HttpMethod) context.getProperty( BaseHttpRequestTransport.HTTP_METHOD );
60  
61        String path = request.getPath();
62        StringBuffer query = new StringBuffer();
63  
64        StringToStringMap responseProperties = (StringToStringMap) context.getProperty( BaseHttpRequestTransport.RESPONSE_PROPERTIES );
65  
66        XmlBeansRestParamsTestPropertyHolder params = request.getParams();
67        for( int c = 0; c < params.getPropertyCount(); c++ )
68        {
69           RestParamProperty param = params.getPropertyAt( c );
70  
71           String value = PropertyExpansionUtils.expandProperties( context, param.getValue() );
72           if( !param.isDisableUrlEncoding() )
73              value = URLEncoder.encode( value );
74  
75           responseProperties.put( param.getName(), value );
76  
77           if( !StringUtils.hasContent( value ) && !param.getRequired() )
78              continue;
79  
80           switch( param.getStyle() )
81           {
82              case HEADER:
83                 httpMethod.setRequestHeader( param.getName(), value );
84                 break;
85              case QUERY:
86                 if( query.length() > 0 )
87                    query.append( '&' );
88  
89                 query.append( URLEncoder.encode( param.getName() ) );
90                 if( StringUtils.hasContent( value ) )
91                    query.append( '=' ).append( value );
92                 break;
93              case TEMPLATE:
94                 path = path.replaceAll( "//{" + param.getName() + "//}", value );
95                 break;
96              case MATRIX:
97                 if( param.getType().equals( XmlBoolean.type.getName() ) )
98                 {
99                    if( value.toUpperCase().equals( "TRUE" ) || value.equals( "1" ) )
100                   {
101                      path += ";" + param.getName();
102                   }
103                }
104                else
105                {
106                   path += ";" + param.getName();
107                   if( StringUtils.hasContent( value ) )
108                   {
109                      path += "=" + value;
110                   }
111                }
112             case PLAIN:
113                break;
114          }
115       }
116 
117       if( PathUtils.isHttpPath( path ) )
118       {
119          try
120          {
121             httpMethod.setURI( new URI( path ) );
122          }
123          catch( Exception e )
124          {
125             e.printStackTrace();
126          }
127       }
128       else
129       {
130          httpMethod.setPath( path );
131       }
132 
133       if( query.length() > 0 && !request.isPostQueryString() )
134       {
135          httpMethod.setQueryString( query.toString() );
136       }
137 
138       String acceptEncoding = request.getAccept();
139       if( StringUtils.hasContent( acceptEncoding ) )
140       {
141          httpMethod.setRequestHeader( "Accept", acceptEncoding );
142       }
143 
144       String encoding = StringUtils.unquote( request.getEncoding() );
145 
146       if( request.hasRequestBody() && httpMethod instanceof EntityEnclosingMethod )
147       {
148          httpMethod.setRequestHeader( "Content-Type", request.getMediaType() );
149 
150          if( request.isPostQueryString() )
151          {
152             ( (EntityEnclosingMethod) httpMethod ).setRequestEntity( new StringRequestEntity( query.toString() ) );
153          }
154          else
155          {
156             String requestContent = request.getRequestContent();
157             List<Attachment> attachments = new ArrayList<Attachment>();
158 
159             for( Attachment attachment : request.getAttachments() )
160             {
161                if( attachment.getContentType().equals( request.getMediaType() ) )
162                {
163                   attachments.add( attachment );
164                }
165             }
166 
167             if( StringUtils.hasContent( requestContent ) && attachments.isEmpty() )
168             {
169                try
170                {
171                   byte[] content = encoding == null ? requestContent.getBytes() : requestContent.getBytes( encoding );
172                   ( (EntityEnclosingMethod) httpMethod ).setRequestEntity( new ByteArrayRequestEntity( content ) );
173                }
174                catch( UnsupportedEncodingException e )
175                {
176                   ( (EntityEnclosingMethod) httpMethod ).setRequestEntity( new ByteArrayRequestEntity( requestContent.getBytes() ) );
177                }
178             }
179             else if( attachments.size() > 0 )
180             {
181                try
182                {
183                   MimeMultipart mp = null;
184 
185                   if( StringUtils.hasContent( requestContent ) )
186                   {
187                      mp = new MimeMultipart();
188                      initRootPart( request, requestContent, mp );
189                   }
190                   else if( attachments.size() == 1 )
191                   {
192                      ( (EntityEnclosingMethod) httpMethod ).setRequestEntity( new InputStreamRequestEntity(
193                              attachments.get( 0 ).getInputStream() ) );
194 
195                      httpMethod.setRequestHeader( "Content-Type", request.getMediaType() );
196                   }
197 
198                   if( ( (EntityEnclosingMethod) httpMethod ).getRequestEntity() == null )
199                   {
200                      if( mp == null )
201                         mp = new MimeMultipart();
202 
203                      // init mimeparts
204                      AttachmentUtils.addMimeParts( request, attachments, mp, new StringToStringMap() );
205 
206                      // create request message
207                      MimeMessage message = new MimeMessage( AttachmentUtils.JAVAMAIL_SESSION );
208                      message.setContent( mp );
209                      message.saveChanges();
210                      RestRequestMimeMessageRequestEntity mimeMessageRequestEntity = new RestRequestMimeMessageRequestEntity( message, request );
211                      ( (EntityEnclosingMethod) httpMethod ).setRequestEntity( mimeMessageRequestEntity );
212                      httpMethod.setRequestHeader( "Content-Type", mimeMessageRequestEntity.getContentType() );
213                      httpMethod.setRequestHeader( "MIME-Version", "1.0" );
214                   }
215                }
216                catch( Exception e )
217                {
218                   e.printStackTrace();
219                }
220             }
221          }
222       }
223    }
224 
225    protected void initRootPart( RestRequest wsdlRequest, String requestContent, MimeMultipart mp ) throws MessagingException
226    {
227       MimeBodyPart rootPart = new PreencodedMimeBodyPart( "8bit" );
228       rootPart.setContentID( AttachmentUtils.ROOTPART_SOAPUI_ORG );
229       mp.addBodyPart( rootPart, 0 );
230 
231       DataHandler dataHandler = new DataHandler( new RestRequestDataSource( wsdlRequest, requestContent ) );
232       rootPart.setDataHandler( dataHandler );
233    }
234 }