mirror of
https://github.com/gnh1201/caterpillar.git
synced 2024-11-26 15:31:45 +00:00
Remove unused workers (will be refactor)
This commit is contained in:
parent
a73ff414c2
commit
96f77b956f
|
@ -1,182 +0,0 @@
|
|||
// https://github.com/gnh1201/caterpillar
|
||||
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const net = require('net');
|
||||
const tls = require('tls');
|
||||
|
||||
const DEFAULT_SOCKET_TIMEOUT = 1000; // milliseconds
|
||||
const STATEFUL_SOCKET_TIMEOUT = 30000; // milliseconds
|
||||
|
||||
const app = express();
|
||||
const port = 3000; // listening port number
|
||||
|
||||
app.use(bodyParser.json());
|
||||
|
||||
function jsonrpc2_encode(method, params, id = '') {
|
||||
const data = {
|
||||
jsonrpc: '2.0',
|
||||
method: method,
|
||||
params: params,
|
||||
id: id
|
||||
};
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
function jsonrpc2_error_encode(error, id = '') {
|
||||
const data = {
|
||||
jsonrpc: '2.0',
|
||||
error: error,
|
||||
id: id
|
||||
};
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
function read_from_remote_server(remote_address, remote_port, scheme, data = null, conn = null, buffer_size = 8192, id = '') {
|
||||
const sock = scheme === "https" || scheme === "ssl" || scheme === "tls"
|
||||
? tls.connect(remote_port, remote_address)
|
||||
: net.connect(remote_port, remote_address);
|
||||
|
||||
sock.on('error', error => {
|
||||
const err = {
|
||||
status: 502,
|
||||
code: error.code,
|
||||
message: error.message
|
||||
};
|
||||
|
||||
if (!conn) {
|
||||
console.log(jsonrpc2_error_encode(err, id));
|
||||
} else {
|
||||
let buf = `HTTP/1.1 502 Bad Gateway\r\n\r\n`;
|
||||
buf += jsonrpc2_error_encode(err, id);
|
||||
conn.write(buf);
|
||||
}
|
||||
});
|
||||
|
||||
sock.on('connect', () => {
|
||||
if (!conn) {
|
||||
sock.write(data);
|
||||
|
||||
sock.on('data', buf => {
|
||||
console.log(buf.toString());
|
||||
});
|
||||
} else {
|
||||
conn.on('data', buf => {
|
||||
sock.write(buf);
|
||||
});
|
||||
|
||||
sock.on('data', buf => {
|
||||
conn.write(buf);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
sock.on('end', () => {
|
||||
sock.end();
|
||||
});
|
||||
}
|
||||
|
||||
function relay_request(params, id = '') {
|
||||
const { buffer_size, request_data, request_length, client_address, client_port, client_encoding, remote_address, remote_port, scheme, datetime } = params;
|
||||
|
||||
const request_header = parse_headers(Buffer.from(request_data, 'base64').toString());
|
||||
|
||||
switch (request_header['@method'][0]) {
|
||||
case 'CONNECT':
|
||||
const err = {
|
||||
status: 405,
|
||||
code: -1,
|
||||
message: "Method Not Allowed"
|
||||
};
|
||||
console.log(jsonrpc2_error_encode(err, id));
|
||||
break;
|
||||
|
||||
default:
|
||||
read_from_remote_server(remote_address, remote_port, scheme, Buffer.from(request_data, 'base64'), null, buffer_size, id);
|
||||
}
|
||||
}
|
||||
|
||||
function relay_connect(params, id = '') {
|
||||
const { buffer_size, client_address, client_port, client_encoding, remote_address, remote_port, scheme, datetime } = params;
|
||||
|
||||
const starttime = Date.now();
|
||||
const sock = net.connect(client_port, client_address);
|
||||
|
||||
sock.on('error', error => {
|
||||
const err = {
|
||||
status: 502,
|
||||
code: error.code,
|
||||
message: error.message,
|
||||
_params: params
|
||||
};
|
||||
console.log(jsonrpc2_error_encode(err, id));
|
||||
});
|
||||
|
||||
sock.on('connect', () => {
|
||||
const stoptime = Date.now();
|
||||
const connection_speed = Math.floor((stoptime - starttime));
|
||||
const data = jsonrpc2_encode("relay_accept", {
|
||||
success: true,
|
||||
connection_speed: connection_speed
|
||||
}, id);
|
||||
sock.write(data + '\r\n\r\n');
|
||||
|
||||
read_from_remote_server(remote_address, remote_port, scheme, null, sock, buffer_size, id);
|
||||
});
|
||||
}
|
||||
|
||||
function parse_headers(str) {
|
||||
const headers = {};
|
||||
|
||||
const lines = str.split(/\r?\n/);
|
||||
|
||||
const first_line = lines.shift();
|
||||
headers['@method'] = first_line.split(' ');
|
||||
|
||||
lines.forEach(line => {
|
||||
const match = line.match(/^([^:]+):(.*)$/);
|
||||
if (match) {
|
||||
headers[match[1]] = match[2].trim();
|
||||
}
|
||||
});
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
function get_client_address(req, res) {
|
||||
const client_address = req.ip;
|
||||
const response = {
|
||||
client_address: client_address
|
||||
};
|
||||
res.json(response);
|
||||
}
|
||||
|
||||
app.post('/', (req, res) => {
|
||||
const context = req.body;
|
||||
if (context.jsonrpc === '2.0') {
|
||||
const method = context.method;
|
||||
switch (method) {
|
||||
case 'relay_request':
|
||||
relay_request(context.params, context.id);
|
||||
break;
|
||||
|
||||
case 'relay_connect':
|
||||
relay_connect(context.params, context.id);
|
||||
break;
|
||||
|
||||
case 'get_client_address':
|
||||
get_client_address(req, res);
|
||||
break;
|
||||
|
||||
default:
|
||||
res.status(400).send('Invalid method');
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
res.status(400).send('Invalid JSON-RPC version');
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server is running on port ${port}`);
|
||||
});
|
|
@ -1,204 +0,0 @@
|
|||
# https://github.com/gnh1201/caterpillar
|
||||
|
||||
use JSON;
|
||||
use IO::Socket::INET;
|
||||
use IO::Socket::SSL;
|
||||
use Time::HiRes qw(time);
|
||||
|
||||
use constant DEFAULT_SOCKET_TIMEOUT => 1;
|
||||
use constant STATEFUL_SOCKET_TIMEOUT => 30;
|
||||
|
||||
sub jsonrpc2_encode {
|
||||
my ($method, $params, $id) = @_;
|
||||
my $data = {
|
||||
jsonrpc => "2.0",
|
||||
method => $method,
|
||||
params => $params,
|
||||
id => $id
|
||||
};
|
||||
return encode_json($data);
|
||||
}
|
||||
|
||||
sub jsonrpc2_result_encode {
|
||||
my ($result, $id) = @_;
|
||||
my $data = {
|
||||
jsonrpc => "2.0",
|
||||
result => $result,
|
||||
id => $id
|
||||
};
|
||||
return encode_json($data);
|
||||
}
|
||||
|
||||
sub jsonrpc2_error_encode {
|
||||
my ($error, $id) = @_;
|
||||
my $data = {
|
||||
jsonrpc => "2.0",
|
||||
error => $error,
|
||||
id => $id
|
||||
};
|
||||
return encode_json($data);
|
||||
}
|
||||
|
||||
sub parse_headers {
|
||||
my ($str) = @_;
|
||||
my %headers;
|
||||
|
||||
my @lines = split(/\r?\n/, $str);
|
||||
|
||||
my $first_line = shift(@lines);
|
||||
$headers{'@method'} = [split(' ', $first_line)];
|
||||
|
||||
foreach my $line (@lines) {
|
||||
if ($line =~ /^([^:]+):(.*)$/) {
|
||||
$headers{$1} = trim($2);
|
||||
}
|
||||
}
|
||||
|
||||
return \%headers;
|
||||
}
|
||||
|
||||
sub read_from_remote_server {
|
||||
my ($remote_address, $remote_port, $scheme, $data, $conn, $buffer_size, $id) = @_;
|
||||
my $sock;
|
||||
if ($scheme ~~ ["https", "ssl", "tls"]) {
|
||||
$sock = IO::Socket::SSL->new(
|
||||
PeerAddr => $remote_address,
|
||||
PeerPort => $remote_port,
|
||||
SSL_verify_mode => 0, # You may adjust SSL options as needed
|
||||
Timeout => DEFAULT_SOCKET_TIMEOUT
|
||||
);
|
||||
} else {
|
||||
$sock = IO::Socket::INET->new(
|
||||
PeerAddr => $remote_address,
|
||||
PeerPort => $remote_port,
|
||||
Proto => 'tcp',
|
||||
Timeout => DEFAULT_SOCKET_TIMEOUT
|
||||
);
|
||||
}
|
||||
|
||||
if (!$sock) {
|
||||
my $error = {
|
||||
status => 502,
|
||||
code => $!,
|
||||
message => $@
|
||||
};
|
||||
|
||||
if (!$conn) {
|
||||
print jsonrpc2_error_encode($error, $id);
|
||||
} else {
|
||||
my $buf = sprintf("HTTP/1.1 502 Bad Gateway\r\n\r\n");
|
||||
$buf .= jsonrpc2_error_encode($error, $id);
|
||||
print $conn $buf;
|
||||
}
|
||||
} else {
|
||||
if (!$conn) {
|
||||
# send data
|
||||
print $sock $data;
|
||||
|
||||
# receive data
|
||||
my $buf;
|
||||
while (!eof($sock) && defined($buf = <$sock>)) {
|
||||
print $buf;
|
||||
}
|
||||
} else {
|
||||
# send data
|
||||
my $buf;
|
||||
while (!eof($conn) && defined($buf = <$conn>)) {
|
||||
print $sock $buf;
|
||||
}
|
||||
|
||||
# receive data
|
||||
$buf = "";
|
||||
while (!eof($sock) && defined($buf = <$sock>)) {
|
||||
print $conn $buf;
|
||||
}
|
||||
}
|
||||
|
||||
close($sock);
|
||||
}
|
||||
}
|
||||
|
||||
sub relay_request {
|
||||
my ($params, $id) = @_;
|
||||
my $buffer_size = $params->{'buffer_size'};
|
||||
my $request_data = decode_base64($params->{'request_data'});
|
||||
my $request_header = parse_headers($request_data);
|
||||
my $request_length = int($params->{'request_length'});
|
||||
my $client_address = $params->{'client_address'};
|
||||
my $client_port = int($params->{'client_port'});
|
||||
my $client_encoding = $params->{'client_encoding'};
|
||||
my $remote_address = $params->{'remote_address'};
|
||||
my $remote_port = int($params->{'remote_port'});
|
||||
my $scheme = $params->{'scheme'};
|
||||
my $datetime = $params->{'datetime'};
|
||||
|
||||
given ($request_header->{'@method'}[0]) {
|
||||
when ("CONNECT") {
|
||||
my $error = {
|
||||
status => 405,
|
||||
code => -1,
|
||||
message => "Method Not Allowed"
|
||||
};
|
||||
print jsonrpc2_error_encode($error, $id);
|
||||
}
|
||||
default {
|
||||
read_from_remote_server($remote_address, $remote_port, $scheme, $request_data, undef, $buffer_size, $id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub relay_connect {
|
||||
my ($params, $id) = @_;
|
||||
my $buffer_size = $params->{'buffer_size'};
|
||||
my $client_address = $params->{'client_address'};
|
||||
my $client_port = int($params->{'client_port'});
|
||||
my $client_encoding = $params->{'client_encoding'};
|
||||
my $remote_address = $params->{'remote_address'};
|
||||
my $remote_port = int($params->{'remote_port'});
|
||||
my $scheme = $params->{'scheme'};
|
||||
my $datetime = $params->{'datetime'};
|
||||
|
||||
my $starttime = time();
|
||||
my $conn = IO::Socket::INET->new(
|
||||
PeerAddr => $client_address,
|
||||
PeerPort => $client_port,
|
||||
Proto => 'tcp',
|
||||
Timeout => STATEFUL_SOCKET_TIMEOUT
|
||||
);
|
||||
if (!$conn) {
|
||||
my $error = {
|
||||
status => 502,
|
||||
code => $!,
|
||||
message => $@
|
||||
};
|
||||
print jsonrpc2_error_encode($error, $id);
|
||||
} else {
|
||||
my $stoptime = time();
|
||||
my $connection_speed = int(($stoptime - $starttime) * 1000);
|
||||
my $data = jsonrpc2_encode("relay_accept", {
|
||||
success => 1,
|
||||
connection_speed => $connection_speed
|
||||
}, $id);
|
||||
print $conn $data . "\r\n\r\n";
|
||||
|
||||
read_from_remote_server($remote_address, $remote_port, $scheme, undef, $conn, $buffer_size, $id);
|
||||
close($conn);
|
||||
}
|
||||
}
|
||||
|
||||
# Parse a context
|
||||
my $json_input = do { local $/; <STDIN> };
|
||||
my $context = decode_json($json_input);
|
||||
|
||||
# Check if it's JSON-RPC 2 (stateless)
|
||||
if ($context->{'jsonrpc'} eq "2.0") {
|
||||
my $method = $context->{'method'};
|
||||
given ($method) {
|
||||
when ("relay_request") {
|
||||
relay_request($context->{'params'}, $context->{'id'}); # stateless mode
|
||||
}
|
||||
when ("relay_connect") {
|
||||
relay_connect($context->{'params'}, $context->{'id'}); # stateful mode
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
# https://github.com/gnh1201/caterpillar
|
||||
|
||||
require 'socket'
|
||||
require 'json'
|
||||
require 'openssl'
|
||||
require 'base64'
|
||||
require 'timeout'
|
||||
|
||||
DEFAULT_SOCKET_TIMEOUT = 1
|
||||
STATEFUL_SOCKET_TIMEOUT = 30
|
||||
|
||||
def jsonrpc2_encode(method, params, id = '')
|
||||
{
|
||||
"jsonrpc" => "2.0",
|
||||
"method" => method,
|
||||
"params" => params,
|
||||
"id" => id
|
||||
}.to_json
|
||||
end
|
||||
|
||||
def jsonrpc2_result_encode(result, id = '')
|
||||
{
|
||||
"jsonrpc" => "2.0",
|
||||
"result" => result,
|
||||
"id" => id
|
||||
}.to_json
|
||||
end
|
||||
|
||||
def jsonrpc2_error_encode(error, id = '')
|
||||
{
|
||||
"jsonrpc" => "2.0",
|
||||
"error" => error,
|
||||
"id" => id
|
||||
}.to_json
|
||||
end
|
||||
|
||||
def parse_headers(str)
|
||||
headers = {}
|
||||
lines = str.split(/\r?\n/)
|
||||
first_line = lines.shift.split(' ')
|
||||
headers['@method'] = first_line
|
||||
lines.each do |line|
|
||||
if match = line.match(/^([^:]+):(.*)$/)
|
||||
headers[match[1]] = match[2].strip
|
||||
end
|
||||
end
|
||||
headers
|
||||
end
|
||||
|
||||
def read_from_remote_server(remote_address, remote_port, scheme, data = nil, conn = nil, buffer_size = 8192, id = '')
|
||||
if ["https", "ssl", "tls"].include?(scheme)
|
||||
ssl_context = OpenSSL::SSL::SSLContext.new
|
||||
sock = OpenSSL::SSL::SSLSocket.new(TCPSocket.open(remote_address, remote_port), ssl_context)
|
||||
sock.connect
|
||||
else
|
||||
sock = TCPSocket.open(remote_address, remote_port)
|
||||
end
|
||||
|
||||
if sock.nil?
|
||||
error = {
|
||||
"status" => 502,
|
||||
"code" => error_code,
|
||||
"message" => error_message
|
||||
}
|
||||
|
||||
if conn.nil?
|
||||
puts jsonrpc2_error_encode(error, id)
|
||||
else
|
||||
buf = "HTTP/1.1 502 Bad Gateway\r\n\r\n"
|
||||
buf += jsonrpc2_error_encode(error, id)
|
||||
conn.write(buf)
|
||||
end
|
||||
else
|
||||
if conn.nil?
|
||||
sock.write(data) unless data.nil?
|
||||
|
||||
buf = nil
|
||||
while buf != false && !sock.eof?
|
||||
buf = sock.gets(buffer_size)
|
||||
puts buf
|
||||
end
|
||||
else
|
||||
buf = nil
|
||||
while buf != false && !conn.eof?
|
||||
buf = conn.gets(buffer_size)
|
||||
sock.write(buf)
|
||||
end
|
||||
|
||||
buf = nil
|
||||
while buf != false && !sock.eof?
|
||||
buf = sock.gets(buffer_size)
|
||||
conn.write(buf)
|
||||
end
|
||||
end
|
||||
|
||||
sock.close
|
||||
end
|
||||
end
|
||||
|
||||
def relay_request(params, id = '')
|
||||
buffer_size = params['buffer_size']
|
||||
request_data = Base64.decode64(params['request_data'])
|
||||
request_header = parse_headers(request_data)
|
||||
request_length = params['request_length'].to_i
|
||||
client_address = params['client_address']
|
||||
client_port = params['client_port'].to_i
|
||||
client_encoding = params['client_encoding']
|
||||
remote_address = params['remote_address']
|
||||
remote_port = params['remote_port'].to_i
|
||||
scheme = params['scheme']
|
||||
datetime = params['datetime'] # format: %Y-%m-%d %H:%M:%S.%f
|
||||
|
||||
begin
|
||||
Timeout.timeout(DEFAULT_SOCKET_TIMEOUT) do
|
||||
if ["https", "ssl", "tls"].include?(scheme)
|
||||
ssl_context = OpenSSL::SSL::SSLContext.new
|
||||
sock = OpenSSL::SSL::SSLSocket.new(TCPSocket.open(remote_address, remote_port), ssl_context)
|
||||
sock.connect
|
||||
else
|
||||
sock = TCPSocket.open(remote_address, remote_port)
|
||||
end
|
||||
end
|
||||
rescue Timeout::Error
|
||||
error = {
|
||||
"status" => 504,
|
||||
"message" => "Gateway Timeout"
|
||||
}
|
||||
puts jsonrpc2_error_encode(error, id)
|
||||
return
|
||||
end
|
||||
|
||||
case request_header['@method'][0]
|
||||
when "CONNECT"
|
||||
error = {
|
||||
"status" => 405,
|
||||
"code" => -1,
|
||||
"message" => "Method Not Allowed"
|
||||
}
|
||||
puts jsonrpc2_error_encode(error, id)
|
||||
else
|
||||
read_from_remote_server(remote_address, remote_port, scheme, request_data, nil, buffer_size, id)
|
||||
end
|
||||
end
|
||||
|
||||
def relay_connect(params, id = '')
|
||||
buffer_size = params['buffer_size']
|
||||
client_address = params['client_address']
|
||||
client_port = params['client_port'].to_i
|
||||
client_encoding = params['client_encoding']
|
||||
remote_address = params['remote_address']
|
||||
remote_port = params['remote_port'].to_i
|
||||
scheme = params['scheme']
|
||||
datetime = params['datetime'] # format: %Y-%m-%d %H:%M:%S.%f
|
||||
|
||||
starttime = Time.now.to_f
|
||||
|
||||
begin
|
||||
Timeout.timeout(STATEFUL_SOCKET_TIMEOUT) do
|
||||
conn = TCPSocket.open(client_address, client_port)
|
||||
end
|
||||
rescue Timeout::Error
|
||||
error = {
|
||||
"status" => 504,
|
||||
"message" => "Gateway Timeout"
|
||||
}
|
||||
puts jsonrpc2_error_encode(error, id)
|
||||
return
|
||||
end
|
||||
|
||||
stoptime = Time.now.to_f
|
||||
connection_speed = ((stoptime - starttime) * 1000).to_i
|
||||
data = jsonrpc2_encode("relay_accept", {
|
||||
"success" => true,
|
||||
"connection_speed" => connection_speed
|
||||
}, id)
|
||||
conn.write(data + "\r\n\r\n")
|
||||
|
||||
read_from_remote_server(remote_address, remote_port, scheme, nil, conn, buffer_size, id)
|
||||
conn.close
|
||||
end
|
||||
|
||||
context = JSON.parse(STDIN.read)
|
||||
|
||||
if context['jsonrpc'] == "2.0"
|
||||
method = context['method']
|
||||
case method
|
||||
when "relay_request"
|
||||
relay_request(context['params'], context['id'])
|
||||
when "relay_connect"
|
||||
relay_connect(context['params'], context['id'])
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user