KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > killingar > servlet > TunnelServlet


1 /* Copyright 2000-2005 Anders Hovmöller
2  *
3  * The person or persons who have associated their work with
4  * this document (the "Dedicator") hereby dedicate the entire
5  * copyright in the work of authorship identified below (the
6  * "Work") to the public domain.
7  *
8  * Dedicator makes this dedication for the benefit of the
9  * public at large and to the detriment of Dedicator's heirs
10  * and successors. Dedicator intends this dedication to be an
11  * overt act of relinquishment in perpetuity of all present
12  * and future rights under copyright law, whether vested or
13  * contingent, in the Work. Dedicator understands that such
14  * relinquishment of all rights includes the relinquishment of
15  * all rights to enforce (by lawsuit or otherwise) those
16  * copyrights in the Work.
17  *
18  * Dedicator recognizes that, once placed in the public
19  * domain, the Work may be freely reproduced, distributed,
20  * transmitted, used, modified, built upon, or otherwise
21  * exploited by anyone for any purpose, commercial or non-
22  * commercial, and in any way, including by methods that have
23  * not yet been invented or conceived.
24  */

25
26 package net.killingar.servlet;
27
28 import javax.servlet.http.HttpServlet JavaDoc;
29 import javax.servlet.http.HttpServletRequest JavaDoc;
30 import javax.servlet.http.HttpServletResponse JavaDoc;
31 import java.io.BufferedOutputStream JavaDoc;
32 import java.io.IOException JavaDoc;
33 import java.io.InputStream JavaDoc;
34 import java.io.OutputStream JavaDoc;
35 import java.net.InetAddress JavaDoc;
36 import java.net.MalformedURLException JavaDoc;
37 import java.net.Socket JavaDoc;
38 import java.net.URL JavaDoc;
39
40 public class TunnelServlet extends HttpServlet JavaDoc
41 {
42     private String JavaDoc host;
43     private int port;
44     private String JavaDoc root;
45
46     public TunnelServlet()
47     {
48     }
49
50     public void init()
51     {
52         try
53         {
54             URL JavaDoc url = new URL JavaDoc(getInitParameter("targetRoot"));
55             host = url.getHost();
56             port = url.getPort();
57             if (port == -1)
58                 port = 80;
59             root = url.getFile();
60         }
61         catch(MalformedURLException JavaDoc e)
62         {
63             e.printStackTrace();
64             log("TunnelServlet: targetRoot does not specify a valid URL", e);
65         }
66     }
67
68     public void service(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) throws IOException JavaDoc
69     {
70         Socket JavaDoc socket = new Socket JavaDoc(InetAddress.getByName(host), port);
71
72         if (!socket.isBound() || socket.isClosed() || !socket.isConnected() || socket.isOutputShutdown() || socket.isInputShutdown())
73         {
74             throw new RuntimeException JavaDoc("error connecting to client");
75         }
76
77         OutputStream JavaDoc out = socket.getOutputStream();
78         InputStream JavaDoc in = socket.getInputStream();
79         BufferedOutputStream JavaDoc buf = new BufferedOutputStream JavaDoc(out);
80
81     byte[] buffer = new byte[65536];
82         sendRequest(request, buf, buffer);
83
84         response.reset();
85         sendResponse(in, response, buffer);
86
87         buf.flush();
88         out.flush();
89         out.close();
90     }
91
92     protected void sendRequest(HttpServletRequest JavaDoc request, OutputStream JavaDoc out, byte[] buffer) throws IOException JavaDoc
93     {
94         try
95         {
96             out.write(request.getMethod().getBytes(request.getCharacterEncoding()));
97             out.write(' ');
98             out.write(request.getRequestURI().getBytes(request.getCharacterEncoding()));
99             out.write(" HTTP/1.1\n".getBytes(request.getCharacterEncoding()));
100             out.flush();
101
102             for (java.util.Enumeration JavaDoc e = request.getHeaderNames(); e.hasMoreElements();)
103             {
104                 String JavaDoc n = (String JavaDoc)e.nextElement();
105                 out.write(n.getBytes(request.getCharacterEncoding()));
106                 out.write(':');
107                 out.write(request.getHeader(n).getBytes(request.getCharacterEncoding()));
108                 out.write('\n');
109             }
110
111             out.write('\n');
112
113             InputStream JavaDoc in = request.getInputStream();
114
115             while (in.available() > 0)
116             {
117                 int read = in.read(buffer, 0, 65536);
118         out.write(buffer, 0, read);
119             }
120
121             out.flush();
122         }
123         catch(ArrayIndexOutOfBoundsException JavaDoc e)
124         {
125         }
126     }
127
128     protected void sendResponse(InputStream JavaDoc in, HttpServletResponse JavaDoc response, byte[] buffer) throws IOException JavaDoc
129     {
130         OutputStream JavaDoc out = response.getOutputStream();
131
132         long start = System.currentTimeMillis();
133         while (in.available() <= 0)
134         {
135             try
136             {
137                 Thread.sleep(10);
138             }
139             catch (Exception JavaDoc e){}
140
141             if (System.currentTimeMillis()-start > 1000*60) // one minute timeout
142
throw new RuntimeException JavaDoc("timeout");
143         }
144
145
146         boolean parsingHeaders = true;
147         while (in.available() > 0)
148         {
149             int read = in.read(buffer, 0, 65536);
150
151             if (read < 0)
152                 break;
153
154             if (parsingHeaders)
155             {
156                 for (int i = 0; i < read-4; i++)
157                 {
158                     if (
159                         (buffer[i] == '\n' || buffer[i] == '\r') &&
160                         (buffer[i+1] == '\n' || buffer[i+1] == '\r') &&
161                         (buffer[i+2] == '\n' || buffer[i+2] == '\r')
162                         )
163                     {
164                         parsingHeaders = false;
165
166                         handleHeaders(response, buffer, i+4);
167
168                         out.write(buffer, i+4, read-i-4);
169
170                         if (read != buffer.length)
171                             return;
172                     }
173                 }
174             }
175             else
176             {
177                 out.write(buffer, 0, read);
178             }
179         }
180     }
181
182     protected void handleHeaders(HttpServletResponse JavaDoc response, byte[] buffer, int length)
183     {
184         String JavaDoc[] s = new String JavaDoc(buffer, 0, length).split("[\\n\\r]");
185
186         for (int i = 0; i < s.length; i++)
187         {
188             if (s[i].indexOf(':') != -1)
189             {
190                 String JavaDoc[] s2 = s[i].split(":");
191                 if (!s2[0].equalsIgnoreCase("Content-Length"))
192                 {
193                     response.setHeader(s2[0], s2[1]);
194                 }
195             }
196         }
197     }
198 }
199
Popular Tags