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) |