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
17 import javax.xml.namespace.QName;
18
19 import org.apache.commons.codec.binary.Base64;
20 import org.apache.commons.codec.binary.Hex;
21 import org.apache.commons.httpclient.Header;
22 import org.apache.commons.httpclient.HeaderElement;
23 import org.apache.commons.httpclient.NameValuePair;
24 import org.apache.xmlbeans.SchemaGlobalElement;
25 import org.apache.xmlbeans.SchemaType;
26 import org.apache.xmlbeans.SchemaTypeSystem;
27 import org.apache.xmlbeans.XmlCursor;
28 import org.apache.xmlbeans.XmlHexBinary;
29 import org.apache.xmlbeans.XmlObject;
30 import org.w3c.dom.Element;
31 import org.w3c.dom.Node;
32
33 import com.eviware.soapui.impl.wsdl.WsdlRequest;
34 import com.eviware.soapui.impl.wsdl.support.xsd.SchemaUtils;
35 import com.eviware.soapui.model.iface.Attachment;
36 import com.eviware.soapui.model.iface.Request;
37 import com.eviware.soapui.settings.HttpSettings;
38 import com.eviware.soapui.support.Tools;
39 import com.eviware.soapui.support.types.StringToStringMap;
40
41 public class MimeMessageResponse implements WsdlResponse
42 {
43 private final WsdlRequest wsdlRequest;
44 private long timeTaken;
45 private long responseContentLength;
46 private StringToStringMap requestHeaders;
47 private StringToStringMap responseHeaders;
48 private final String requestContent;
49 private SSLInfo sslInfo;
50 private MultipartMessageSupport mmSupport;
51 private long timestamp;
52
53 public MimeMessageResponse(WsdlRequest wsdlRequest, final TimeablePostMethod postMethod, String requestContent)
54 {
55 this.wsdlRequest = wsdlRequest;
56 this.requestContent = requestContent;
57 this.timeTaken = postMethod.getTimeTaken();
58 this.timestamp = System.currentTimeMillis();
59
60 try
61 {
62 initHeaders( postMethod );
63 sslInfo = postMethod.getSSLInfo();
64 PostResponseDataSource postResponseDataSource = new PostResponseDataSource( postMethod );
65 responseContentLength = postResponseDataSource.getDataSize();
66
67 Header h = postMethod.getResponseHeader( "Content-Type" );
68 HeaderElement[] elements = h.getElements();
69
70 String rootPartId = null;
71 String multipartType = null;
72
73 for( HeaderElement element : elements )
74 {
75 String name = element.getName().toUpperCase();
76 if( name.startsWith( "MULTIPART/" ))
77 {
78 NameValuePair parameter = element.getParameterByName("start");
79 if (parameter != null)
80 rootPartId = parameter.getValue();
81
82 parameter = element.getParameterByName("type");
83 if (parameter != null)
84 multipartType = parameter.getValue();
85 }
86 }
87
88 mmSupport = new MultipartMessageSupport( postResponseDataSource, rootPartId );
89
90 if (wsdlRequest.getSettings().getBoolean(HttpSettings.INCLUDE_RESPONSE_IN_TIME_TAKEN))
91 this.timeTaken = postMethod.getTimeTakenUntilNow();
92
93 if (wsdlRequest.isExpandMtomResponseAttachments() && "application/xop+xml".equals( multipartType ))
94 {
95 expandMtomAttachments();
96 }
97 }
98 catch ( Exception e)
99 {
100 e.printStackTrace();
101 }
102 }
103
104 private void expandMtomAttachments()
105 {
106 try
107 {
108 XmlObject xmlObject = XmlObject.Factory.parse(getContentAsString());
109 XmlObject[] includes = xmlObject.selectPath( "declare namespace xop='http://www.w3.org/2004/08/xop/include'; //xop:Include" );
110
111 for( XmlObject include : includes )
112 {
113 Element elm = ( Element ) include.getDomNode();
114 String href = elm.getAttribute( "href" );
115 Attachment attachment = mmSupport.getAttachmentWithContentId( "<" + href.substring( 4 ) + ">" );
116 if( attachment != null )
117 {
118 ByteArrayOutputStream data = Tools.readAll( attachment.getInputStream(), 0 );
119 byte[] byteArray = data.toByteArray();
120
121 XmlCursor cursor = include.newCursor();
122 cursor.toParent();
123 XmlObject parentXmlObject = cursor.getObject();
124 cursor.dispose();
125
126 SchemaType schemaType = parentXmlObject.schemaType();
127 Node parentNode = elm.getParentNode();
128
129 if( schemaType.isNoType())
130 {
131 SchemaTypeSystem typeSystem = wsdlRequest.getOperation().getInterface().getWsdlContext().getSchemaTypeSystem();
132 SchemaGlobalElement schemaElement = typeSystem.findElement( new QName( parentNode.getNamespaceURI(), parentNode.getLocalName() ) );
133 if( schemaElement != null )
134 {
135 schemaType = schemaElement.getType();
136 }
137 }
138
139 String txt = null;
140
141 if( SchemaUtils.isInstanceOf( schemaType, XmlHexBinary.type ))
142 {
143 txt = new String( Hex.encodeHex( byteArray ));
144 }
145 else
146 {
147 txt = new String( Base64.encodeBase64( byteArray ));
148 }
149
150
151 parentNode.replaceChild( elm.getOwnerDocument().createTextNode( txt ), elm );
152 }
153 }
154
155 mmSupport.setResponseContent( xmlObject.toString() );
156 }
157 catch( Exception e )
158 {
159 e.printStackTrace();
160 }
161 }
162
163 public SSLInfo getSSLInfo()
164 {
165 return sslInfo;
166 }
167
168 public long getContentLength()
169 {
170 return responseContentLength;
171 }
172
173 public Request getRequest()
174 {
175 return wsdlRequest;
176 }
177
178 public long getTimeTaken()
179 {
180 return timeTaken;
181 }
182
183 private void initHeaders(TimeablePostMethod postMethod)
184 {
185 requestHeaders = new StringToStringMap();
186 Header[] headers = postMethod.getRequestHeaders();
187 for( Header header : headers )
188 {
189 requestHeaders.put( header.getName(), header.getValue() );
190 }
191
192 responseHeaders = new StringToStringMap();
193 headers = postMethod.getResponseHeaders();
194 for( Header header : headers )
195 {
196 responseHeaders.put( header.getName(), header.getValue() );
197 }
198
199 responseHeaders.put( "#status#", postMethod.getStatusLine().toString() );
200 }
201
202 public StringToStringMap getRequestHeaders()
203 {
204 return requestHeaders;
205 }
206
207 public StringToStringMap getResponseHeaders()
208 {
209 return responseHeaders;
210 }
211
212 public String getRequestContent()
213 {
214 return requestContent;
215 }
216
217 public void setResponseContent( String responseContent )
218 {
219 mmSupport.setResponseContent( responseContent );
220 }
221
222 public Attachment[] getAttachments()
223 {
224 return mmSupport.getAttachments();
225 }
226
227 public Attachment[] getAttachmentsForPart( String partName )
228 {
229 return mmSupport.getAttachmentsForPart( partName );
230 }
231
232 public String getContentAsString()
233 {
234 return mmSupport.getContentAsString();
235 }
236
237 public long getTimestamp()
238 {
239 return timestamp;
240 }
241 }