1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.submit.transports.http;
14
15 import java.io.ByteArrayOutputStream;
16 import java.io.StringWriter;
17 import java.lang.ref.WeakReference;
18 import java.util.Vector;
19
20 import javax.xml.namespace.QName;
21
22 import org.apache.commons.codec.binary.Base64;
23 import org.apache.commons.codec.binary.Hex;
24 import org.apache.commons.httpclient.Header;
25 import org.apache.commons.httpclient.HeaderElement;
26 import org.apache.commons.httpclient.NameValuePair;
27 import org.apache.xmlbeans.SchemaGlobalElement;
28 import org.apache.xmlbeans.SchemaType;
29 import org.apache.xmlbeans.SchemaTypeSystem;
30 import org.apache.xmlbeans.XmlCursor;
31 import org.apache.xmlbeans.XmlHexBinary;
32 import org.apache.xmlbeans.XmlObject;
33 import org.w3c.dom.Document;
34 import org.w3c.dom.Element;
35 import org.w3c.dom.Node;
36
37 import com.eviware.soapui.SoapUI;
38 import com.eviware.soapui.impl.wsdl.WsdlRequest;
39 import com.eviware.soapui.impl.wsdl.submit.filters.WssRequestFilter;
40 import com.eviware.soapui.impl.wsdl.support.wss.IncomingWss;
41 import com.eviware.soapui.impl.wsdl.support.wss.WssContainer;
42 import com.eviware.soapui.impl.wsdl.support.xsd.SchemaUtils;
43 import com.eviware.soapui.model.iface.Attachment;
44 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContext;
45 import com.eviware.soapui.settings.HttpSettings;
46 import com.eviware.soapui.support.Tools;
47 import com.eviware.soapui.support.types.StringToStringMap;
48 import com.eviware.soapui.support.xml.XmlUtils;
49
50 /***
51 * WsdlMockResponse for a MimeResponse
52 *
53 * @author ole.matzura
54 */
55
56 public class MimeMessageResponse implements WsdlResponse
57 {
58 private final WeakReference<WsdlRequest> wsdlRequest;
59 private long timeTaken;
60 private long responseContentLength;
61 private StringToStringMap requestHeaders;
62 private StringToStringMap responseHeaders;
63 private final String requestContent;
64 private SSLInfo sslInfo;
65 private MultipartMessageSupport mmSupport;
66 private long timestamp;
67 private Vector wssResult;
68 private PostResponseDataSource postResponseDataSource;
69 private byte[] requestData;
70
71 public MimeMessageResponse(WsdlRequest wsdlRequest, final TimeablePostMethod postMethod, String requestContent, PropertyExpansionContext context)
72 {
73 this.wsdlRequest = new WeakReference<WsdlRequest>( wsdlRequest );
74 this.requestContent = requestContent;
75 this.timeTaken = postMethod.getTimeTaken();
76 this.timestamp = System.currentTimeMillis();
77
78 try
79 {
80 initHeaders( postMethod );
81 sslInfo = postMethod.getSSLInfo();
82 postResponseDataSource = new PostResponseDataSource( postMethod );
83 responseContentLength = postResponseDataSource.getDataSize();
84
85 Header h = postMethod.getResponseHeader( "Content-Type" );
86 HeaderElement[] elements = h.getElements();
87
88 String rootPartId = null;
89 String multipartType = null;
90
91 for( HeaderElement element : elements )
92 {
93 String name = element.getName().toUpperCase();
94 if( name.startsWith( "MULTIPART/" ))
95 {
96 NameValuePair parameter = element.getParameterByName("start");
97 if (parameter != null)
98 rootPartId = parameter.getValue();
99
100 parameter = element.getParameterByName("type");
101 if (parameter != null)
102 multipartType = parameter.getValue();
103 }
104 }
105
106 mmSupport = new MultipartMessageSupport( postResponseDataSource, rootPartId, wsdlRequest.getOperation(), false,
107 wsdlRequest.isPrettyPrint() );
108
109 processIncomingWss( wsdlRequest, context );
110
111 if (wsdlRequest.getSettings().getBoolean(HttpSettings.INCLUDE_RESPONSE_IN_TIME_TAKEN))
112 this.timeTaken = postMethod.getTimeTakenUntilNow();
113
114 if (wsdlRequest.isExpandMtomResponseAttachments() && "application/xop+xml".equals( multipartType ))
115 {
116 expandMtomAttachments( wsdlRequest );
117 }
118
119 ByteArrayOutputStream out = new ByteArrayOutputStream();
120 postMethod.getRequestEntity().writeRequest( out );
121 requestData = out.toByteArray();
122 }
123 catch ( Exception e)
124 {
125 SoapUI.logError( e );
126 }
127 }
128
129 private void processIncomingWss( WsdlRequest wsdlRequest, PropertyExpansionContext context )
130 {
131 IncomingWss incomingWss = ( IncomingWss ) context.getProperty( WssRequestFilter.INCOMING_WSS_PROPERTY );
132 if( incomingWss != null )
133 {
134 try
135 {
136 Document document = XmlUtils.parseXml( mmSupport.getContentAsString() );
137 wssResult = incomingWss.processIncoming( document, context );
138 if( wssResult != null && wssResult.size() > 0 )
139 {
140 StringWriter writer = new StringWriter();
141 XmlUtils.serializePretty( document, writer );
142 mmSupport.setResponseContent( writer.toString() );
143 }
144 }
145 catch( Exception e )
146 {
147 if( wssResult == null )
148 wssResult = new Vector();
149 wssResult.add( e );
150 }
151 }
152 }
153
154 private void expandMtomAttachments(WsdlRequest wsdlRequest)
155 {
156 try
157 {
158 XmlObject xmlObject = XmlObject.Factory.parse(getContentAsString());
159 XmlObject[] includes = xmlObject.selectPath( "declare namespace xop='http://www.w3.org/2004/08/xop/include'; //xop:Include" );
160
161 for( XmlObject include : includes )
162 {
163 Element elm = ( Element ) include.getDomNode();
164 String href = elm.getAttribute( "href" );
165 Attachment attachment = mmSupport.getAttachmentWithContentId( "<" + href.substring( 4 ) + ">" );
166 if( attachment != null )
167 {
168 ByteArrayOutputStream data = Tools.readAll( attachment.getInputStream(), 0 );
169 byte[] byteArray = data.toByteArray();
170
171 XmlCursor cursor = include.newCursor();
172 cursor.toParent();
173 XmlObject parentXmlObject = cursor.getObject();
174 cursor.dispose();
175
176 SchemaType schemaType = parentXmlObject.schemaType();
177 Node parentNode = elm.getParentNode();
178
179 if( schemaType.isNoType())
180 {
181 SchemaTypeSystem typeSystem = wsdlRequest.getOperation().getInterface().getWsdlContext().getSchemaTypeSystem();
182 SchemaGlobalElement schemaElement = typeSystem.findElement( new QName( parentNode.getNamespaceURI(), parentNode.getLocalName() ) );
183 if( schemaElement != null )
184 {
185 schemaType = schemaElement.getType();
186 }
187 }
188
189 String txt = null;
190
191 if( SchemaUtils.isInstanceOf( schemaType, XmlHexBinary.type ))
192 {
193 txt = new String( Hex.encodeHex( byteArray ));
194 }
195 else
196 {
197 txt = new String( Base64.encodeBase64( byteArray ));
198 }
199
200
201 parentNode.replaceChild( elm.getOwnerDocument().createTextNode( txt ), elm );
202 }
203 }
204
205 mmSupport.setResponseContent( xmlObject.toString() );
206 }
207 catch( Exception e )
208 {
209 SoapUI.logError( e );
210 }
211 }
212
213 public SSLInfo getSSLInfo()
214 {
215 return sslInfo;
216 }
217
218 public long getContentLength()
219 {
220 return responseContentLength;
221 }
222
223 public WsdlRequest getRequest()
224 {
225 return wsdlRequest.get();
226 }
227
228 public long getTimeTaken()
229 {
230 return timeTaken;
231 }
232
233 private void initHeaders(TimeablePostMethod postMethod)
234 {
235 requestHeaders = new StringToStringMap();
236 Header[] headers = postMethod.getRequestHeaders();
237 for( Header header : headers )
238 {
239 requestHeaders.put( header.getName(), header.getValue() );
240 }
241
242 responseHeaders = new StringToStringMap();
243 headers = postMethod.getResponseHeaders();
244 for( Header header : headers )
245 {
246 responseHeaders.put( header.getName(), header.getValue() );
247 }
248
249 responseHeaders.put( "#status#", postMethod.getStatusLine().toString() );
250 }
251
252 public StringToStringMap getRequestHeaders()
253 {
254 return requestHeaders;
255 }
256
257 public StringToStringMap getResponseHeaders()
258 {
259 return responseHeaders;
260 }
261
262 public String getRequestContent()
263 {
264 return requestContent;
265 }
266
267 public void setResponseContent( String responseContent )
268 {
269 String oldContent = getContentAsString();
270 mmSupport.setResponseContent( responseContent );
271
272 getRequest().notifyPropertyChanged( WsdlRequest.RESPONSE_CONTENT_PROPERTY, oldContent, responseContent );
273 }
274
275 public Attachment[] getAttachments()
276 {
277 return mmSupport.getAttachments();
278 }
279
280 public Attachment[] getAttachmentsForPart( String partName )
281 {
282 return mmSupport.getAttachmentsForPart( partName );
283 }
284
285 public String getContentAsString()
286 {
287 return mmSupport.getContentAsString();
288 }
289
290 public long getTimestamp()
291 {
292 return timestamp;
293 }
294
295 public Vector getWssResult()
296 {
297 return wssResult;
298 }
299
300 public byte[] getRawRequestData()
301 {
302 return requestData;
303 }
304
305 public byte[] getRawResponseData()
306 {
307 return postResponseDataSource.getData();
308 }
309 }