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.IOException;
15 import java.io.InputStream;
16 import java.io.OutputStream;
17 import java.net.InetSocketAddress;
18 import java.net.Socket;
19 import java.util.Enumeration;
20 import java.util.HashSet;
21
22 import javax.servlet.Servlet;
23 import javax.servlet.ServletConfig;
24 import javax.servlet.ServletContext;
25 import javax.servlet.ServletException;
26 import javax.servlet.ServletRequest;
27 import javax.servlet.ServletResponse;
28 import javax.servlet.http.HttpServletRequest;
29 import javax.servlet.http.HttpServletResponse;
30
31 import org.mortbay.jetty.HttpSchemes;
32 import org.mortbay.jetty.client.HttpClient;
33 import org.mortbay.util.IO;
34 import org.mortbay.util.ajax.Continuation;
35 import org.mortbay.util.ajax.ContinuationSupport;
36
37 import com.eviware.soapui.impl.wsdl.WsdlProject;
38 import com.eviware.soapui.impl.wsdl.monitor.JProxyServletWsdlMonitorMessageExchange;
39 import com.eviware.soapui.impl.wsdl.monitor.SoapMonitor;
40
41 public class ProxyServlet implements Servlet
42 {
43
44 private ServletConfig config;
45 private ServletContext context;
46 private HttpClient client;
47 private JProxyServletWsdlMonitorMessageExchange capturedData;
48 private SoapMonitor monitor;
49 private WsdlProject project;
50
51 static HashSet<String> dontProxyHeaders = new HashSet<String>();
52 {
53 dontProxyHeaders.add("proxy-connection");
54 dontProxyHeaders.add("connection");
55 dontProxyHeaders.add("keep-alive");
56 dontProxyHeaders.add("transfer-encoding");
57 dontProxyHeaders.add("te");
58 dontProxyHeaders.add("trailer");
59 dontProxyHeaders.add("proxy-authorization");
60 dontProxyHeaders.add("proxy-authenticate");
61 dontProxyHeaders.add("upgrade");
62 }
63
64 public ProxyServlet(SoapMonitor soapMonitor)
65 {
66 this.monitor = soapMonitor;
67 this.project = monitor.getProject();
68 }
69
70 public void destroy()
71 {
72 }
73
74 public ServletConfig getServletConfig()
75 {
76 return config;
77 }
78
79 public String getServletInfo()
80 {
81 return "SoapUI Monitor";
82 }
83
84 public void init(ServletConfig config) throws ServletException
85 {
86
87 this.config = config;
88 this.context = config.getServletContext();
89
90 client = new HttpClient();
91 client.setConnectorType(HttpClient.CONNECTOR_SOCKET);
92 try
93 {
94 client.start();
95 }
96 catch (Exception e)
97 {
98 throw new ServletException(e);
99 }
100
101 }
102
103 public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException
104 {
105
106 HttpServletRequest httpRequest = (HttpServletRequest) request;
107 HttpServletResponse httpResponse = (HttpServletResponse) response;
108
109 if (capturedData == null)
110 {
111 capturedData = new JProxyServletWsdlMonitorMessageExchange(project);
112 capturedData.setRequestHost(httpRequest.getServerName());
113 capturedData.setTargetHost(httpRequest.getRemoteHost());
114 capturedData.setRequestHeader(httpRequest);
115 }
116
117
118
119
120
121
122
123 CaptureInputStream capture = new CaptureInputStream(httpRequest.getInputStream());
124 Continuation continuation = ContinuationSupport.getContinuation(httpRequest, httpRequest);
125
126 if (!continuation.isPending())
127 {
128 String uri = httpRequest.getRequestURI();
129 if (httpRequest.getQueryString() != null)
130 uri += "?" + httpRequest.getQueryString();
131
132 SoapUIHttpExchange exchange = new SoapUIHttpExchange(monitor, httpRequest, httpResponse, capture, capturedData);
133
134 exchange.setScheme(HttpSchemes.HTTPS.equals(request.getScheme()) ? HttpSchemes.HTTPS_BUFFER
135 : HttpSchemes.HTTP_BUFFER);
136 exchange.setMethod(httpRequest.getMethod());
137 exchange.setURI(uri);
138 capturedData.setTargetURL(httpRequest.getRequestURL().toString());
139
140 exchange.setVersion(httpRequest.getProtocol());
141 InetSocketAddress address = new InetSocketAddress(httpRequest.getServerName(), httpRequest.getServerPort());
142 exchange.setAddress(address);
143
144 System.err.println("PROXY TO http://" + address.getHostName() + ":" + address.getPort() + uri);
145
146
147 String connectionHeader = httpRequest.getHeader("Connection");
148 if (connectionHeader != null)
149 {
150 connectionHeader = connectionHeader.toLowerCase();
151 if (connectionHeader.indexOf("keep-alive") < 0 && connectionHeader.indexOf("close") < 0)
152 connectionHeader = null;
153 }
154
155
156 boolean xForwardedFor = false;
157 boolean hasContent = false;
158 @SuppressWarnings("unused")
159 long contentLength = -1;
160 Enumeration headerNames = httpRequest.getHeaderNames();
161 while (headerNames.hasMoreElements())
162 {
163 String hdr = (String) headerNames.nextElement();
164 String lhdr = hdr.toLowerCase();
165
166 if (dontProxyHeaders.contains(lhdr))
167 continue;
168 if (connectionHeader != null && connectionHeader.indexOf(lhdr) >= 0)
169 continue;
170
171 if ("content-type".equals(lhdr))
172 hasContent = true;
173 if ("content-length".equals(lhdr))
174 contentLength = request.getContentLength();
175
176 Enumeration vals = httpRequest.getHeaders(hdr);
177 while (vals.hasMoreElements())
178 {
179 String val = (String) vals.nextElement();
180 if (val != null)
181 {
182 exchange.setRequestHeader(lhdr, val);
183 xForwardedFor |= "X-Forwarded-For".equalsIgnoreCase(hdr);
184 }
185 }
186 }
187
188
189 exchange.setRequestHeader("Via", "SoapUI Monitor");
190 if (!xForwardedFor)
191 exchange.addRequestHeader("X-Forwarded-For", request.getRemoteAddr());
192
193 if (hasContent)
194 {
195 exchange.setRequestContentSource(capture);
196 }
197 client.send(exchange);
198 continuation.suspend(3000);
199 }
200
201
202 if (!capturedData.isStopCapture())
203 {
204
205 monitor.addMessageExchange(capturedData);
206 System.err.println("Killed " + capturedData.toString());
207 capturedData = null;
208 }
209 }
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227 }