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