1
2
3
4
5
6
7
8
9
10
11
12 package com.eviware.soapui.impl.wsdl.monitor.jettyproxy;
13
14 import java.io.ByteArrayInputStream;
15 import java.io.IOException;
16 import java.net.InetSocketAddress;
17 import java.util.Enumeration;
18
19 import javax.servlet.ServletConfig;
20 import javax.servlet.ServletException;
21 import javax.servlet.ServletRequest;
22 import javax.servlet.ServletResponse;
23 import javax.servlet.http.HttpServletRequest;
24 import javax.servlet.http.HttpServletResponse;
25
26 import org.apache.commons.httpclient.Header;
27 import org.apache.commons.httpclient.HostConfiguration;
28 import org.apache.commons.httpclient.HttpMethodBase;
29 import org.apache.commons.httpclient.HttpState;
30 import org.apache.commons.httpclient.URI;
31 import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
32 import org.apache.commons.httpclient.params.HostParams;
33 import org.mortbay.util.IO;
34
35 import com.eviware.soapui.impl.wsdl.actions.monitor.SoapMonitorAction.LaunchForm;
36 import com.eviware.soapui.impl.wsdl.monitor.JProxyServletWsdlMonitorMessageExchange;
37 import com.eviware.soapui.impl.wsdl.monitor.SoapMonitor;
38 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedGetMethod;
39 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedPostMethod;
40 import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport;
41 import com.eviware.soapui.impl.wsdl.support.http.ProxyUtils;
42 import com.eviware.soapui.impl.wsdl.support.http.SoapUIHostConfiguration;
43 import com.eviware.soapui.model.propertyexpansion.DefaultPropertyExpansionContext;
44 import com.eviware.soapui.support.types.StringToStringMap;
45 import com.eviware.soapui.support.xml.XmlUtils;
46
47 public class TunnelServlet extends ProxyServlet
48 {
49 private String sslEndPoint;
50 private int sslPort = 443;
51 private String prot = "https://";
52
53 public TunnelServlet( SoapMonitor soapMonitor, String sslEndpoint )
54 {
55 super( soapMonitor );
56
57 if( !sslEndpoint.startsWith( "https" ) )
58 {
59 this.prot = "http://";
60 }
61 int prefix = sslEndpoint.indexOf( "://" );
62 int c = sslEndpoint.indexOf( prefix, ':' );
63 if( c > 0 )
64 {
65 this.sslPort = Integer.parseInt( sslEndpoint.substring( c + 1 ) );
66 this.sslEndPoint = sslEndpoint.substring( prefix, c );
67 }
68 else
69 {
70 if( prefix > 0 )
71 this.sslEndPoint = sslEndpoint.substring( prefix + 3 );
72 }
73 }
74
75 @Override
76 public void init( ServletConfig config ) throws ServletException
77 {
78 this.config = config;
79 this.context = config.getServletContext();
80
81 client = HttpClientSupport.getHttpClient();
82 }
83
84 public void service( ServletRequest request, ServletResponse response ) throws ServletException, IOException
85 {
86 monitor.fireOnRequest( request, response );
87 if( response.isCommitted() )
88 return;
89
90 HttpMethodBase postMethod;
91
92
93 InetSocketAddress inetAddress = new InetSocketAddress( sslEndPoint, sslPort );
94 HttpServletRequest httpRequest = ( HttpServletRequest )request;
95 if( httpRequest.getMethod().equals( "GET" ) )
96 postMethod = new ExtendedGetMethod();
97 else
98 postMethod = new ExtendedPostMethod();
99
100 JProxyServletWsdlMonitorMessageExchange capturedData = new JProxyServletWsdlMonitorMessageExchange( project );
101 capturedData.setRequestHost( httpRequest.getRemoteHost() );
102 capturedData.setRequestHeader( httpRequest );
103 capturedData.setTargetURL( this.prot + inetAddress.getHostName() );
104
105 CaptureInputStream capture = new CaptureInputStream( httpRequest.getInputStream() );
106
107
108 Enumeration<?> headerNames = httpRequest.getHeaderNames();
109 while( headerNames.hasMoreElements() )
110 {
111 String hdr = ( String )headerNames.nextElement();
112 String lhdr = hdr.toLowerCase();
113
114 if( "host".equals( lhdr ) )
115 {
116 Enumeration<?> vals = httpRequest.getHeaders( hdr );
117 while( vals.hasMoreElements() )
118 {
119 String val = ( String )vals.nextElement();
120 if( val.startsWith( "127.0.0.1" ) )
121 {
122 postMethod.addRequestHeader( hdr, sslEndPoint );
123 }
124 }
125 continue;
126 }
127
128 Enumeration<?> vals = httpRequest.getHeaders( hdr );
129 while( vals.hasMoreElements() )
130 {
131 String val = ( String )vals.nextElement();
132 if( val != null )
133 {
134 postMethod.addRequestHeader( hdr, val );
135 }
136 }
137
138 }
139
140 if( postMethod instanceof ExtendedPostMethod )
141 ( ( ExtendedPostMethod )postMethod ).setRequestEntity( new InputStreamRequestEntity( capture, request
142 .getContentType() ) );
143
144 HostConfiguration hostConfiguration = new HostConfiguration();
145
146 httpRequest.getProtocol();
147 hostConfiguration.getParams().setParameter(
148 SoapUIHostConfiguration.SOAPUI_SSL_CONFIG,
149 settings.getString( LaunchForm.SSLTUNNEL_KEYSTOREPATH, "" ) + " "
150 + settings.getString( LaunchForm.SSLTUNNEL_KEYSTOREPASSWORD, "" ) );
151 hostConfiguration.setHost( new URI( this.prot + sslEndPoint, true ) );
152
153 hostConfiguration = ProxyUtils.initProxySettings( settings, httpState, hostConfiguration, prot + sslEndPoint,
154 new DefaultPropertyExpansionContext( project ) );
155
156 HostParams param = hostConfiguration.getParams();
157 if (sslEndPoint.indexOf( "/" ) < 0)
158 postMethod.setPath( "/" );
159 else
160 postMethod.setPath( sslEndPoint.substring( sslEndPoint.indexOf( "/" ), sslEndPoint.length() ) );
161
162 monitor.fireBeforeProxy( request, response, postMethod, hostConfiguration );
163
164 if( settings.getBoolean( LaunchForm.SSLTUNNEL_REUSESTATE ) )
165 {
166 if( httpState == null )
167 httpState = new HttpState();
168 client.executeMethod( hostConfiguration, postMethod, httpState );
169 }
170 else
171 {
172 client.executeMethod( hostConfiguration, postMethod );
173 }
174 capturedData.stopCapture();
175
176 capturedData.setRequest( capture.getCapturedData() );
177 capturedData.setRawResponseBody( postMethod.getResponseBody() );
178 capturedData.setResponseHeader( postMethod );
179 capturedData.setRawRequestData( getRequestToBytes( request.toString(), postMethod, capture ) );
180 capturedData.setRawResponseData( getResponseToBytes( response.toString(), postMethod, capturedData
181 .getRawResponseBody() ) );
182
183 monitor.fireAfterProxy( request, response, postMethod, capturedData );
184
185 StringToStringMap responseHeaders = capturedData.getResponseHeaders();
186
187 HttpServletResponse httpResponse = ( HttpServletResponse )response;
188 for( String name : responseHeaders.keySet() )
189 {
190 String header = responseHeaders.get( name );
191 httpResponse.addHeader( name, header );
192
193 }
194
195 IO.copy( new ByteArrayInputStream( capturedData.getRawResponseBody() ), httpResponse.getOutputStream() );
196
197 postMethod.releaseConnection();
198
199 monitor.addMessageExchange( capturedData );
200 capturedData = null;
201
202 }
203
204 private byte[] getResponseToBytes( String footer, HttpMethodBase postMethod, byte[] res )
205 {
206 String response = footer;
207
208 Header[] headers = postMethod.getResponseHeaders();
209 for( Header header : headers )
210 {
211 response += header.toString();
212 }
213 response += "\n";
214 response += XmlUtils.prettyPrintXml( new String( res ) );
215
216 return response.getBytes();
217 }
218
219 private byte[] getRequestToBytes( String footer, HttpMethodBase postMethod, CaptureInputStream capture )
220 {
221 String request = footer;
222
223
224
225
226
227
228 request += "\n";
229 request += XmlUtils.prettyPrintXml( new String( capture.getCapturedData() ) );
230
231 return request.getBytes();
232 }
233
234 }