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.util.Enumeration;
17 import java.util.HashSet;
18
19 import javax.servlet.Servlet;
20 import javax.servlet.ServletConfig;
21 import javax.servlet.ServletContext;
22 import javax.servlet.ServletException;
23 import javax.servlet.ServletRequest;
24 import javax.servlet.ServletResponse;
25 import javax.servlet.http.HttpServletRequest;
26
27 import org.apache.commons.httpclient.Header;
28 import org.apache.commons.httpclient.HostConfiguration;
29 import org.apache.commons.httpclient.HttpClient;
30 import org.apache.commons.httpclient.HttpState;
31 import org.apache.commons.httpclient.URI;
32 import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
33 import org.mortbay.util.IO;
34
35 import com.eviware.soapui.impl.wsdl.WsdlProject;
36 import com.eviware.soapui.impl.wsdl.actions.monitor.SoapMonitorAction.LaunchForm;
37 import com.eviware.soapui.impl.wsdl.monitor.JProxyServletWsdlMonitorMessageExchange;
38 import com.eviware.soapui.impl.wsdl.monitor.SoapMonitor;
39 import com.eviware.soapui.impl.wsdl.submit.transports.http.support.methods.ExtendedPostMethod;
40 import com.eviware.soapui.model.settings.Settings;
41
42 public class ProxyServlet implements Servlet
43 {
44
45 protected ServletConfig config;
46 protected ServletContext context;
47 protected HttpClient client;
48 protected JProxyServletWsdlMonitorMessageExchange capturedData;
49 protected SoapMonitor monitor;
50 protected WsdlProject project;
51 protected HttpState httpState = null;
52 protected Settings settings;
53
54 static HashSet<String> dontProxyHeaders = new HashSet<String>();
55 {
56 dontProxyHeaders.add("proxy-connection");
57 dontProxyHeaders.add("connection");
58 dontProxyHeaders.add("keep-alive");
59 dontProxyHeaders.add("transfer-encoding");
60 dontProxyHeaders.add("te");
61 dontProxyHeaders.add("trailer");
62 dontProxyHeaders.add("proxy-authorization");
63 dontProxyHeaders.add("proxy-authenticate");
64 dontProxyHeaders.add("upgrade");
65 }
66
67 public ProxyServlet(SoapMonitor soapMonitor)
68 {
69 this.monitor = soapMonitor;
70 this.project = monitor.getProject();
71 settings = project.getSettings();
72 }
73
74 public void destroy()
75 {
76 }
77
78 public ServletConfig getServletConfig()
79 {
80 return config;
81 }
82
83 public String getServletInfo()
84 {
85 return "SoapUI Monitor";
86 }
87
88 public void init(ServletConfig config) throws ServletException
89 {
90
91 this.config = config;
92 this.context = config.getServletContext();
93
94 client = new HttpClient();
95
96 }
97
98 public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException
99 {
100
101 HttpServletRequest httpRequest = (HttpServletRequest) request;
102
103
104 ExtendedPostMethod postMethod = new ExtendedPostMethod();
105
106 if (capturedData == null)
107 {
108 capturedData = new JProxyServletWsdlMonitorMessageExchange(project);
109 capturedData.setRequestHost(httpRequest.getServerName());
110 capturedData.setRequestHeader(httpRequest);
111 capturedData.setTargetURL(httpRequest.getRequestURL().toString());
112 }
113
114 CaptureInputStream capture = new CaptureInputStream(httpRequest.getInputStream());
115
116
117 String connectionHeader = httpRequest.getHeader("Connection");
118 if (connectionHeader != null)
119 {
120 connectionHeader = connectionHeader.toLowerCase();
121 if (connectionHeader.indexOf("keep-alive") < 0 && connectionHeader.indexOf("close") < 0)
122 connectionHeader = null;
123 }
124
125
126 boolean xForwardedFor = false;
127 @SuppressWarnings("unused")
128 long contentLength = -1;
129 Enumeration<?> headerNames = httpRequest.getHeaderNames();
130 while (headerNames.hasMoreElements())
131 {
132 String hdr = (String) headerNames.nextElement();
133 String lhdr = hdr.toLowerCase();
134
135 if (dontProxyHeaders.contains(lhdr))
136 continue;
137 if (connectionHeader != null && connectionHeader.indexOf(lhdr) >= 0)
138 continue;
139
140 if ("content-length".equals(lhdr))
141 contentLength = request.getContentLength();
142
143 Enumeration<?> vals = httpRequest.getHeaders(hdr);
144 while (vals.hasMoreElements())
145 {
146 String val = (String) vals.nextElement();
147 if (val != null)
148 {
149 postMethod.setRequestHeader(lhdr, val);
150 xForwardedFor |= "X-Forwarded-For".equalsIgnoreCase(hdr);
151 }
152 }
153 }
154
155
156 postMethod.setRequestHeader("Via", "SoapUI Monitor");
157 if (!xForwardedFor)
158 postMethod.addRequestHeader("X-Forwarded-For", request.getRemoteAddr());
159
160 postMethod.setRequestEntity(new InputStreamRequestEntity(capture, "text/xml; charset=utf-8"));
161
162 HostConfiguration hostConfiguration = new HostConfiguration();
163 hostConfiguration.setHost(new URI("http://"+httpRequest.getServerName()+httpRequest.getServletPath(), true));
164 postMethod.setPath("http://"+httpRequest.getServerName()+httpRequest.getServletPath());
165
166 if (settings.getBoolean(LaunchForm.SSLTUNNEL_REUSESTATE))
167 {
168 if ( httpState == null )
169 httpState = new HttpState();
170 client.executeMethod(hostConfiguration, postMethod, httpState);
171 }
172 else
173 {
174 client.executeMethod(hostConfiguration, postMethod);
175 }
176
177
178 capturedData.stopCapture();
179 byte[] res = postMethod.getResponseBody();
180 IO.copy(new ByteArrayInputStream(postMethod.getResponseBody()), response.getOutputStream());
181 capturedData.setRequest(capture.getCapturedData());
182 capturedData.setResponse(res);
183 capturedData.setResponseHeader(postMethod);
184 capturedData.setRawRequestData(getRequestToBytes(postMethod, capture));
185 capturedData.setRawResponseData(getResponseToBytes(postMethod, res));
186 monitor.addMessageExchange(capturedData);
187 capturedData = null;
188
189 postMethod.releaseConnection();
190 }
191
192
193 private byte[] getResponseToBytes(ExtendedPostMethod postMethod, byte[] res)
194 {
195 String response = "";
196
197 Header[] headers = postMethod.getResponseHeaders();
198 for (Header header : headers)
199 {
200 response += header.toString();
201 }
202 response += "\n";
203 response += new String(res);
204
205 return response.getBytes();
206 }
207
208 private byte[] getRequestToBytes(ExtendedPostMethod postMethod, CaptureInputStream capture)
209 {
210 String request = "";
211
212 Header[] headers = postMethod.getRequestHeaders();
213 for (Header header : headers)
214 {
215 request += header.toString();
216 }
217 request += "\n";
218 request += new String(capture.getCapturedData());
219
220 return request.getBytes();
221 }
222
223 }