KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > servlet > ProxyServlet


1 // ========================================================================
2
// $Id: ProxyServlet.java,v 1.2 2004/07/19 13:13:00 hlavac Exp $
3
// Copyright 2004-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.servlet;
17
18 import java.io.IOException JavaDoc;
19 import java.io.InputStream JavaDoc;
20 import java.io.OutputStream JavaDoc;
21 import java.net.HttpURLConnection JavaDoc;
22 import java.net.Socket JavaDoc;
23 import java.net.URL JavaDoc;
24 import java.net.URLConnection JavaDoc;
25 import java.util.Enumeration JavaDoc;
26 import java.util.HashSet JavaDoc;
27
28 import javax.servlet.Servlet JavaDoc;
29 import javax.servlet.ServletConfig JavaDoc;
30 import javax.servlet.ServletContext JavaDoc;
31 import javax.servlet.ServletException JavaDoc;
32 import javax.servlet.ServletRequest JavaDoc;
33 import javax.servlet.ServletResponse JavaDoc;
34 import javax.servlet.http.HttpServletRequest JavaDoc;
35 import javax.servlet.http.HttpServletResponse JavaDoc;
36
37 import org.mortbay.util.IO;
38 import org.mortbay.util.InetAddrPort;
39
40
41 /**
42  * EXPERIMENTAL Proxy servlet.
43  * @author gregw
44  *
45  */

