1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.maven.archetype.proxy;
18
19
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.OutputStream;
23 import java.io.PrintWriter;
24 import java.net.HttpURLConnection;
25 import java.net.InetSocketAddress;
26 import java.net.Socket;
27 import java.net.URL;
28 import java.net.URLConnection;
29 import java.util.Enumeration;
30 import java.util.HashSet;
31 import javax.servlet.ServletConfig;
32 import javax.servlet.ServletContext;
33 import javax.servlet.ServletException;
34 import javax.servlet.ServletRequest;
35 import javax.servlet.ServletResponse;
36 import javax.servlet.http.HttpServlet;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.servlet.http.HttpServletResponse;
39 import org.mortbay.util.IO;
40
41
42
43
44
45
46 public class ProxyServlet
47 extends HttpServlet
48 {
49 protected HashSet _DontProxyHeaders = new HashSet();
50
51 {
52 _DontProxyHeaders.add( "proxy-connection" );
53 _DontProxyHeaders.add( "connection" );
54 _DontProxyHeaders.add( "keep-alive" );
55 _DontProxyHeaders.add( "transfer-encoding" );
56 _DontProxyHeaders.add( "te" );
57 _DontProxyHeaders.add( "trailer" );
58 _DontProxyHeaders.add( "proxy-authorization" );
59 _DontProxyHeaders.add( "proxy-authenticate" );
60 _DontProxyHeaders.add( "upgrade" );
61 }
62
63 private ServletConfig config;
64
65 private ServletContext context;
66
67
68
69
70 public void init( ServletConfig config )
71 throws ServletException
72 {
73 this.config = config;
74 this.context = config.getServletContext();
75 }
76
77
78
79
80 public ServletConfig getServletConfig()
81 {
82 return config;
83 }
84
85
86
87
88 public void service( ServletRequest req, ServletResponse res )
89 throws ServletException,
90 IOException
91 {
92 HttpServletRequest request = (HttpServletRequest) req;
93 HttpServletResponse response = (HttpServletResponse) res;
94 if ( "CONNECT".equalsIgnoreCase( request.getMethod() ) )
95 {
96 handleConnect( request, response );
97 }
98 else
99 {
100 String uri = request.getRequestURI();
101 if ( request.getQueryString() != null )
102 {
103 uri += "?" + request.getQueryString();
104 }
105 URL url =
106 new URL( request.getScheme(), request.getServerName(),
107 request.getServerPort(),
108 uri );
109
110 context.log( "\n\n\nURL=" + url );
111
112 URLConnection connection = url.openConnection();
113 connection.setAllowUserInteraction( false );
114
115
116 HttpURLConnection http = null;
117 if ( connection instanceof HttpURLConnection )
118 {
119 http = (HttpURLConnection) connection;
120 http.setRequestMethod( request.getMethod() );
121 http.setInstanceFollowRedirects( false );
122 }
123
124
125 String connectionHdr = request.getHeader( "Connection" );
126 if ( connectionHdr != null )
127 {
128 connectionHdr = connectionHdr.toLowerCase();
129 if ( connectionHdr.equals( "keep-alive" ) || connectionHdr.equals( "close" ) )
130 {
131 connectionHdr = null;
132 }
133 }
134
135
136 boolean xForwardedFor = false;
137 boolean hasContent = false;
138 Enumeration enm = request.getHeaderNames();
139 while ( enm.hasMoreElements() )
140 {
141
142 String hdr = (String) enm.nextElement();
143 String lhdr = hdr.toLowerCase();
144
145 if ( _DontProxyHeaders.contains( lhdr ) )
146 {
147 continue;
148 }
149 if ( connectionHdr != null && connectionHdr.indexOf( lhdr ) >= 0 )
150 {
151 continue;
152 }
153 if ( "content-type".equals( lhdr ) )
154 {
155 hasContent = true;
156 }
157 Enumeration vals = request.getHeaders( hdr );
158 while ( vals.hasMoreElements() )
159 {
160 String val = (String) vals.nextElement();
161 if ( val != null )
162 {
163 connection.addRequestProperty( hdr, val );
164 context.log( "req " + hdr + ": " + val );
165 xForwardedFor |= "X-Forwarded-For".equalsIgnoreCase( hdr );
166 }
167 }
168 }
169
170
171 connection.setRequestProperty( "Via", "1.1 (jetty)" );
172 if ( !xForwardedFor )
173 {
174 connection.addRequestProperty( "X-Forwarded-For", request.getRemoteAddr() );
175 }
176
177 String cache_control = request.getHeader( "Cache-Control" );
178 if ( cache_control != null &&
179 (cache_control.indexOf( "no-cache" ) >= 0 || cache_control.indexOf( "no-store" ) >= 0) )
180 {
181 connection.setUseCaches( false );
182
183
184 }
185 try
186 {
187 connection.setDoInput( true );
188
189
190 InputStream in = request.getInputStream();
191 if ( hasContent )
192 {
193 connection.setDoOutput( true );
194 IO.copy( in, connection.getOutputStream() );
195 }
196
197
198 connection.connect();
199 }
200 catch ( Exception e )
201 {
202 context.log( "proxy", e );
203 }
204
205 InputStream proxy_in = null;
206
207
208 int code = 500;
209 if ( http != null )
210 {
211 proxy_in = http.getErrorStream();
212
213 code = http.getResponseCode();
214 response.setStatus( code, http.getResponseMessage() );
215 context.log( "response = " + http.getResponseCode() );
216 }
217
218 if ( proxy_in == null )
219 {
220 try
221 {
222 proxy_in = connection.getInputStream();
223 }
224 catch ( Exception e )
225 {
226 context.log( "stream", e );
227 proxy_in = http.getErrorStream();
228 }
229 }
230
231
232 response.setHeader( "Date", null );
233 response.setHeader( "Server", null );
234
235
236 int h = 0;
237 String hdr = connection.getHeaderFieldKey( h );
238 String val = connection.getHeaderField( h );
239 while ( hdr != null || val != null )
240 {
241 String lhdr = hdr != null ? hdr.toLowerCase() : null;
242 if ( hdr != null && val != null && !_DontProxyHeaders.contains( lhdr ) )
243 {
244 response.addHeader( hdr, val );
245 }
246 context.log( "res " + hdr + ": " + val );
247
248 h++;
249 hdr = connection.getHeaderFieldKey( h );
250 val = connection.getHeaderField( h );
251 }
252 response.addHeader( "Via", "1.1 (jetty)" );
253
254
255 if ( proxy_in != null )
256 {
257 IO.copy( proxy_in, response.getOutputStream() );
258 }
259 }
260 }
261
262
263 public void handleConnect( HttpServletRequest request,
264 HttpServletResponse response )
265 throws IOException
266 {
267 String uri = request.getRequestURI();
268
269 context.log( "CONNECT: " + uri );
270
271 String port = "";
272 String host = "";
273
274 int c = uri.indexOf( ':' );
275 if ( c >= 0 )
276 {
277 port = uri.substring( c + 1 );
278 host = uri.substring( 0, c );
279 if ( host.indexOf( '/' ) > 0 )
280 {
281 host = host.substring( host.indexOf( '/' ) + 1 );
282 }
283 }
284
285 InetSocketAddress inetAddress =
286 new InetSocketAddress( host, Integer.parseInt( port ) );
287
288 InputStream in = request.getInputStream();
289 OutputStream out = response.getOutputStream();
290
291 Socket socket = new Socket( inetAddress.getAddress(), inetAddress.getPort() );
292 context.log( "Socket: " + socket );
293
294 response.setStatus( 200 );
295 response.setHeader( "Connection", "close" );
296 response.flushBuffer();
297
298
299
300 context.log( "out<-in" );
301 IO.copyThread( socket.getInputStream(), out );
302 context.log( "in->out" );
303 IO.copy( in, socket.getOutputStream() );
304 }
305
306
307
308
309 public String getServletInfo()
310 {
311 return "Proxy Servlet";
312 }
313
314
315
316
317 public void destroy()
318 {
319 }
320
321
322
323
324
325
326 protected void processRequest( HttpServletRequest request,
327 HttpServletResponse response )
328 throws ServletException, IOException
329 {
330 response.setContentType( "text/html;charset=UTF-8" );
331 PrintWriter out = response.getWriter();
332 try
333 {
334
335
336
337
338
339
340
341
342
343
344 }
345 finally
346 {
347 out.close();
348 }
349 }
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382 }