View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
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  
25  import org.apache.commons.httpclient.Header;
26  import org.apache.commons.httpclient.HostConfiguration;
27  import org.apache.commons.httpclient.HttpState;
28  import org.apache.commons.httpclient.URI;
29  import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
30  import org.mortbay.util.IO;
31  
32  import com.eviware.soapui.impl.wsdl.actions.monitor.SoapMonitorAction.LaunchForm;
33  import com.eviware.soapui.impl.wsdl.monitor.JProxyServletWsdlMonitorMessageExchange;
34  import com.eviware.soapui.impl.wsdl.monitor.SoapMonitor;
35  import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedPostMethod;
36  import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport;
37  import com.eviware.soapui.impl.wsdl.support.http.SoapUIHostConfiguration;
38  
39  public class TunnelServlet extends ProxyServlet
40  {
41  
42  	private String sslEndPoint;
43  	private int sslPort = 443;
44  
45  	public TunnelServlet(SoapMonitor soapMonitor, String sslEndpoint)
46  	{
47  		super(soapMonitor);
48  
49  		int prefix = sslEndpoint.indexOf("://");
50  		int c = sslEndpoint.indexOf(prefix, ':');
51  		if (c > 0)
52  		{
53  			this.sslPort = Integer.parseInt(sslEndpoint.substring(c + 1));
54  			this.sslEndPoint = sslEndpoint.substring(prefix, c);
55  		}
56  		else {
57  			if ( prefix > 0 )
58  			this.sslEndPoint = sslEndpoint.substring(prefix+3);
59  		}
60  	}
61  
62  	@Override
63  	public void init(ServletConfig config) throws ServletException
64  	{
65  		this.config = config;
66  		this.context = config.getServletContext();
67  
68  		client = HttpClientSupport.getHttpClient();
69  	}
70  
71  	public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException
72  	{
73  
74  		HttpServletRequest httpRequest = (HttpServletRequest) request;
75  
76  		// for this create ui server and port, properties.
77  		InetSocketAddress inetAddress = new InetSocketAddress(sslEndPoint, sslPort);
78  		ExtendedPostMethod postMethod = new ExtendedPostMethod();
79  
80  		if (capturedData == null)
81  		{
82  			capturedData = new JProxyServletWsdlMonitorMessageExchange(project);
83  			capturedData.setRequestHost(httpRequest.getRemoteHost());
84  			capturedData.setRequestHeader(httpRequest);
85  			capturedData.setTargetURL("https://" + inetAddress.getHostName());
86  		}
87  
88  		CaptureInputStream capture = new CaptureInputStream(httpRequest.getInputStream());
89  
90  		// copy headers
91  		Enumeration<?> headerNames = httpRequest.getHeaderNames();
92  		while (headerNames.hasMoreElements())
93  		{
94  			String hdr = (String) headerNames.nextElement();
95  			String lhdr = hdr.toLowerCase();
96  
97  			if ("host".equals(lhdr))
98  			{
99  				Enumeration<?> vals = httpRequest.getHeaders(hdr);
100 				while (vals.hasMoreElements())
101 				{
102 					String val = (String) vals.nextElement();
103 					if (val.startsWith("127.0.0.1"))
104 					{
105 						postMethod.addRequestHeader(hdr, sslEndPoint);
106 					}
107 				}
108 				continue;
109 			}
110 
111 			Enumeration<?> vals = httpRequest.getHeaders(hdr);
112 			while (vals.hasMoreElements())
113 			{
114 				String val = (String) vals.nextElement();
115 				if (val != null)
116 				{
117 					postMethod.addRequestHeader(hdr, val);
118 				}
119 			}
120 
121 		}
122 
123 		postMethod.setRequestEntity(new InputStreamRequestEntity(capture, "text/xml; charset=utf-8"));
124 
125 		HostConfiguration hostConfiguration = new HostConfiguration();
126 		hostConfiguration.getParams().setParameter(
127 				SoapUIHostConfiguration.SOAPUI_SSL_CONFIG,
128 				settings.getString(LaunchForm.SSLTUNNEL_KEYSTOREPATH, "") + " "
129 						+ settings.getString(LaunchForm.SSLTUNNEL_KEYSTOREPASSWORD, ""));
130 		hostConfiguration.setHost(new URI("https://" + sslEndPoint, true));
131 
132 		if (settings.getBoolean(LaunchForm.SSLTUNNEL_REUSESTATE))
133 		{
134 			if ( httpState == null ) 
135 				httpState = new HttpState();
136 			client.executeMethod(hostConfiguration, postMethod, httpState);
137 		}
138 		else
139 		{
140 			client.executeMethod(hostConfiguration, postMethod);
141 		}
142 		capturedData.stopCapture();
143 
144 		byte[] res = postMethod.getResponseBody();
145 		IO.copy(new ByteArrayInputStream(postMethod.getResponseBody()), response.getOutputStream());
146 		capturedData.setRequest(capture.getCapturedData());
147 		capturedData.setResponse(res);
148 		capturedData.setResponseHeader(postMethod);
149 		capturedData.setRawRequestData(getRequestToBytes(postMethod, capture));
150 		capturedData.setRawResponseData(getResponseToBytes(postMethod, res));
151 		monitor.addMessageExchange(capturedData);
152 		capturedData = null;
153 
154 		postMethod.releaseConnection();
155 
156 	}
157 
158 	private byte[] getResponseToBytes(ExtendedPostMethod postMethod, byte[] res)
159 	{
160 		String response = "";
161 
162 		Header[] headers = postMethod.getResponseHeaders();
163 		for (Header header : headers)
164 		{
165 			response += header.toString();
166 		}
167 		response += "\n";
168 		response += new String(res);
169 
170 		return response.getBytes();
171 	}
172 
173 	private byte[] getRequestToBytes(ExtendedPostMethod postMethod, CaptureInputStream capture)
174 	{
175 		String request = "";
176 
177 		Header[] headers = postMethod.getRequestHeaders();
178 		for (Header header : headers)
179 		{
180 			request += header.toString();
181 		}
182 		request += "\n";
183 		request += new String(capture.getCapturedData());
184 
185 		return request.getBytes();
186 	}
187 
188 }