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