Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

192
LINES

< > BotCompany Repo | #1002783 // HTTP Proxy (old)

JavaX source code [tags: use-pretranspiled] - run with: x30.jar

Libraryless. Click here for Pure Java version (2302L/16K/55K).

!752

static S vmArgs = "-XX:+PrintGC -Xmx32m";

static int port = 80;
static S forwardServer =
  //"ai1.lol";
  //"google.de";
  "localhost";

static Map<S, Integer> forwardMap = litmap(
  "thedevchannel.com", 3000,
  "default", 8080);

p {
  // Safety Rebooter - to hold up thedevchannel.com and ai1.lol when admin sleeps!
  
  thread "Rebooter" {
    sleepSeconds(60*60*24);
    nohupJavax(programID(), vmArgs);
    System.exit (0);
  }
  
  // turn off memory leak
  
  noPrintLog();
  
  // Now for the actual server...
  
  final ServerSocket serverSocket = new ServerSocket(port);

  Thread thread = new Thread("HTTP Proxy Accept Port " + port) { public void run() {
   try {
    while (true) {
      try {
        final Socket s = serverSocket.accept();
        
        thread "Lister" {
          sleepSeconds(5);
          listThreads();
        }
        
        final S client = dropPrefix("/", s.getInetAddress().toString()); // Hmm... how to get the actual IP properly?
        String threadName = "PROXY: Handling client " + client;

        Thread t2 = new Thread(threadName) {
          public void run() ctex {
            Socket outSocket = null;
            final new AtomicLong transmitted;
            final new AtomicLong outTransmitted;
            try {
              print("HTTP Proxy Incoming!");
              
              final OutputStream out = s.getOutputStream();
              final InputStream in = s.getInputStream();
              
              // collect headers
              
              new ByteArrayOutputStream headersOut;
              BufferedReader headerReader = new BufferedReader(new InputStreamReader(in, "US-ASCII"), 1);
              boolean forwardedFor = false;
              S host = null;
              while (true) {
                S line = headerReader.readLine();
                if (line == null) ret;
                print("Header line read: " + quote(line));
                
                if (startsWithIgnoreCase(line, "Host:"))
                  host = dropPrefix("Host:", line).trim();
                else {
                  S rewritten;
                  if (startsWithIgnoreCase(line, "X-Forwarded-For:")) {
                    forwardedFor = true;
                    rewritten = line + ", " + client;
                  } else
                    rewritten = empty(line) ? line : rewriteHeaderLine(line);
                  if (!eq(rewritten, line))
                    print("Rewritten as: " + quote(rewritten));
                  if (nempty(rewritten)) {
                    byte[] bytes = (rewritten + "\r\n").getBytes("US-ASCII");
                    //print("Sending: " + bytesToHex(bytes));
                    headersOut.write(bytes);
                  }
                }
                
                if (l(line) == 0)
                  break;
              }
              
              int port = getForwardPort(host);
              
              outSocket = new Socket(forwardServer, port);
              print("Connected to " + forwardServer + ":" + port);
              final OutputStream outOut = outSocket.getOutputStream();
              final InputStream outIn = outSocket.getInputStream();
              
              outOut.write(headersOut.toByteArray());
              
              if (!forwardedFor)
                headerSend(outOut, "X-Forwarded-For: " + client);
                
              headerSend(outOut, "Host: " + hostToPort(host, port));
              
              headerSend(outOut, ""); // end of headers
                
              outOut.flush();
              
              // forward content in both directions
              
              //copyStream(outIn, out);
              
              Thread inThread = new Thread("Proxy In") {
                public void run() ctex {
                  byte[] buf = new byte[1];
                  while (true) {
                    int n = outIn.read(buf);
                    if (n <= 0) return;
                    out.write(buf, 0, n);
                    long t = transmitted.addAndGet(n);
                    if (t % 100000 == 0) print("Transmitted to client: " + t);
                  }
                }
              };
              inThread.start();
              
              Thread outThread = new Thread("Proxy Out") {
                public void run() ctex {
                  byte[] buf = new byte[1];
                  while (true) {
                    int n = in.read(buf);
                    if (n <= 0) return;
                    outOut.write(buf, 0, n);
                    long t = outTransmitted.addAndGet(n);
                    if (t % 100000 == 0) print("Transmitted to server: " + t);
                  }
                }
              };
              outThread.start();
              
              inThread.join();
              //outThread.join();
            } catch (IOException e) {
              print("[internal] " + e);
            } finally {
              print("Proxy request done, got " + transmitted.get() + ", sent " + outTransmitted.get() + " + headers");
              pcall { s.close(); }
              pcall { if (outSocket != null) outSocket.close(); }
            }
          }
        }; // Thread t2
        t2.setDaemon(true);
        t2.start();
      } catch (SocketTimeoutException e) {
      }
    }   
   } catch (IOException e) {
     print("[internal] " + e);
   }
  }};
  thread.start();
 
  print("HTTP proxy on port " + port + " started."); 
}

static S rewriteHeaderLine(S line) {
  /*if (startsWithIgnoreCase(line, "Host:"))
    line = "Host: " + forwardServer + ":" + forwardPort;*/
  ret line;
}

static int getForwardPort(S host) {
  int i = host.indexOf(':');
  if (i >= 0)
    host = host.substring(0, i);
  host = host.toLowerCase();
  for (S key : forwardMap.keySet())
    if (eq(host, key) || host.endsWith("." + key))
      ret forwardMap.get(key);
  ret forwardMap.get("default");
}

static S hostToPort(S host, int port) {
  int i = host.indexOf(':');
  if (i >= 0)
    host = host.substring(0, i);
  ret host + ":" + port;
}

static void headerSend(OutputStream out, S header) ctex {
  print("Sending header: " + header);
  out.write((header + "\r\n").getBytes("US-ASCII"));
}

download  show line numbers  debug dex  old transpilations   

Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, jtubtzbbkimh, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1002783
Snippet name: HTTP Proxy (old)
Eternal ID of this version: #1002783/1
Text MD5: 7cd269f9330f62fd472129b2e293ffbd
Transpilation MD5: 406e055dc891f05f984c2bf8119c0e91
Author: stefan
Category: eleu
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-03-02 02:13:06
Source code size: 6429 bytes / 192 lines
Pitched / IR pitched: No / No
Views / Downloads: 897 / 938
Referenced in: #1002822 - HTTP Proxy (with partial close, OK)
#3000238 - Answer for stefanreich (>> t power bot)
#3000382 - Answer for ferdie (>> t = 1, f = 0)
#3000383 - Answer for funkoverflow (>> t=1, f=0 okay)