46 public class ProxyServlet implements Servlet JavaDoc
47 {
48     private int _tunnelTimeoutMs=3000;
49     
50     protected HashSet JavaDoc _DontProxyHeaders = new HashSet JavaDoc();
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 JavaDoc config;
64     private ServletContext JavaDoc context;
65     
66     /* (non-Javadoc)
67      * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
68      */

69     public void init(ServletConfig JavaDoc config) throws ServletException JavaDoc
70     {
71         this.config=config;
72         this.context=config.getServletContext();
73     }
74
75     /* (non-Javadoc)
76      * @see javax.servlet.Servlet#getServletConfig()
77      */

78     public ServletConfig JavaDoc getServletConfig()
79     {
80         return config;
81     }
82
83     /* (non-Javadoc)
84      * @see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
85      */

86     public void service(ServletRequest JavaDoc req, ServletResponse JavaDoc res) throws ServletException JavaDoc,
87             IOException JavaDoc
88     {
89         HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc)req;
90         HttpServletResponse JavaDoc response = (HttpServletResponse JavaDoc)res;
91         if ("CONNECT".equalsIgnoreCase(request.getMethod()))
92         {
93             handleConnect(request,response);
94         }
95         else
96         {
97             String JavaDoc uri=request.getRequestURI();
98             if (request.getQueryString()!=null)
99                 uri+="?"+request.getQueryString();
100             URL JavaDoc url = new URL JavaDoc(request.getScheme(),
101                               request.getServerName(),
102                               request.getServerPort(),
103                               uri);
104             
105             context.log("URL="+url);
106
107             URLConnection JavaDoc connection = url.openConnection();
108             connection.setAllowUserInteraction(false);
109             
110             // Set method
111
HttpURLConnection JavaDoc http = null;
112             if (connection instanceof HttpURLConnection JavaDoc)
113             {
114                 http = (HttpURLConnection JavaDoc)connection;
115                 http.setRequestMethod(request.getMethod());
116                 http.setInstanceFollowRedirects(false);
117             }
118
119             // check connection header
120
String JavaDoc connectionHdr = request.getHeader("Connection");
121             if (connectionHdr!=null)
122             {
123                 connectionHdr=connectionHdr.toLowerCase();
124                 if (connectionHdr.equals("keep-alive")||
125                     connectionHdr.equals("close"))
126                     connectionHdr=null;
127             }
128             
129             // copy headers
130
boolean xForwardedFor=false;
131             boolean hasContent=false;
132             Enumeration JavaDoc enm = request.getHeaderNames();
133             while (enm.hasMoreElements())
134             {
135                 // TODO could be better than this!
136
String JavaDoc hdr=(String JavaDoc)enm.nextElement();
137                 String JavaDoc lhdr=hdr.toLowerCase();
138
139                 if (_DontProxyHeaders.contains(lhdr))
140                     continue;
141                 if (connectionHdr!=null && connectionHdr.indexOf(lhdr)>=0)
142                     continue;
143
144                 if ("content-type".equals(lhdr))
145                     hasContent=true;
146
147                 Enumeration JavaDoc vals = request.getHeaders(hdr);
148                 while (vals.hasMoreElements())
149                 {
150                     String JavaDoc val = (String JavaDoc)vals.nextElement();
151                     if (val!=null)
152                     {
153                         connection.addRequestProperty(hdr,val);
154                         context.log("req "+hdr+": "+val);
155                         xForwardedFor|="X-Forwarded-For".equalsIgnoreCase(hdr);
156                     }
157                 }
158             }
159
160             // Proxy headers
161
connection.setRequestProperty("Via","1.1 (jetty)");
162             if (!xForwardedFor)
163                 connection.addRequestProperty("X-Forwarded-For",
164                                               request.getRemoteAddr());
165
166             // a little bit of cache control
167
String JavaDoc cache_control = request.getHeader("Cache-Control");
168             if (cache_control!=null &&
169                 (cache_control.indexOf("no-cache")>=0 ||
170                  cache_control.indexOf("no-store")>=0))
171                 connection.setUseCaches(false);
172
173             // customize Connection
174

175             try
176             {
177                 connection.setDoInput(true);
178                 
179                 // do input thang!
180
InputStream JavaDoc in=request.getInputStream();
181                 if (hasContent)
182                 {
183                     connection.setDoOutput(true);
184                     IO.copy(in,connection.getOutputStream());
185                 }
186                 
187                 // Connect
188
connection.connect();
189             }
190             catch (Exception JavaDoc e)
191             {
192                 context.log("proxy",e);
193             }
194             
195             InputStream JavaDoc proxy_in = null;
196
197             // handler status codes etc.
198
int code=500;
199             if (http!=null)
200             {
201                 proxy_in = http.getErrorStream();
202                 
203                 code=http.getResponseCode();
204                 response.setStatus(code,http.getResponseMessage());
205                 context.log("response = "+http.getResponseCode());
206             }
207             
208             if (proxy_in==null)
209             {
210                 try {proxy_in=connection.getInputStream();}
211                 catch (Exception JavaDoc e)
212                 {
213                     context.log("stream",e);
214                     proxy_in = http.getErrorStream();
215                 }
216             }
217             
218             // clear response defaults.
219
response.setHeader("Date",null);
220             response.setHeader("Server",null);
221             
222             // set response headers
223
int h=0;
224             String JavaDoc hdr=connection.getHeaderFieldKey(h);
225             String JavaDoc val=connection.getHeaderField(h);
226             while(hdr!=null || val!=null)
227             {
228                 String JavaDoc lhdr = hdr!=null?hdr.toLowerCase():null;
229                 if (hdr!=null && val!=null && !_DontProxyHeaders.contains(lhdr))
230                     response.addHeader(hdr,val);
231
232                 context.log("res "+hdr+": "+val);
233                 
234                 h++;
235                 hdr=connection.getHeaderFieldKey(h);
236                 val=connection.getHeaderField(h);
237             }
238             response.addHeader("Via","1.1 (jetty)");
239
240             // Handle
241
if (proxy_in!=null)
242                 IO.copy(proxy_in,response.getOutputStream());
243             
244         }
245     }
246
247
248     /* ------------------------------------------------------------ */
249     public void handleConnect(HttpServletRequest JavaDoc request,
250                               HttpServletResponse JavaDoc response)
251         throws IOException JavaDoc
252     {
253         String JavaDoc uri = request.getRequestURI();
254         
255         context.log("CONNECT: "+uri);
256         
257         InetAddrPort addrPort=new InetAddrPort(uri);
258         
259         //if (isForbidden(HttpMessage.__SSL_SCHEME,addrPort.getHost(),addrPort.getPort(),false))
260
//{
261
// sendForbid(request,response,uri);
262
//}
263
//else
264
{
265             InputStream JavaDoc in=request.getInputStream();
266             OutputStream JavaDoc out=response.getOutputStream();
267             
268             Socket JavaDoc socket = new Socket JavaDoc(addrPort.getInetAddress(),addrPort.getPort());
269             context.log("Socket: "+socket);
270             
271             response.setStatus(200);
272             response.setHeader("Connection","close");
273             response.flushBuffer();
274             
275             System.err.println(response);
276
277             context.log("out<-in");
278             IO.copyThread(socket.getInputStream(),out);
279             context.log("in->out");
280             IO.copy(in,socket.getOutputStream());
281         }
282     }
283     
284     
285     
286     
287     /* (non-Javadoc)
288      * @see javax.servlet.Servlet#getServletInfo()
289      */

290     public String JavaDoc getServletInfo()
291     {
292         return "Proxy Servlet";
293     }
294
295     /* (non-Javadoc)
296      * @see javax.servlet.Servlet#destroy()
297      */

298     public void destroy()
299     {
300
301     }
302 }
303
Popular Tags