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