📄 proxyserver.java
字号:
package org.placelab.proxy;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import java.util.Enumeration;import java.util.Hashtable;import java.util.Vector;import org.placelab.util.StringUtil;public class ProxyServer extends SocketServer { public static final int DEFAULT_PORT = 2080; private Vector servlets = new Vector(); public ProxyServer (int port) { super(port, 10, "Placelab Proxy Server"); } public void addServlet (Servlet servlet) { if (!servlets.contains(servlet)) servlets.add(servlet); } private String readLine (InputStream in) { StringBuffer buffer = new StringBuffer(""); int c; try { in.mark(1); if (in.read() == -1) return null; else in.reset(); while ((c = in.read()) >= 0) { if ((c == 0) || (c == '\n') || (c == '\r')) break; else buffer.append((char)c); } if (c == '\r') { in.mark(1); if (in.read() != '\n') in.reset(); } } catch (Exception e) { e.printStackTrace(); } return buffer.toString(); } public static byte[] getByteArray (InputStream in) throws IOException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); boolean block = true; while (block) { int b; try { b = in.read(); buffer.write(b); } catch (IOException e) { block = false; } if (in.available() == 0) block = false; } return buffer.toByteArray(); } public void serviceSocket(Socket s) { StringBuffer remoteHostBuffer = new StringBuffer(); StringBuffer methodTypeBuffer = new StringBuffer(); String remoteHost = ""; String methodType = ""; int contentLen = -1; byte[] request = null; try { InputStream clientInput = s.getInputStream(); OutputStream clientOutput = s.getOutputStream(); int remotePort = 80; request = readRequest (clientInput, remoteHostBuffer, methodTypeBuffer); methodType = methodTypeBuffer.toString(); remoteHost = remoteHostBuffer.toString(); if (remoteHost.indexOf(':') != -1) { String[] hostname = StringUtil.split(remoteHost.toString(), ':', 2); remoteHost = hostname[0]; remotePort = Integer.parseInt(hostname[1]); } // We don't support stuff like this. if (methodType.equals("CONNECT") || methodType.equals("OPTIONS")) return; Socket remote = new Socket(remoteHost, remotePort); remote.setSoTimeout(5000); // System.out.println("### " + new String(request)); BufferedInputStream remoteIn = new BufferedInputStream(remote.getInputStream()); BufferedOutputStream remoteOut = new BufferedOutputStream(remote.getOutputStream()); remoteOut.write(request); remoteOut.flush(); StringBuffer header = new StringBuffer(); boolean inHeader = true; int i = 0; int responseCode = -1; String line = ""; // check response code line = readLine(remoteIn); if (line != null) { header.append(line + "\r\n"); String[] parts = line.split(" "); responseCode = Integer.parseInt(parts[1]); } // get the rest of the header info for (;;) { line = readLine(remoteIn); if (line == null) break; if (line.length() == 0) break; header.append(line + "\r\n"); if (line.toString().toLowerCase().startsWith("content-length:")) { String[] pair = line.toString().trim().split(" "); if (pair[1].trim().length() != 0) { contentLen = Integer.parseInt(pair[1]); } } } header.append("\r\n"); clientOutput.write(header.toString().getBytes(), 0, header.length()); // if we didn't get 200/OK from server, flush out what did get // because we might not get anything else. if ((responseCode != 200) && (contentLen == 0)) { clientOutput.flush(); } // server explicitly told use we're getting nothing. if (contentLen == 0) { clientOutput.flush(); return; } byte[] buf = new byte[4096]; int bytesIn = 0; while ( ((contentLen != -1 && i < contentLen) || contentLen == -1) && !remote.isInputShutdown() && ((bytesIn = remoteIn.read(buf)) >= 0) ) { clientOutput.write(buf, 0, bytesIn); i += bytesIn; } clientOutput.flush(); } catch (Exception e) { // silently fail } } public byte[] readRequest (InputStream in, StringBuffer remoteHost, StringBuffer methodType) throws IOException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); StringBuffer line = new StringBuffer(); for (boolean first = true; first || in.available() > 0; first = false) { int b; try { b = in.read(); } catch (IOException e) { // happens when peer disconnects or buffer is empty break; } if (b == -1) break; line.append((char) b); // catch \r\n case if (b == '\r') { in.mark(1); if (in.read() == '\n') { //buffer.write('\n'); line.append('\n'); } else { in.reset(); //oops, it wasn't \r\n, put it back } } if ( b == '\r' || b == '\n' ) { if (line.toString().toLowerCase().startsWith("host:")) { String[] pair = line.toString().trim().split(" "); remoteHost.append(pair[1].trim()); for (int j=0;j<servlets.size();j++) { Servlet servlet = (Servlet) servlets.get(j); Hashtable hash = servlet.injectHeaders(null); for (Enumeration e = hash.keys(); e.hasMoreElements();) { String key = (String) e.nextElement(); buffer.write(new String(key + ": " + ((String) hash.get(key)) + "\r\n").getBytes()); } } } else if (methodType.length() == 0) { String[] parts = line.toString().trim().split(" "); methodType.append(parts[0]); // Some HTTP servers don't like to be given the absolute URL if (parts[1].startsWith("http")) { parts[1] = parts[1].substring(parts[1].indexOf("/", 8)); } line.setLength(0); line.append(parts[0] + " " + parts[1] + " " + parts[2] + "\r\n"); } else if (line.toString().toLowerCase().startsWith("proxy-connection:")) { // this header was meant for us and not to be forwarded on. line.setLength(0); continue; } buffer.write(line.toString().getBytes()); line.setLength(0); } } return buffer.toByteArray(); } public static void main(String[] args) { ProxyServer proxy = new ProxyServer(2080); try { proxy.startServer(); } catch (Exception e) { e.printStackTrace(); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -