View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 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.mock;
14  
15  import java.io.ByteArrayOutputStream;
16  import java.io.IOException;
17  import java.io.StringWriter;
18  import java.util.Enumeration;
19  import java.util.Vector;
20  
21  import javax.mail.MessagingException;
22  import javax.servlet.ServletInputStream;
23  import javax.servlet.http.HttpServletRequest;
24  import javax.servlet.http.HttpServletResponse;
25  
26  import org.apache.xmlbeans.XmlException;
27  import org.apache.xmlbeans.XmlObject;
28  import org.w3c.dom.Document;
29  
30  import com.eviware.soapui.SoapUI;
31  import com.eviware.soapui.impl.wsdl.WsdlOperation;
32  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.MockRequestDataSource;
33  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.MultipartMessageSupport;
34  import com.eviware.soapui.impl.wsdl.support.soap.SoapUtils;
35  import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
36  import com.eviware.soapui.impl.wsdl.support.wss.IncomingWss;
37  import com.eviware.soapui.model.iface.Attachment;
38  import com.eviware.soapui.model.mock.MockRequest;
39  import com.eviware.soapui.settings.WsdlSettings;
40  import com.eviware.soapui.support.StringUtils;
41  import com.eviware.soapui.support.Tools;
42  import com.eviware.soapui.support.types.StringToStringMap;
43  import com.eviware.soapui.support.xml.XmlUtils;
44  
45  /***
46   * Request-class created when receiving an external request to a WsdlMockService
47   * 
48   * @author ole.matzura
49   */
50  
51  public class WsdlMockRequest implements MockRequest
52  {
53  	private StringToStringMap requestHeaders;
54  	private String requestContent;
55  	private MultipartMessageSupport mmSupport;
56  	private XmlObject requestXmlObject;
57  	private SoapVersion soapVersion;
58  	private final HttpServletResponse response;
59  	private String protocol;
60  	private String path;
61  	private String soapAction;
62  	private final WsdlMockRunContext context;
63  	private final WsdlMockRunContext requestContext;
64  	private final HttpServletRequest request;
65  	private Vector<Object> wssResult;
66  	private MockRequestDataSource mockRequestDataSource;
67  	private String actualRequestContent;
68  	private boolean responseMessage;
69  	private String method;
70  
71  	public WsdlMockRequest( HttpServletRequest request, HttpServletResponse response, WsdlMockRunContext context )
72  			throws Exception
73  	{
74  		this.request = request;
75  		this.response = response;
76  		this.context = context;
77  
78  		requestContext = new WsdlMockRunContext( context.getMockService(), null );
79  
80  		requestHeaders = new StringToStringMap();
81  		for( Enumeration<?> e = request.getHeaderNames(); e.hasMoreElements(); )
82  		{
83  			String header = ( String )e.nextElement();
84  			String lcHeader = header.toLowerCase();
85  			if( lcHeader.equals( "soapaction" ) )
86  				requestHeaders.put( "SOAPAction", request.getHeader( header ) );
87  			else if( lcHeader.equals( "content-type" ) )
88  				requestHeaders.put( "Content-Type", request.getHeader( header ) );
89  			else if( lcHeader.equals( "content-length" ) )
90  				requestHeaders.put( "Content-Length", request.getHeader( header ) );
91  			else if( lcHeader.equals( "content-encoding" ) )
92  				requestHeaders.put( "Content-Encoding", request.getHeader( header ) );
93  			else
94  				requestHeaders.put( header, request.getHeader( header ) );
95  		}
96  
97  		protocol = request.getProtocol();
98  		path = request.getPathInfo();
99  
100 		if( request.getMethod().equals( "POST" ) )
101 		{
102 			initPostRequest( request, context );
103 		}
104 	}
105 
106 	protected void initPostRequest( HttpServletRequest request, WsdlMockRunContext context ) throws Exception
107 	{
108 		String contentType = request.getContentType();
109 
110 		if( contentType != null && contentType.toUpperCase().startsWith( "MULTIPART" ) )
111 		{
112 			readMultipartRequest( request );
113 			contentType = mmSupport.getRootPart().getContentType();
114 		}
115 		else
116 		{
117 			this.requestContent = readRequestContent( request );
118 
119 			if( StringUtils.hasContent( context.getMockService().getIncomingWss() ) )
120 			{
121 				IncomingWss incoming = context.getMockService().getProject().getWssContainer().getIncomingWssByName(
122 						context.getMockService().getIncomingWss() );
123 				if( incoming != null )
124 				{
125 					Document dom = XmlUtils.parseXml( requestContent );
126 					try
127 					{
128 						wssResult = incoming.processIncoming( dom, context );
129 						if( wssResult != null && wssResult.size() > 0 )
130 						{
131 							StringWriter writer = new StringWriter();
132 							XmlUtils.serialize( dom, writer );
133 							actualRequestContent = requestContent;
134 							requestContent = writer.toString();
135 						}
136 					}
137 					catch( Exception e )
138 					{
139 						if( wssResult == null )
140 							wssResult = new Vector<Object>();
141 						wssResult.add( e );
142 					}
143 				}
144 			}
145 		}
146 
147 		soapVersion = SoapUtils.deduceSoapVersion( contentType, getRequestXmlObject() );
148 		if( soapVersion == null )
149 			soapVersion = SoapVersion.Soap11;
150 
151 		soapAction = SoapUtils.getSoapAction( soapVersion, requestHeaders );
152 	}
153 
154 	public SoapVersion getSoapVersion()
155 	{
156 		return soapVersion;
157 	}
158 
159 	public String getProtocol()
160 	{
161 		return protocol;
162 	}
163 
164 	public Vector<?> getWssResult()
165 	{
166 		return wssResult;
167 	}
168 
169 	private void readMultipartRequest( HttpServletRequest request ) throws MessagingException
170 	{
171 		StringToStringMap values = StringToStringMap.fromHttpHeader( request.getContentType() );
172 		mockRequestDataSource = new MockRequestDataSource( request );
173 		mmSupport = new MultipartMessageSupport( mockRequestDataSource, values.get( "start" ), null, true, requestContext
174 				.getMockService().getSettings().getBoolean( WsdlSettings.PRETTY_PRINT_RESPONSE_MESSAGES ) );
175 	}
176 
177 	private String readRequestContent( HttpServletRequest request ) throws Exception
178 	{
179 		String responseContent = null;
180 		String encoding = request.getCharacterEncoding();
181 		if( encoding != null )
182 			encoding = StringUtils.unquote( encoding );
183 
184 		ServletInputStream is = request.getInputStream();
185 		if( is.markSupported() && request.getContentLength() > 0 )
186 			is.mark( request.getContentLength() );
187 
188 		ByteArrayOutputStream out = Tools.readAll( is, Tools.READ_ALL );
189 		byte[] data = out.toByteArray();
190 
191 		if( is.markSupported() && request.getContentLength() > 0 )
192 		{
193 			try
194 			{
195 			is.reset();
196 			}
197 			catch( IOException e )
198 			{
199 				SoapUI.logError( e );
200 			}
201 		}
202 
203 		int contentOffset = 0;
204 
205 		String contentType = request.getContentType();
206 		if( contentType != null && data.length > 0 )
207 		{
208 			if( contentType.toLowerCase().endsWith( "xml" ) )
209 			{
210 				if( data.length > 3 && data[0] == ( byte )239 && data[1] == ( byte )187 && data[2] == ( byte )191 )
211 				{
212 					encoding = "UTF-8";
213 					contentOffset = 3;
214 				}
215 			}
216 
217 			encoding = StringUtils.unquote( encoding );
218 
219 			responseContent = encoding == null ? new String( data ) : new String( data, contentOffset,
220 					( int )( data.length - contentOffset ), encoding );
221 		}
222 
223 		if( encoding == null )
224 			encoding = "UTF-8";
225 
226 		if( responseContent == null )
227 		{
228 			responseContent = new String( data, encoding );
229 		}
230 
231 		return responseContent;
232 	}
233 
234 	public Attachment[] getRequestAttachments()
235 	{
236 		return mmSupport == null ? new Attachment[0] : mmSupport.getAttachments();
237 	}
238 
239 	public String getRequestContent()
240 	{
241 		return mmSupport == null ? requestContent : mmSupport.getContentAsString();
242 	}
243 
244 	public StringToStringMap getRequestHeaders()
245 	{
246 		return requestHeaders;
247 	}
248 
249 	public void setRequestContent( String requestContent )
250 	{
251 		this.requestContent = requestContent;
252 		requestXmlObject = null;
253 
254 		try
255 		{
256 			soapVersion = SoapUtils.deduceSoapVersion( request.getContentType(), getRequestXmlObject() );
257 		}
258 		catch( XmlException e )
259 		{
260 			SoapUI.logError( e );
261 		}
262 
263 		if( soapVersion == null )
264 			soapVersion = SoapVersion.Soap11;
265 	}
266 
267 	public XmlObject getRequestXmlObject() throws XmlException
268 	{
269 		if( requestXmlObject == null )
270 			requestXmlObject = XmlObject.Factory.parse( getRequestContent() );
271 
272 		return requestXmlObject;
273 	}
274 
275 	public HttpServletResponse getHttpResponse()
276 	{
277 		return response;
278 	}
279 
280 	public HttpServletRequest getHttpRequest()
281 	{
282 		return request;
283 	}
284 
285 	public String getMethod()
286 	{
287 		return method == null ? request.getMethod() : method;
288 	}
289 
290 	public void setMethod( String method )
291 	{
292 		this.method = method;
293 	}
294 
295 	public XmlObject getContentElement() throws XmlException
296 	{
297 		return SoapUtils.getContentElement( getRequestXmlObject(), soapVersion );
298 	}
299 
300 	public String getPath()
301 	{
302 		return path;
303 	}
304 
305 	public WsdlMockRunContext getContext()
306 	{
307 		return context;
308 	}
309 
310 	public void setOperation( WsdlOperation operation )
311 	{
312 		if( mmSupport != null )
313 			mmSupport.setOperation( operation );
314 	}
315 
316 	public WsdlMockRunContext getRequestContext()
317 	{
318 		return requestContext;
319 	}
320 
321 	public String getSoapAction()
322 	{
323 		return soapAction;
324 	}
325 
326 	public void setSoapAction( String soapAction )
327 	{
328 		this.soapAction = soapAction;
329 	}
330 
331 	public byte[] getRawRequestData()
332 	{
333 		return mockRequestDataSource == null ? actualRequestContent == null ? requestContent.getBytes()
334 				: actualRequestContent.getBytes() : mockRequestDataSource.getData();
335 	}
336 
337 	public void setResponseMessage( boolean responseMessage )
338 	{
339 		this.responseMessage = responseMessage;
340 	}
341 
342 	public boolean isResponseMessage()
343 	{
344 		return responseMessage;
345 	}
346 }