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 c = sslEndpoint.indexOf(':');
50  		if (c > 0)
51  		{
52  			this.sslPort = Integer.parseInt(sslEndpoint.substring(c + 1));
53  			this.sslEndPoint = sslEndpoint.substring(0, c);
54  		}
55  		else
56  			this.sslEndPoint = sslEndpoint;
57  	}
58  
59  	@Override
60  	public void init(ServletConfig config) throws ServletException
61  	{
62  		this.config = config;
63  		this.context = config.getServletContext();
64  
65  		client = HttpClientSupport.getHttpClient();
66  	}
67  
68  	public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException
69  	{
70  
71  		HttpServletRequest httpRequest = (HttpServletRequest) request;
72  
73  		// for this create ui server and port, properties.
74  		InetSocketAddress inetAddress = new InetSocketAddress(sslEndPoint, sslPort);
75  		ExtendedPostMethod postMethod = new ExtendedPostMethod();
76  
77  		if (capturedData == null)
78  		{
79  			capturedData = new JProxyServletWsdlMonitorMessageExchange(project);
80  			capturedData.setRequestHost(httpRequest.getRemoteHost());
81  			capturedData.setRequestHeader(httpRequest);
82  			capturedData.setTargetURL("https://" + inetAddress.getHostName());
83  		}
84  
85  		CaptureInputStream capture = new CaptureInputStream(httpRequest.getInputStream());
86  
87  		// copy headers
88  		Enumeration<?> headerNames = httpRequest.getHeaderNames();
89  		while (headerNames.hasMoreElements())
90  		{
91  			String hdr = (String) headerNames.nextElement();
92  			String lhdr = hdr.toLowerCase();
93  
94  			if ("host".equals(lhdr))
95  			{
96  				Enumeration<?> vals = httpRequest.getHeaders(hdr);
97  				while (vals.hasMoreElements())
98  				{
99  					String val = (String) vals.nextElement();
100 					if (val.startsWith("127.0.0.1"))
101 					{
102 						postMethod.addRequestHeader(hdr, sslEndPoint);
103 					}
104 				}
105 				continue;
106 			}
107 
108 			Enumeration<?> vals = httpRequest.getHeaders(hdr);
109 			while (vals.hasMoreElements())
110 			{
111 				String val = (String) vals.nextElement();
112 				if (val != null)
113 				{
114 					postMethod.addRequestHeader(hdr, val);
115 				}
116 			}
117 
118 		}
119 
120 		postMethod.setRequestEntity(new InputStreamRequestEntity(capture, "text/xml; charset=utf-8"));
121 
122 		HostConfiguration hostConfiguration = new HostConfiguration();
123 		hostConfiguration.getParams().setParameter(
124 				SoapUIHostConfiguration.SOAPUI_SSL_CONFIG,
125 				settings.getString(LaunchForm.SSLTUNNEL_KEYSTOREPATH, "") + " "
126 						+ settings.getString(LaunchForm.SSLTUNNEL_KEYSTOREPASSWORD, ""));
127 		hostConfiguration.setHost(new URI("https://" + sslEndPoint, true));
128 
129 		if (settings.getBoolean(LaunchForm.SSLTUNNEL_REUSESTATE))
130 		{
131 			if ( httpState == null ) 
132 				httpState = new HttpState();
133 			client.executeMethod(hostConfiguration, postMethod, httpState);
134 		}
135 		else
136 		{
137 			client.executeMethod(hostConfiguration, postMethod);
138 		}
139 		capturedData.stopCapture();
140 
141 		byte[] res = postMethod.getResponseBody();
142 		IO.copy(new ByteArrayInputStream(postMethod.getResponseBody()), response.getOutputStream());
143 		capturedData.setRequest(capture.getCapturedData());
144 		capturedData.setResponse(res);
145 		capturedData.setResponseHeader(postMethod);
146 		capturedData.setRawRequestData(getRequestToBytes(postMethod, capture));
147 		capturedData.setRawResponseData(getResponseToBytes(postMethod, res));
148 		monitor.addMessageExchange(capturedData);
149 		capturedData = null;
150 
151 		postMethod.releaseConnection();
152 
153 	}
154 
155 	private byte[] getResponseToBytes(ExtendedPostMethod postMethod, byte[] res)
156 	{
157 		String response = "";
158 
159 		Header[] headers = postMethod.getResponseHeaders();
160 		for (Header header : headers)
161 		{
162 			response += header.toString();
163 		}
164 		response += "\n";
165 		response += new String(res);
166 
167 		return response.getBytes();
168 	}
169 
170 	private byte[] getRequestToBytes(ExtendedPostMethod postMethod, CaptureInputStream capture)
171 	{
172 		String request = "";
173 
174 		Header[] headers = postMethod.getRequestHeaders();
175 		for (Header header : headers)
176 		{
177 			request += header.toString();
178 		}
179 		request += "\n";
180 		request += new String(capture.getCapturedData());
181 
182 		return request.getBytes();
183 	}
184 
185 }