java实现轻量型http代理服务器示例

复制代码 代码如下:

package cn.liangjintang.httpproxy;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class HttpProxy {
 static long threadCount = 0;
 int myTcpPort = 8080;
 private ServerSocket myServerSocket;
 private Thread myThread;

 public HttpProxy(int port) throws IOException {
  myTcpPort = port;
  myServerSocket = new ServerSocket(myTcpPort);
  myThread = new Thread(new Runnable() {
   public void run() {
    try {
     while (true)
      new HTTPSession(myServerSocket.accept());
    } catch (IOException ioe) {
    }
   }
  });
  myThread.setDaemon(true);
  myThread.start();
 }

 /**
  * Stops the server.
  */

 public void stop() {
  try {
   myServerSocket.close();
   myThread.join();
  } catch (IOException ioe) {
  } catch (InterruptedException e) {
  }
 }

 public class HTTPSession implements Runnable {
  private Socket mySocket;

  public HTTPSession(Socket s) {
   mySocket = s;
   Thread t = new Thread(this);
   t.setDaemon(true);
   t.start();
  }

  @Override
  public void run() {
   try {
    ++threadCount;

    InputStream is = mySocket.getInputStream();
    if (is == null)
     return;
    final int bufsize = 8192;
    byte[] buf = new byte[bufsize];
    int splitbyte = 0;
    int rlen = 0;
    {
     int read = is.read(buf, 0, bufsize);
     while (read > 0) {
      rlen += read;
      splitbyte = findHeaderEnd(buf, rlen);
      if (splitbyte > 0)
       break;
      read = is.read(buf, rlen, bufsize - rlen);
     }
     ByteArrayInputStream hbis = new ByteArrayInputStream(buf,
       0, rlen);
     BufferedReader hin = new BufferedReader(
       new InputStreamReader(hbis));
     Host host = new Host();
     {
      String string;
      boolean flag = false;
      while ((string = hin.readLine()) != null) {
       if (string.toLowerCase().startsWith("host:")) {
        host.host = string;
        flag = true;
       }
       System.out.println(string);
      }
      if (!flag) {
       mySocket.getOutputStream().write(
         "error!".getBytes());
       mySocket.close();
       return;
      }
     }

     host.cal();
     System.out.println("address:[" + host.address + "]port:"
       + host.port + "\n-------------------\n");

     try {
      pipe(buf, rlen, mySocket, mySocket.getInputStream(),
        mySocket.getOutputStream(), host);
     } catch (Exception e) {
      System.out.println("Run Exception!");
      e.printStackTrace();
     }
    }

   } catch (Exception e) {
   }
   System.out.println("threadcount:" + --threadCount);
  }

  /**
   * finad http header
   **/
  private int findHeaderEnd(final byte[] buf, int rlen) {
   int splitbyte = 0;
   while (splitbyte + 3 < rlen) {
    if (buf[splitbyte] == '\r' && buf[splitbyte + 1] == '\n'
      && buf[splitbyte + 2] == '\r'
      && buf[splitbyte + 3] == '\n')
     return splitbyte + 4;
    splitbyte++;
   }
   return 0;
  }

  void pipe(byte[] request, int requestLen, Socket client,
    InputStream clientIS, OutputStream clientOS, Host host)
    throws Exception {
   byte bytes[] = new byte[1024 * 32];
   Socket socket = new Socket(host.address, host.port);
   socket.setSoTimeout(3000);
   OutputStream os = socket.getOutputStream();
   InputStream is = socket.getInputStream();
   try {
    do {
     os.write(request, 0, requestLen);
     int resultLen = 0;
     try {
      while ((resultLen = is.read(bytes)) != -1
        && !mySocket.isClosed() && !socket.isClosed()) {
       clientOS.write(bytes, 0, resultLen);
      }
     } catch (Exception e) {
      System.out.println("target Socket exception:"
        + e.toString());
     }

     System.out.println("proxy requset-connect broken,socket:"
       + socket.hashCode());
    } while (!mySocket.isClosed()
      && (requestLen = clientIS.read(request)) != -1);
   } catch (Exception e) {
    System.out.println("client Socket exception:" + e.toString());
   }

   System.out.println("end,socket:" + socket.hashCode());
   os.close();
   is.close();
   clientIS.close();
   clientOS.close();
   socket.close();
   mySocket.close();

  }

  // target Host info
  final class Host {
   public String address;
   public int port;
   public String host;

   public boolean cal() {
    if (host == null)
     return false;
    int start = host.indexOf(": ");
    if (start == -1)
     return false;
    int next = host.indexOf(':', start + 2);
    if (next == -1) {
     port = 80;
     address = host.substring(start + 2);
    } else {
     address = host.substring(start + 2, next);
     port = Integer.valueOf(host.substring(next + 1));
    }
    return true;
   }
  }
 }

 public static void main(String[] args) {
  try {
   new HttpProxy(8580);
  } catch (IOException ioe) {
   System.err.println("Couldn't start server:\n" + ioe);
   System.exit(-1);
  }
  System.out.println("start!");
  try {
   System.in.read();
  } catch (Throwable t) {
  }
  System.out.println("stop!");
 }
}

你可能感兴趣的:(java实现轻量型http代理服务器示例)