1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.monitor;
14
15 import java.io.ByteArrayInputStream;
16 import java.io.IOException;
17 import java.io.StringWriter;
18 import java.net.MalformedURLException;
19 import java.net.URL;
20 import java.util.ArrayList;
21 import java.util.Enumeration;
22 import java.util.List;
23 import java.util.Vector;
24
25 import javax.servlet.http.HttpServletRequest;
26
27 import org.apache.commons.httpclient.Header;
28 import org.apache.commons.httpclient.HttpMethodBase;
29 import org.apache.xmlbeans.XmlObject;
30 import org.w3c.dom.Document;
31
32 import com.eviware.soapui.SoapUI;
33 import com.eviware.soapui.impl.wsdl.WsdlInterface;
34 import com.eviware.soapui.impl.wsdl.WsdlOperation;
35 import com.eviware.soapui.impl.wsdl.WsdlProject;
36 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.MultipartMessageSupport;
37 import com.eviware.soapui.impl.wsdl.support.CompressionSupport;
38 import com.eviware.soapui.impl.wsdl.support.soap.SoapUtils;
39 import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
40 import com.eviware.soapui.impl.wsdl.support.wss.IncomingWss;
41 import com.eviware.soapui.model.iface.Attachment;
42 import com.eviware.soapui.model.iface.Operation;
43 import com.eviware.soapui.model.propertyexpansion.DefaultPropertyExpansionContext;
44 import com.eviware.soapui.model.support.ModelSupport;
45 import com.eviware.soapui.support.Tools;
46 import com.eviware.soapui.support.types.StringToStringMap;
47 import com.eviware.soapui.support.xml.XmlUtils;
48
49 public class JProxyServletWsdlMonitorMessageExchange extends WsdlMonitorMessageExchange
50 {
51
52 private WsdlOperation operation;
53 private WsdlProject project;
54 private String requestContent;
55 private StringToStringMap requestHeaders;
56 private String responseContent;
57 private StringToStringMap responseHeaders;
58 private MultipartMessageSupport requestMmSupport;
59 private boolean discarded;
60 private long timestampStart;
61 private byte[] request;
62 private byte[] response;
63 private String requestHost;
64 private URL targetURL;
65 private String requestContentType;
66 private Vector<Object> requestWssResult;
67 private SoapVersion soapVersion;
68 private String responseContentType;
69 private MultipartMessageSupport responseMmSupport;
70 private Vector<Object> responseWssResult;
71 private long timestampEnd;
72 private boolean capture;
73 private byte[] requestRaw = null;
74 private byte[] responseRaw = null;
75
76 public JProxyServletWsdlMonitorMessageExchange( WsdlProject project )
77 {
78 super( null );
79 responseHeaders = new StringToStringMap();
80 requestHeaders = new StringToStringMap();
81 timestampStart = System.currentTimeMillis();
82 this.project = project;
83 capture = true;
84 }
85
86 @Override
87 public void discard()
88 {
89 operation = null;
90 project = null;
91
92 requestContent = null;
93 requestHeaders = null;
94
95 responseContent = null;
96 responseHeaders = null;
97
98 requestMmSupport = null;
99
100 response = null;
101 request = null;
102 capture = false;
103
104 discarded = true;
105 }
106
107 @Override
108 public long getRequestContentLength()
109 {
110 return request == null ? -1 : request.length;
111 }
112
113 @Override
114 public String getRequestHost()
115 {
116 return requestHost;
117 }
118
119 @Override
120 public long getResponseContentLength()
121 {
122 return response == null ? -1 : response.length;
123 }
124
125 @Override
126 public URL getTargetUrl()
127 {
128 return this.targetURL;
129 }
130
131 @Override
132 public void prepare( IncomingWss incomingRequestWss, IncomingWss incomingResponseWss )
133 {
134 parseRequestData( incomingRequestWss );
135 parseReponseData( incomingResponseWss );
136 }
137
138 private void parseReponseData( IncomingWss incomingResponseWss )
139 {
140 ByteArrayInputStream in = new ByteArrayInputStream( response == null ? new byte[0] : response );
141 try
142 {
143 responseContentType = responseHeaders.get( "Content-Type" );
144 if( responseContentType != null && responseContentType.toUpperCase().startsWith( "MULTIPART" ) )
145 {
146 StringToStringMap values = StringToStringMap.fromHttpHeader( responseContentType );
147 responseMmSupport = new MultipartMessageSupport( new MonitorMessageExchangeDataSource( "monitor response",
148 in, responseContentType ), values.get( "start" ), null, true, false );
149 responseContentType = responseMmSupport.getRootPart().getContentType();
150 }
151 else
152 {
153 String charset = getCharset( responseHeaders );
154 this.responseContent = charset == null ? Tools.readAll( in, 0 ).toString() : Tools.readAll( in, 0 )
155 .toString( charset );
156 }
157
158 processResponseWss( incomingResponseWss );
159 }
160 catch( Exception e )
161 {
162 SoapUI.logError( e );
163 }
164 finally
165 {
166 try
167 {
168 in.close();
169 }
170 catch( IOException e1 )
171 {
172 SoapUI.logError( e1 );
173 }
174 }
175 }
176
177 private void processResponseWss( IncomingWss incomingResponseWss ) throws IOException
178 {
179 if( incomingResponseWss != null )
180 {
181 Document dom = XmlUtils.parseXml( responseContent );
182 try
183 {
184 responseWssResult = incomingResponseWss
185 .processIncoming( dom, new DefaultPropertyExpansionContext( project ) );
186 if( responseWssResult != null && responseWssResult.size() > 0 )
187 {
188 StringWriter writer = new StringWriter();
189 XmlUtils.serialize( dom, writer );
190 responseContent = writer.toString();
191 }
192 }
193 catch( Exception e )
194 {
195 if( responseWssResult == null )
196 responseWssResult = new Vector<Object>();
197 responseWssResult.add( e );
198 }
199 }
200
201 }
202
203 private void parseRequestData( IncomingWss incomingRequestWss )
204 {
205 ByteArrayInputStream in = request == null ? new ByteArrayInputStream( new byte[0] ) : new ByteArrayInputStream(
206 request );
207 try
208 {
209
210 requestContentType = requestHeaders.get( "Content-Type" );
211 if( requestContentType != null && requestContentType.toUpperCase().startsWith( "MULTIPART" ) )
212 {
213 StringToStringMap values = StringToStringMap.fromHttpHeader( requestContentType );
214 requestMmSupport = new MultipartMessageSupport( new MonitorMessageExchangeDataSource( "monitor request",
215 in, requestContentType ), values.get( "start" ), null, true, false );
216 requestContentType = requestMmSupport.getRootPart().getContentType();
217 }
218 else
219 {
220 String charset = getCharset( requestHeaders );
221 this.requestContent = charset == null ? Tools.readAll( in, 0 ).toString() : Tools.readAll( in, 0 )
222 .toString( charset );
223 }
224
225 processRequestWss( incomingRequestWss );
226
227 operation = findOperation();
228 }
229 catch( Exception e )
230 {
231 SoapUI.logError( e );
232 }
233 finally
234 {
235 try
236 {
237 in.close();
238 }
239 catch( IOException e1 )
240 {
241 SoapUI.logError( e1 );
242 }
243 }
244 }
245
246 private static String getCharset( StringToStringMap headers )
247 {
248 String requestContentType = headers.get( "Content-Type" );
249 if( requestContentType != null )
250 {
251 StringToStringMap values = StringToStringMap.fromHttpHeader( requestContentType );
252 if( values.containsKey( "charset" ) )
253 return values.get( "charset" );
254 }
255
256 String contentEncodingHeader = headers.get( "Content-Encoding" );
257 if( contentEncodingHeader != null )
258 {
259 try
260 {
261 if( CompressionSupport.getAvailableAlgorithm( contentEncodingHeader ) == null )
262 {
263 new String( "" ).getBytes( contentEncodingHeader );
264 return contentEncodingHeader;
265 }
266 }
267 catch( Exception e )
268 {
269 }
270 }
271
272 return null;
273 }
274
275 private WsdlOperation findOperation() throws Exception
276 {
277 soapVersion = SoapUtils.deduceSoapVersion( requestContentType, XmlObject.Factory.parse( getRequestContent() ) );
278 if( soapVersion == null )
279 throw new Exception( "Unrecognized SOAP Version" );
280
281 String soapAction = SoapUtils.getSoapAction( soapVersion, requestHeaders );
282
283 List<WsdlOperation> operations = new ArrayList<WsdlOperation>();
284 for( WsdlInterface iface : ModelSupport.getChildren( project, WsdlInterface.class ) )
285 {
286 for( Operation operation : iface.getOperationList() )
287 operations.add( ( WsdlOperation )operation );
288 }
289
290 return SoapUtils.findOperationForRequest( soapVersion, soapAction,
291 XmlObject.Factory.parse( getRequestContent() ), operations, true, false, getRequestAttachments() );
292 }
293
294 private void processRequestWss( IncomingWss incomingRequestWss ) throws IOException
295 {
296
297 if( incomingRequestWss != null )
298 {
299 Document dom = XmlUtils.parseXml( requestContent );
300 try
301 {
302 requestWssResult = incomingRequestWss.processIncoming( dom, new DefaultPropertyExpansionContext( project ) );
303 if( requestWssResult != null && requestWssResult.size() > 0 )
304 {
305 StringWriter writer = new StringWriter();
306 XmlUtils.serialize( dom, writer );
307 requestContent = writer.toString();
308 }
309 }
310 catch( Exception e )
311 {
312 if( requestWssResult == null )
313 requestWssResult = new Vector<Object>();
314 requestWssResult.add( e );
315 }
316 }
317
318 }
319
320 public WsdlOperation getOperation()
321 {
322 return operation;
323 }
324
325 public Vector<?> getRequestWssResult()
326 {
327 return requestWssResult;
328 }
329
330 public Vector<?> getResponseWssResult()
331 {
332 return responseWssResult;
333 }
334
335 public Attachment[] getRequestAttachments()
336 {
337 return requestMmSupport == null ? new Attachment[0] : requestMmSupport.getAttachments();
338 }
339
340 public String getRequestContent()
341 {
342 return requestMmSupport == null ? requestContent : requestMmSupport.getContentAsString();
343 }
344
345 public byte[] getRawRequestData()
346 {
347 if( requestRaw != null )
348 return requestRaw;
349 else
350 return request;
351 }
352
353 public void setRawRequestData( byte[] data )
354 {
355 requestRaw = data;
356 }
357
358 public byte[] getRawResponseData()
359 {
360 if( responseRaw == null )
361 return response;
362 else
363 return responseRaw;
364 }
365
366 public void setRawResponseData( byte[] data )
367 {
368 responseRaw = data;
369 }
370
371 public StringToStringMap getRequestHeaders()
372 {
373 return requestHeaders;
374 }
375
376 public Attachment[] getResponseAttachments()
377 {
378 return requestMmSupport == null ? new Attachment[0] : requestMmSupport.getAttachments();
379 }
380
381 public String getResponseContent()
382 {
383 return responseContent;
384 }
385
386 public StringToStringMap getResponseHeaders()
387 {
388 return responseHeaders;
389 }
390
391 public long getTimeTaken()
392 {
393 return timestampEnd - timestampStart;
394 }
395
396 public long getTimestamp()
397 {
398 return timestampStart;
399 }
400
401 public boolean isDiscarded()
402 {
403 return discarded;
404 }
405
406 public void stopCapture()
407 {
408 timestampEnd = System.currentTimeMillis();
409 capture = false;
410 }
411
412 public boolean isStopCapture()
413 {
414 return capture;
415 }
416
417 public void setRequest( byte[] request )
418 {
419 this.request = request;
420 }
421
422 public byte [] getRawResponseBody()
423 {
424 return response;
425 }
426
427 public void setRawResponseBody( byte[] response )
428 {
429 if( this.response == null )
430 {
431 this.response = response;
432 }
433 else
434 {
435 byte[] newResponse = new byte[this.response.length + response.length];
436 for( int i = 0; i < this.response.length; i++ )
437 {
438 newResponse[i] = this.response[i];
439 }
440 for( int i = this.response.length; i < newResponse.length; i++ )
441 {
442 newResponse[i] = response[i - this.response.length];
443 }
444 this.response = newResponse;
445 }
446 }
447
448 public void setResponseHeader( String name, String value )
449 {
450 responseHeaders.put( name, value );
451 }
452
453 public void setRequestHost( String serverName )
454 {
455 requestHost = serverName;
456 }
457
458 public void setTargetHost( String remoteHost )
459 {
460 }
461
462 @SuppressWarnings( "unchecked" )
463 public void setRequestHeader( HttpServletRequest httpRequest )
464 {
465 Enumeration<String> headerNames = httpRequest.getHeaderNames();
466 while( headerNames.hasMoreElements() )
467 {
468 String name = headerNames.nextElement();
469 Enumeration<String> header = httpRequest.getHeaders( name );
470 while( header.hasMoreElements() )
471 {
472 String value = header.nextElement();
473 if( value != null )
474 {
475 requestHeaders.put( name, value );
476 }
477 }
478 }
479 }
480
481 public void setTargetURL( String url )
482 {
483 try
484 {
485 this.targetURL = new URL( url );
486 }
487 catch( MalformedURLException e )
488 {
489 e.printStackTrace();
490 }
491 }
492
493 public int getResponseStatusCode()
494 {
495 return 0;
496 }
497
498 public String getResponseContentType()
499 {
500 return null;
501 }
502
503 public void setResponseHeader( HttpMethodBase method )
504 {
505 Header[] headers = method.getResponseHeaders();
506 for( Header header : headers )
507 {
508 String name = header.getName();
509 String value = header.getValue();
510 if( value != null )
511 {
512 responseHeaders.put( name, value );
513 }
514 }
515 }
516
517 }