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

204
LINES

< > BotCompany Repo | #1011937 // Smart Bot HTTP Proxy (OK) - should now be safe from endless loops

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

Libraryless. Click here for Pure Java version (1662L/12K/41K).

1  
!7
2  
3  
static bool debug = false;
4  
static int port = 80;
5  
static L<S> blockedIPs = ll();
6  
7  
static S forwardURL() {
8  
  ret "http://localhost:4678";
9  
  //ret smartBotURL();
10  
}
11  
12  
p {
13  
  // Now for the actual server...
14  
  
15  
  final ServerSocket serverSocket = new ServerSocket(port);
16  
17  
  Thread thread = new Thread("HTTP Proxy Accept Port " + port) { public void run() {
18  
   try {
19  
    while (true) {
20  
      try {
21  
        final Socket s = serverSocket.accept();
22  
        
23  
        /*thread "Lister" {
24  
          sleepSeconds(5);
25  
          listThreads();
26  
        }*/
27  
        
28  
        final S client = dropPrefix("/", s.getInetAddress().toString()); // Hmm... how to get the actual IP properly?
29  
        String threadName = "PROXY: Handling client " + client;
30  
        
31  
        if (blockedIPs.contains(client)) {
32  
          print("Blocked IP!! " + client);
33  
          pcall { s.close(); }
34  
          continue;
35  
        }
36  
37  
        Thread t2 = new Thread(threadName) {
38  
          public void run() ctex {
39  
            Socket outSocket = null;
40  
            final new AtomicLong transmitted;
41  
            final new AtomicLong outTransmitted;
42  
            try {
43  
              print("HTTP Proxy Incoming!");
44  
              
45  
              final OutputStream out = s.getOutputStream();
46  
              final InputStream in = s.getInputStream();
47  
              
48  
              // collect headers
49  
              
50  
              new ByteArrayOutputStream headersOut;
51  
              //BufferedReader headerReader = new BufferedReader(new InputStreamReader(in, "US-ASCII"), 1);
52  
              boolean forwardedFor = false;
53  
              S host = null;
54  
              while (true) {
55  
                S line = readHeaderLine(in);
56  
                if (line == null) ret;
57  
                print("Header line read: " + quote(line));
58  
                
59  
                if (startsWithIgnoreCase(line, "Host:"))
60  
                  host = dropPrefixIgnoreCase("Host:", line).trim();
61  
                else {
62  
                  S rewritten;
63  
                  if (startsWithIgnoreCase(line, "X-Forwarded-For:")) {
64  
                    forwardedFor = true;
65  
                    rewritten = line + ", " + client;
66  
                    print("Forwarded for: " + rewritten);
67  
                  } else
68  
                    rewritten = empty(line) ? line : rewriteHeaderLine(line);
69  
                  if (!eq(rewritten, line))
70  
                    print("Rewritten as: " + quote(rewritten));
71  
                  if (nempty(rewritten)) {
72  
                    byte[] bytes = (rewritten + "\r\n").getBytes("US-ASCII");
73  
                    //print("Sending: " + bytesToHex(bytes));
74  
                    headersOut.write(bytes);
75  
                  }
76  
                }
77  
                
78  
                if (l(line) == 0)
79  
                  break;
80  
              }
81  
              
82  
              // if (eq(smartBotURL(), smartBotURL_default)) ...
83  
              
84  
              URL url = new URL(forwardURL());
85  
              S forwardServer = url.getHost();
86  
              if (isMyIP(hostToIP(forwardServer)))
87  
                fail("Routing to myself");
88  
              
89  
              int port = ifNegative(url.getPort(), 80);
90  
              outSocket = new Socket(forwardServer, port);
91  
              final Socket outS = outSocket;
92  
              print("Connected to " + forwardServer + ":" + port);
93  
              final OutputStream outOut = outSocket.getOutputStream();
94  
              final InputStream outIn = outSocket.getInputStream();
95  
              
96  
              if (!forwardedFor) {
97  
                S rewritten = "X-Forwarded-For: " + client;
98  
                //print("Forwarded for: " + rewritten);
99  
                //headerSend(outOut, rewritten);
100  
                headersOut.write((rewritten + "\r\n").getBytes("US-ASCII"));
101  
              }
102  
                
103  
              printIndent("{" + headersOut + "}");
104  
              outOut.write(headersOut.toByteArray());
105  
              
106  
              //headerSend(outOut, "Host: " + hostToPort(host, port));
107  
              
108  
              headerSend(outOut, ""); // end of headers
109  
                
110  
              outOut.flush();
111  
              
112  
              // forward content in both directions
113  
              
114  
              //copyStream(outIn, out);
115  
              
116  
              Thread inThread = new Thread("Proxy In") {
117  
                public void run() ctex {
118  
                  try {
119  
byte[] buf = new byte[1];
120  
                  while (true) {
121  
                    int n = outIn.read(buf);
122  
                    if (n <= 0) return;
123  
                    out.write(buf, 0, n);
124  
                    long t = transmitted.addAndGet(n);
125  
                    if (t % 100000 == 0) print("Transmitted to client: " + t);
126  
                  }
127  
} finally {
128  
print("Shutting down client output.");
129  
s.shutdownOutput();
130  
}
131  
                }
132  
              };
133  
              inThread.start();
134  
              
135  
              Thread outThread = new Thread("Proxy Out") {
136  
                public void run() ctex {
137  
try {
138  
                  print("Proxy Out started.");
139  
                  byte[] buf = new byte[1];
140  
                  while (true) {
141  
                    int n = in.read(buf);
142  
                    if (n <= 0) return;
143  
                    outOut.write(buf, 0, n);
144  
                    /*if (outTransmitted.get() == 0)
145  
                      print("Proxy Out first byte!");*/
146  
                    long t = outTransmitted.addAndGet(n);
147  
                    if (t % (debug ? 10 : 100000) == 0) print("Transmitted to server: " + t);
148  
                  }
149  
} finally {
150  
  print("Shutting down server output.");
151  
  outS.shutdownOutput();
152  
}
153  
                }
154  
              };
155  
              outThread.start();
156  
              
157  
              inThread.join();
158  
              outThread.join();
159  
            } catch (IOException e) {
160  
              print("[internal] " + e);
161  
            } finally {
162  
              print("Proxy request done, got " + transmitted.get() + ", sent " + outTransmitted.get() + " + headers");
163  
              pcall { s.close(); }
164  
              pcall { if (outSocket != null) outSocket.close(); }
165  
            }
166  
          }
167  
        }; // Thread t2
168  
        t2.setDaemon(true);
169  
        t2.start();
170  
      } catch (SocketTimeoutException e) {
171  
      }
172  
    }   
173  
   } catch (IOException e) {
174  
     print("[internal] " + e);
175  
   }
176  
  }};
177  
  thread.start();
178  
 
179  
  print("HTTP proxy on port " + port + " started."); 
180  
}
181  
182  
static S rewriteHeaderLine(S line) {
183  
  /*if (startsWithIgnoreCase(line, "Host:"))
184  
    line = "Host: " + forwardServer + ":" + forwardPort;*/
185  
  ret line;
186  
}
187  
188  
static void headerSend(OutputStream out, S header) ctex {
189  
  print("Sending header: " + header);
190  
  out.write((header + "\r\n").getBytes("US-ASCII"));
191  
}
192  
193  
static String readHeaderLine(InputStream inputStream) throws IOException {
194  
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
195  
    int c;
196  
    for (c = inputStream.read(); c != '\n' && c != -1 ; c = inputStream.read()) {
197  
        if (c != '\r')
198  
          byteArrayOutputStream.write(c);
199  
    }
200  
    if (c == -1 && byteArrayOutputStream.size() == 0) {
201  
        return null;
202  
    }
203  
    ret byteArrayOutputStream.toString("US-ASCII");
204  
}

Author comment

Began life as a copy of #1002822

download  show line numbers  debug dex  old transpilations   

Travelled to 16 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, ppjhyzlbdabe, pyentgdyhuwx, pzhvpgtvlbxg, sgthpswjdnle, tslmcundralx, tvejysmllsmz, vouqrxazstgt, vupmehlpavxc

No comments. add comment

Snippet ID: #1011937
Snippet name: Smart Bot HTTP Proxy (OK) - should now be safe from endless loops
Eternal ID of this version: #1011937/13
Text MD5: a152878e082697209618425bf8ac7ace
Transpilation MD5: 82111ef8027c53025e22eb373c48f6fc
Author: stefan
Category: javax / a.i. / html
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2017-12-25 00:24:18
Source code size: 7265 bytes / 204 lines
Pitched / IR pitched: No / No
Views / Downloads: 475 / 645
Version history: 12 change(s)
Referenced in: [show references]