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