All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.dev.util.NetProxy Maven / Gradle / Ivy

/*
 * Copyright 2006 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.dev.util;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * A blind byte-by-byte bi-directional proxy.
 */
public class NetProxy {

  private class ClientToServerProxyConnection extends ProxyConnection {
    public ClientToServerProxyConnection(Socket clientSideSocket,
        Socket serverSideSocket) {
      super(clientSideSocket, serverSideSocket);
      setName(fromPort + " => " + toPort + " #" + connections);
    }

    @Override
    protected void recordBytesTransferred(byte[] bytes, int avail) {
      addBytesSent(avail, bytes);
    }
  }

  private abstract class ProxyConnection extends Thread {
    private Socket fromSocket;
    private Socket toSocket;

    public ProxyConnection(Socket fromSocket, Socket toSocket) {
      this.fromSocket = fromSocket;
      this.toSocket = toSocket;
    }

    @Override
    public void run() {
      try {
        InputStream fromSideInput = fromSocket.getInputStream();
        OutputStream toSideOutput = toSocket.getOutputStream();

        /*
         * Spin and pass data in one direction.
         */
        int avail;
        byte[] bytes = new byte[32768];
        while (true) {
          // Read 'from' side
          avail = fromSideInput.read(bytes);
          if (avail > 0) {
            // Forward to 'to' side
            toSideOutput.write(bytes, 0, avail);
            // Accumulate bytes received
            recordBytesTransferred(bytes, avail);
          } else if (avail == -1) {
            break;
          }
        }
      } catch (Throwable e) {
      } finally {
        try {
          fromSocket.close();
          toSocket.close();
        } catch (Throwable e) {
        }
      }
    }

    protected abstract void recordBytesTransferred(byte[] bytes, int avail);
  }
  private class ServerToClientProxyConnection extends ProxyConnection {
    public ServerToClientProxyConnection(Socket clientSideSocket,
        Socket serverSideSocket) {
      super(serverSideSocket, clientSideSocket);
      setName(fromPort + " <= " + toPort + " #" + connections);
    }

    @Override
    protected void recordBytesTransferred(byte[] bytes, int avail) {
      addBytesReceived(avail, bytes);
    }
  }

  public static void main(String[] args) {
    if (args.length < 2) {
      System.out.println("Usage: NetProxy   []");
      return;
    }

    int localPort = Integer.parseInt(args[0]);
    int remotePort = Integer.parseInt(args[1]);
    String remoteHost = args.length < 3 ? "localhost" : args[2];
    NetProxy netProxy = new NetProxy(localPort, remoteHost, remotePort, true);
    netProxy.run();
  }

  private boolean dumpChars;
  private int fromPort;
  private String toName;
  private int toPort;
  private int bytesSent;
  private int bytesReceived;

  private int connections;

  private boolean end;

  private long startTime = System.currentTimeMillis();

  public NetProxy(int fromPort, String toName, int toPort, boolean dumpChars) {
    this.fromPort = fromPort;
    this.toName = toName;
    this.toPort = toPort;
    this.dumpChars = dumpChars;
  }

  public void end() {
    end = true;
  }

  public void run() {
    try {
      System.out.println("Time\tBytes Sent\tBytes Received\tTotal Bytes\tHTTP Data");
      ServerSocket serverSocket = new ServerSocket(fromPort);
      while (!end) {
        try {
          ++connections;

          /*
           * Listen for and accept the client-initiated connection. Connect to
           * the real server. Spawn a thread to handle the data shuffling for
           * newly-created connection.
           */
          Socket clientSideSocket = serverSocket.accept();
          clientSideSocket.setTcpNoDelay(true);

          Socket serverSideSocket = new Socket(toName, toPort);
          serverSideSocket.setTcpNoDelay(true);

          new ClientToServerProxyConnection(clientSideSocket, serverSideSocket).start();
          new ServerToClientProxyConnection(clientSideSocket, serverSideSocket).start();
        } catch (Throwable e) {
          e.printStackTrace();
        }
      }
    } catch (Throwable e) {
      // Failed to even be able to listen.
      e.printStackTrace();
    }
  }

  protected int getBytesReceived() {
    return bytesReceived;
  }

  protected int getBytesSent() {
    return bytesSent;
  }

  private synchronized void addBytesReceived(int byteCount, byte[] bytes) {
    bytesReceived += byteCount;
    log(0, byteCount, bytes);
  }

  private synchronized void addBytesSent(int byteCount, byte[] bytes) {
    this.bytesSent += byteCount;
    log(byteCount, 0, bytes);
  }

  private synchronized void log(int bytesSent, int bytesReceived,
      byte[] dataBuffer) {
    System.out.print(System.currentTimeMillis() - startTime);
    System.out.print("\t");
    System.out.print(bytesSent);
    System.out.print("\t");
    System.out.print(bytesReceived);
    System.out.print("\t");
    System.out.print(this.bytesSent + this.bytesReceived);
    System.out.print("\t");
    char ch;
    int avail = (bytesSent != 0 ? bytesSent : bytesReceived);
    if (dumpChars) {
      int limit = (avail < 1024 ? avail : 1024);
      for (int i = 0; i < limit; ++i) {
        ch = (char) dataBuffer[i];
        if (ch >= 32 && ch < 128) {
          System.out.print(ch);
        } else if (ch == '\n') {
          System.out.print("\\n");
        } else if (ch == '\r') {
          System.out.print("\\r");
        } else {
          System.out.print('.');
        }
      }
    } else {
      // Just read up to the \r\n\r\n.
      //
      try {
        String http = new String(dataBuffer, "UTF-8");
        int endOfHeaders = http.indexOf("\r\n\r\n");
        if (endOfHeaders != -1 && http.indexOf("HTTP") != -1) {
          http = http.replaceAll("\\r", "");
          http = http.replaceAll("\\n", "\n\t\t\t\t");
          System.out.print(http.substring(0, endOfHeaders));
        } else {
          System.out.print("(data)");
        }
      } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
      }
    }

    System.out.println();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy