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