1 25 26 package net.killingar.servlet; 27 28 import javax.servlet.http.HttpServlet ; 29 import javax.servlet.http.HttpServletRequest ; 30 import javax.servlet.http.HttpServletResponse ; 31 import java.io.BufferedOutputStream ; 32 import java.io.IOException ; 33 import java.io.InputStream ; 34 import java.io.OutputStream ; 35 import java.net.InetAddress ; 36 import java.net.MalformedURLException ; 37 import java.net.Socket ; 38 import java.net.URL ; 39 40 public class TunnelServlet extends HttpServlet 41 { 42 private String host; 43 private int port; 44 private String root; 45 46 public TunnelServlet() 47 { 48 } 49 50 public void init() 51 { 52 try 53 { 54 URL url = new URL (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 e) 62 { 63 e.printStackTrace(); 64 log("TunnelServlet: targetRoot does not specify a valid URL", e); 65 } 66 } 67 68 public void service(HttpServletRequest request, HttpServletResponse response) throws IOException 69 { 70 Socket socket = new Socket (InetAddress.getByName(host), port); 71 72 if (!socket.isBound() || socket.isClosed() || !socket.isConnected() || socket.isOutputShutdown() || socket.isInputShutdown()) 73 { 74 throw new RuntimeException ("error connecting to client"); 75 } 76 77 OutputStream out = socket.getOutputStream(); 78 InputStream in = socket.getInputStream(); 79 BufferedOutputStream buf = new BufferedOutputStream (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 request, OutputStream out, byte[] buffer) throws IOException 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 e = request.getHeaderNames(); e.hasMoreElements();) 103 { 104 String n = (String )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 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 e) 124 { 125 } 126 } 127 128 protected void sendResponse(InputStream in, HttpServletResponse response, byte[] buffer) throws IOException 129 { 130 OutputStream 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 e){} 140 141 if (System.currentTimeMillis()-start > 1000*60) throw new RuntimeException ("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 response, byte[] buffer, int length) 183 { 184 String [] s = new String (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 [] 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 |