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