Skip to content

Instantly share code, notes, and snippets.

@Logioniz
Last active December 25, 2015 20:07
Show Gist options
  • Save Logioniz/8bdd6bd8089837bfc7c0 to your computer and use it in GitHub Desktop.
Save Logioniz/8bdd6bd8089837bfc7c0 to your computer and use it in GitHub Desktop.
1-st not good variant of http/https proxy via CONNECT only method. 2-nd - is good simple http/https proxy.
#!/usr/bin/perl
use Mojo::Base -strict;
use Mojo::IOLoop;
use Mojo::UserAgent;
my %connections;
Mojo::IOLoop->server({port => 3128} => sub {
my ($loop, $stream_client, $client_id) = @_;
$stream_client->on(read => sub {
my ($stream_client, $data_client) = @_;
# Need coorectly detect first http message which have \r\n\r\n. Now code may have sometimes errors.
if (!$connections{$client_id} && $data_client =~ m/CONNECT ([^:]+):(\d+) HTTP/i) {
my ($server, $server_port) = ($1, $2);
$connections{$client_id} = my $server_id = Mojo::IOLoop->client(address => $server, port => $server_port => sub {
my ($loop, $err, $stream_server) = @_;
if ($err) {
delete $connections{$client_id};
return $stream_client->close;
}
$stream_client->write("HTTP/1.1 200 Connection established\r\n\r\n");
$stream_server->on(read => sub {
my ($stream_server, $data_server) = @_;
$stream_client->write($data_server);
});
$stream_server->on(close => sub {
delete $connections{$client_id};
$stream_client->close;
});
$stream_server->on(error => sub {
delete $connections{$client_id};
$stream_client->close;
});
});
} elsif (my $server_stream = Mojo::IOLoop->stream($connections{$client_id})) {
$server_stream->write($data_client)
} else {
warn '!!!!!!!!!';
}
});
});
Mojo::IOLoop->start;
#!/usr/bin/perl
use Mojo::Base -strict;
use Mojo::Log;
use Mojo::Message::Request;
use Mojo::IOLoop;
my %connections;
my $log = Mojo::Log->new(path => 'proxy.log', level => 'warn');
sub connection_close {
my ($client_id, $id) = @_;
eval { Mojo::IOLoop->remove($id) if $id };
delete $connections{$client_id};
}
sub connect_to_server {
my $client_id = shift;
my $request = $connections{$client_id}{request};
$connections{$client_id}{server_id} = Mojo::IOLoop->client(address => $request->url->ihost, port => $request->url->port // 80 => sub {
my ($loop, $err, $server_stream) = @_;
return connection_close($client_id, $client_id) if $err;
$server_stream->on(read => sub {
my ($server_stream, $server_data) = @_;
Mojo::IOLoop->stream($client_id)->write($server_data);
});
$server_stream->on(close => sub { connection_close($client_id, $client_id) });
$server_stream->on(error => sub { connection_close($client_id, $client_id); $log->error($_[1]) });
if ($request->method eq 'CONNECT') {
# connect method: https, http
Mojo::IOLoop->stream($client_id)->write("HTTP/1.1 200 Connection established\r\n\r\n");
} else {
# not connect method: http
$server_stream->write($request->to_string);
}
});
}
Mojo::IOLoop->server({port => 3128} => sub {
my ($loop, $client_stream, $client_id) = @_;
$connections{$client_id}{request} = Mojo::Message::Request->new;
$client_stream->on(read => sub {
my ($client_stream, $client_data) = @_;
unless ($connections{$client_id}{server_id}) {
my $request = $connections{$client_id}{request};
$request->parse($client_data);
connect_to_server($client_id) if $request->is_finished;
return;
}
if (my $server_stream = Mojo::IOLoop->stream($connections{$client_id}{server_id})) {
$server_stream->write($client_data)
} else {
$log->error('Panic: stream not defined!')
}
});
$client_stream->on(close => sub { connection_close($client_id, $connections{$client_id}{server_id}) });
$client_stream->on(error => sub { connection_close($client_id, $connections{$client_id}{server_id}); $log->error($_[1]) });
});
Mojo::IOLoop->start;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment