Warning: session_start(): open(/var/lib/php/sessions/sess_l8i0qvdnb3fnketu6erqa6se8l, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
abstract sclass StandaloneHttpProxy implements AutoCloseable {
bool debug;
int port = 8443;
Set blockedIPs = syncSet();
Thread acceptThread;
ServerSocket makeServerSocket() throws IOException {
ret new ServerSocket(port);
}
abstract HostAndPort forwardServerAndPort(Request req);
ServerSocket serverSocket;
void start() throws IOException {
serverSocket = makeServerSocket();
acceptThread = startThread("HTTP Proxy Accept Port " + port, r acceptLoop);
print("HTTP proxy on port " + port + " started.");
}
void acceptLoop() throws IOException {
while (true) {
try {
Socket s = serverSocket.accept();
new Request(s).run();
} catch (SocketTimeoutException e) {
}
}
}
S rewriteHeaderLine(S line) {
/*if (startsWithIgnoreCase(line, "Host:"))
line = "Host: " + forwardServer + ":" + forwardPort;*/
ret line;
}
svoid headerSend(OutputStream out, S header) ctex {
print("Sending header: " + header);
out.write((header + "\r\n").getBytes("US-ASCII"));
}
close { dispose serverSocket; }
class Request is AutoCloseable {
Socket s; // client socket
S client;
bool blocked;
Socket outSocket;
new AtomicLong transmitted;
new AtomicLong outTransmitted;
Thread thread, inThread, outThread;
OutputStream out, outOut;
InputStream in, outIn;
MultiMap incomingHeaders = ciMultiMap();
bool forwardedFor;
S host;
*(Socket *s) {}
run {
client = dropPrefix("/", s.getInetAddress().toString()); // Hmm... how to get the actual IP properly?
S threadName = "PROXY: Handling client " + client;
if (blocked = blockedIPs.contains(client)) {
print("Blocked IP!! " + client);
pcall { s.close(); }
ret;
}
thread = startDaemonThread(threadName, r handleIt_impl);
} // Request.run
void handleIt_impl() throws IOException {
try {
print("HTTP Proxy Incoming!");
out = s.getOutputStream();
in = s.getInputStream();
// collect headers
new ByteArrayOutputStream headersOut;
while (true) {
S line = readHttpHeaderLine(in);
if (line == null) ret;
print("Header line read: " + quote(line));
int i = indexOf(line, ':');
if (i >= 0)
incomingHeaders.put(trim(takeFirst(i, line)), trim(dropFirst(i+1, line)));
if (startsWithIgnoreCase(line, "Host:"))
host = dropPrefixIgnoreCase("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;
}
HostAndPort hap = forwardServerAndPort(this);
if (hap == null || empty(hap.host) || hap.port == 0)
ret with print("Can't forward request");
S forwardServer = hap.host;
int port = hap.port;
outSocket = new Socket(forwardServer, port);
print("Connected to " + forwardServer + ":" + port);
outOut = outSocket.getOutputStream();
outIn = outSocket.getInputStream();
outOut.write(headersOut.toByteArray());
if (!forwardedFor)
headerSend(outOut, "X-Forwarded-For: " + client);
headerSend(outOut, "Host: " + addPortToHost(host, port));
headerSend(outOut, ""); // end of headers
outOut.flush();
// forward content in both directions
inThread = startThread("Proxy In", r proxyIn_impl);
outThread = startThread("Proxy Out", r proxyOut_impl);
joinThreads(inThread, outThread);
} catch (IOException e) {
print("[internal] " + e);
} finally {
print("Proxy request done, got " + transmitted! + ", sent " + outTransmitted! + " + headers");
close();
}
} // end of handleIt_impl
void proxyIn_impl ctex {
try {
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);
}
} finally {
print("Shutting down client output.");
s.shutdownOutput();
}
}
void proxyOut_impl() throws IOException {
try {
print("Proxy Out started.");
byte[] buf = new byte[1];
while (true) {
int n = in.read(buf);
if (n <= 0) return;
outOut.write(buf, 0, n);
if (outTransmitted.get() == 0)
print("Proxy Out first byte!");
long t = outTransmitted.addAndGet(n);
if (t % (debug ? 10 : 100000) == 0) print("Transmitted to server: " + t);
}
} finally {
print("Shutting down server output.");
outSocket.shutdownOutput();
}
}
close {
dispose s;
dispose outSocket;
}
} // end of Request
}