File: connect-proxy.pl

package info (click to toggle)
libmojolicious-perl 2.98%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 2,968 kB
  • sloc: perl: 10,178; sh: 48; makefile: 8
file content (79 lines) | stat: -rw-r--r-- 2,405 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use FindBin;
use lib "$FindBin::Bin/../lib";
use Mojo::Base -strict;

# "Cheating in a fake fight. That's low."
use Mojo::IOLoop;

# Connection buffer
my %buffer;

# Minimal connect proxy server to test TLS tunneling
Mojo::IOLoop->server(
  {port => 3000} => sub {
    my ($loop, $stream, $client) = @_;
    $stream->on(
      read => sub {
        my ($stream, $chunk) = @_;
        if (my $server = $buffer{$client}{connection}) {
          return Mojo::IOLoop->stream($server)->write($chunk);
        }
        $buffer{$client}{client} .= $chunk;
        if ($buffer{$client}{client} =~ /\x0d?\x0a\x0d?\x0a$/) {
          my $buffer = $buffer{$client}{client};
          $buffer{$client}{client} = '';
          if ($buffer =~ /CONNECT (\S+):(\d+)?/) {
            my $address = $1;
            my $port = $2 || 80;
            my $server;
            $server = Mojo::IOLoop->client(
              {address => $address, port => $port} => sub {
                my ($loop, $err, $stream) = @_;
                if ($err) {
                  say "Connection error for $address:$port: $err";
                  Mojo::IOLoop->remove($client);
                  return delete $buffer{$client};
                }
                say "Forwarding to $address:$port.";
                $buffer{$client}{connection} = $server;
                $stream->on(
                  read => sub {
                    my ($stream, $chunk) = @_;
                    Mojo::IOLoop->stream($client)->write($chunk);
                  }
                );
                $stream->on(
                  close => sub {
                    Mojo::IOLoop->remove($client);
                    delete $buffer{$client};
                  }
                );
                Mojo::IOLoop->stream($client)
                  ->write("HTTP/1.1 200 OK\x0d\x0a"
                    . "Connection: keep-alive\x0d\x0a\x0d\x0a");
              }
            );
          }
        }
        else { Mojo::IOLoop->remove($client) }
      }
    );
    $stream->on(
      close => sub {
        Mojo::IOLoop->remove($buffer{$client}{connection})
          if $buffer{$client}{connection};
        delete $buffer{$client};
      }
    );
  }
) or die "Couldn't create listen socket!\n";

print <<'EOF';
Starting connect proxy on port 3000.
For testing use something like "HTTPS_PROXY=http://127.0.0.1:3000".
EOF

# Start loop
Mojo::IOLoop->start;

1;