1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.monitor;
14
15 import com.eviware.soapui.SoapUI;
16 import com.eviware.soapui.impl.wsdl.WsdlOperation;
17 import com.eviware.soapui.impl.wsdl.WsdlProject;
18 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.MultipartMessageSupport;
19 import com.eviware.soapui.impl.wsdl.support.soap.SoapUtils;
20 import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
21 import com.eviware.soapui.impl.wsdl.support.wss.IncomingWss;
22 import com.eviware.soapui.model.iface.Attachment;
23 import com.eviware.soapui.model.iface.Interface;
24 import com.eviware.soapui.model.iface.Operation;
25 import com.eviware.soapui.model.propertyexpansion.DefaultPropertyExpansionContext;
26 import com.eviware.soapui.settings.WsdlSettings;
27 import com.eviware.soapui.support.Tools;
28 import com.eviware.soapui.support.types.StringToStringMap;
29 import com.eviware.soapui.support.xml.XmlUtils;
30 import org.apache.commons.httpclient.Header;
31 import org.apache.commons.httpclient.HttpParser;
32 import org.apache.xmlbeans.XmlObject;
33 import org.w3c.dom.Document;
34
35 import java.io.ByteArrayInputStream;
36 import java.io.IOException;
37 import java.io.StringWriter;
38 import java.net.URL;
39 import java.util.ArrayList;
40 import java.util.List;
41 import java.util.Vector;
42
43 public class TcpMonWsdlMonitorMessageExchange extends WsdlMonitorMessageExchange
44 {
45 private URL targetUrl;
46 private StringToStringMap responseHeaders;
47 private long timeTaken;
48 private long timestamp;
49 private StringToStringMap requestHeaders;
50 private String requestContent;
51 private String responseContent;
52 private int responseContentLength;
53 private int requestContentLength;
54 private String requestHost;
55 private WsdlProject project;
56 private WsdlOperation operation;
57 private byte[] capturedRequestData;
58 private byte[] capturedResponseData;
59 private String responseContentType;
60 private MultipartMessageSupport responseMmSupport;
61
62 private static final String HTTP_ELEMENT_CHARSET = "US-ASCII";
63 private SoapVersion soapVersion;
64 private MultipartMessageSupport requestMmSupport;
65 private String requestContentType;
66 private boolean discarded;
67 private Vector requestWssResult;
68 private Vector responseWssResult;
69
70 public TcpMonWsdlMonitorMessageExchange( WsdlProject project )
71 {
72 super( null );
73 this.project = project;
74 responseHeaders = new StringToStringMap();
75 requestHeaders = new StringToStringMap();
76 timestamp = System.currentTimeMillis();
77 }
78
79 @Override
80 public WsdlOperation getOperation()
81 {
82 return operation;
83 }
84
85 public Attachment[] getRequestAttachments()
86 {
87 return requestMmSupport == null ? new Attachment[0] : requestMmSupport.getAttachments();
88 }
89
90 public String getRequestContent()
91 {
92 return requestMmSupport == null ? requestContent : requestMmSupport.getContentAsString();
93 }
94
95 public StringToStringMap getRequestHeaders()
96 {
97 return requestHeaders;
98 }
99
100 public Attachment[] getResponseAttachments()
101 {
102 return responseMmSupport == null ? new Attachment[0] : responseMmSupport.getAttachments();
103 }
104
105 public String getResponseContent()
106 {
107 return responseMmSupport == null ? responseContent : responseMmSupport.getContentAsString();
108 }
109
110 public StringToStringMap getResponseHeaders()
111 {
112 return responseHeaders;
113 }
114
115 public long getTimeTaken()
116 {
117 return timeTaken;
118 }
119
120 public long getTimestamp()
121 {
122 return timestamp;
123 }
124
125 public void setTargetUrl( URL targetHost )
126 {
127 this.targetUrl = targetHost;
128 }
129
130 public boolean isActive()
131 {
132 return false;
133 }
134
135 public long getRequestContentLength()
136 {
137 return requestContentLength;
138 }
139
140 public long getResponseContentLength()
141 {
142 return responseContentLength;
143 }
144
145 public String getRequestHost()
146 {
147 return requestHost;
148 }
149
150 public URL getTargetUrl()
151 {
152 return targetUrl;
153 }
154
155 public byte[] getRawRequestData()
156 {
157 return capturedRequestData;
158 }
159
160 public byte[] getRawResponseData()
161 {
162 return capturedResponseData;
163 }
164
165 @Override
166 public boolean hasRawData()
167 {
168 return true;
169 }
170
171 public void finish( byte[] capturedRequestData, byte[] capturedResponseData )
172 {
173 this.capturedRequestData = capturedRequestData;
174 this.capturedResponseData = capturedResponseData;
175
176 if( timeTaken == 0 )
177 timeTaken = System.currentTimeMillis() - timestamp;
178 }
179
180 public void prepare( IncomingWss requestWss, IncomingWss responseWss )
181 {
182 parseRequestData( capturedRequestData, requestWss );
183 parseReponseData( capturedResponseData, responseWss );
184 }
185
186 private void parseReponseData( byte[] capturedResponseData, IncomingWss responseWss )
187 {
188 responseContentLength = capturedResponseData.length;
189 ByteArrayInputStream in = new ByteArrayInputStream( capturedResponseData );
190 try
191 {
192
193 String line = null;
194 do
195 {
196 line = HttpParser.readLine( in, HTTP_ELEMENT_CHARSET );
197 }
198 while( line != null && line.length() == 0 );
199
200 if( line == null )
201 {
202 throw new Exception( "Missing request status line" );
203 }
204
205 Header[] headers = HttpParser.parseHeaders( in, HTTP_ELEMENT_CHARSET );
206 if( headers != null )
207 {
208 for( Header header : headers )
209 {
210 responseHeaders.put( header.getName(), header.getValue() );
211 }
212 }
213
214 responseContentType = responseHeaders.get( "Content-Type" );
215 if( responseContentType != null && responseContentType.toUpperCase().startsWith( "MULTIPART" ))
216 {
217 StringToStringMap values = StringToStringMap.fromHttpHeader( responseContentType );
218 responseMmSupport = new MultipartMessageSupport(
219 new MonitorMessageExchangeDataSource( "monitor response", in, responseContentType ), values.get( "start" ), null, true,
220 SoapUI.getSettings().getBoolean( WsdlSettings.PRETTY_PRINT_RESPONSE_MESSAGES ));
221 responseContentType = responseMmSupport.getRootPart().getContentType();
222 }
223 else
224 {
225 this.responseContent = XmlUtils.prettyPrintXml( Tools.readAll( in, 0 ).toString());
226 }
227
228 processResponseWss( responseWss );
229 }
230 catch( Exception e )
231 {
232 try
233 {
234 in.close();
235 }
236 catch( IOException e1 )
237 {
238 e1.printStackTrace();
239 }
240 }
241 }
242
243 private void processResponseWss( IncomingWss responseWss ) throws IOException
244 {
245 if( responseWss != null )
246 {
247 Document dom = XmlUtils.parseXml( responseContent );
248 try
249 {
250 responseWssResult = responseWss.processIncoming( dom, new DefaultPropertyExpansionContext(project ) );
251 if( responseWssResult != null && responseWssResult.size() > 0 )
252 {
253 StringWriter writer = new StringWriter();
254 XmlUtils.serialize( dom, writer );
255 responseContent = writer.toString();
256 }
257 }
258 catch( Exception e )
259 {
260 if( responseWssResult == null )
261 responseWssResult = new Vector();
262 responseWssResult.add( e );
263 }
264 }
265 }
266
267 private void parseRequestData( byte[] capturedRequestData, IncomingWss requestWss )
268 {
269 requestContentLength = capturedRequestData.length;
270 ByteArrayInputStream in = new ByteArrayInputStream( capturedRequestData );
271 try
272 {
273
274 String line = null;
275 do
276 {
277 line = HttpParser.readLine( in, HTTP_ELEMENT_CHARSET );
278 }
279 while( line != null && line.length() == 0 );
280
281 if( line == null )
282 {
283 throw new Exception( "Missing request status line" );
284 }
285
286 Header[] headers = HttpParser.parseHeaders( in, HTTP_ELEMENT_CHARSET );
287 if( headers != null )
288 {
289 for( Header header : headers )
290 {
291 requestHeaders.put( header.getName(), header.getValue() );
292 }
293 }
294
295 requestContentType = requestHeaders.get( "Content-Type" );
296 if( requestContentType != null && requestContentType.toUpperCase().startsWith( "MULTIPART" ))
297 {
298 StringToStringMap values = StringToStringMap.fromHttpHeader( requestContentType );
299 requestMmSupport = new MultipartMessageSupport(
300 new MonitorMessageExchangeDataSource( "monitor request", in, requestContentType ), values.get( "start" ), null, true,
301 SoapUI.getSettings().getBoolean( WsdlSettings.PRETTY_PRINT_RESPONSE_MESSAGES ));
302 requestContentType = requestMmSupport.getRootPart().getContentType();
303 }
304 else
305 {
306 this.requestContent = XmlUtils.prettyPrintXml( Tools.readAll( in, 0 ).toString() );
307 }
308
309 processRequestWss( requestWss );
310
311 operation = findOperation();
312 }
313 catch( Exception e )
314 {
315 try
316 {
317 in.close();
318 }
319 catch( IOException e1 )
320 {
321 e1.printStackTrace();
322 }
323 }
324 }
325
326 private void processRequestWss( IncomingWss requestWss ) throws IOException
327 {
328 if( requestWss != null )
329 {
330 Document dom = XmlUtils.parseXml( requestContent );
331 try
332 {
333 requestWssResult = requestWss.processIncoming( dom, new DefaultPropertyExpansionContext(project ) );
334 if( requestWssResult != null && requestWssResult.size() > 0 )
335 {
336 StringWriter writer = new StringWriter();
337 XmlUtils.serialize( dom, writer );
338 requestContent = writer.toString();
339 }
340 }
341 catch( Exception e )
342 {
343 if( requestWssResult == null )
344 requestWssResult = new Vector();
345 requestWssResult.add( e );
346 }
347 }
348 }
349
350 private WsdlOperation findOperation() throws Exception
351 {
352 soapVersion = SoapUtils.deduceSoapVersion( requestContentType, getRequestContent() );
353 if( soapVersion == null )
354 throw new Exception( "Unrecognized SOAP Version" );
355
356 String soapAction = SoapUtils.getSoapAction( soapVersion, requestHeaders );
357
358 List<WsdlOperation> operations = new ArrayList<WsdlOperation>();
359 for( Interface iface : project.getInterfaceList() )
360 {
361 for( Operation operation : iface.getOperationList())
362 operations.add( ( WsdlOperation ) operation );
363 }
364
365 return SoapUtils.findOperationForRequest( soapVersion, soapAction,
366 XmlObject.Factory.parse( getRequestContent() ), operations, true, false );
367 }
368
369 public void setRequestHost( String requestHost )
370 {
371 this.requestHost = requestHost;
372 }
373
374 public SoapVersion getSoapVersion()
375 {
376 if( soapVersion == null )
377 soapVersion = SoapUtils.deduceSoapVersion( requestHeaders.get( "Content-Type" ), getRequestContent() );
378
379 return soapVersion;
380 }
381
382 public void setTimeTaken( long timeTaken )
383 {
384 this.timeTaken = timeTaken;
385 }
386
387 public void discard()
388 {
389 operation = null;
390 project = null;
391
392 requestContent = null;
393 requestHeaders = null;
394
395 responseContent = null;
396 responseHeaders = null;
397
398 requestMmSupport = null;
399
400 discarded = true;
401 }
402
403 public boolean isDiscarded()
404 {
405 return discarded;
406 }
407
408 public Vector getRequestWssResult()
409 {
410 return requestWssResult;
411 }
412
413 public Vector getResponseWssResult()
414 {
415 return responseWssResult;
416 }
417
418 public int getResponseStatusCode()
419 {
420 return 0;
421 }
422
423 public String getResponseContentType()
424 {
425 return null;
426 }
427 }