Skip to content

Instantly share code, notes, and snippets.

@brianmed
Last active December 26, 2015 04:09
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save brianmed/7091198 to your computer and use it in GitHub Desktop.
package Mojo::UserAgent::Proxy;
use Mojo::Base -base;
has [qw(http https no)];
sub detect {
my $self = shift;
$self->http($ENV{HTTP_PROXY} || $ENV{http_proxy});
$self->https($ENV{HTTPS_PROXY} || $ENV{https_proxy});
return $self->no([split /,/, $ENV{NO_PROXY} || $ENV{no_proxy} || '']);
}
# sub _start {
# ...
# $self->proxy->inject($tx);
# ...
# }
sub inject {
my ($self, $tx) = @_;
$self->detect if $ENV{MOJO_PROXY};
my $proto = $url->protocol;
if ($self->need_proxy($url->host)) {
# HTTP proxy
my $http = $self->http_proxy;
$req->proxy($http) if $http && !defined $req->proxy && $proto eq 'http';
# HTTPS proxy
my $https = $self->https_proxy;
$req->proxy($https) if $https && !defined $req->proxy && $proto eq 'https';
}
}
sub is_needed {
!first { $_[1] =~ /\Q$_\E$/ } @{$_[0]->no_proxy || []};
}
# $self->proxy->config($tx)
# sub _connect_proxy {
# my ($self, $old, $cb) = @_;
#
# # Start CONNECT request
# return undef unless my $new = $self->proxy->connect($old);
# return $self->_start($new => $self->proxy->start);
# }
sub connect {
my ($self, $old) = @_;
# Already a CONNECT request
my $req = $old->req;
return undef if uc $req->method eq 'CONNECT';
# No proxy
return undef unless my $proxy = $req->proxy;
# WebSocket and/or HTTPS
my $url = $req->url;
my $upgrade = lc($req->headers->upgrade // '');
return undef unless $upgrade eq 'websocket' || $url->protocol eq 'https';
# CONNECT request
my $new = $self->tx(CONNECT => $url->clone->userinfo(undef));
$new->req->proxy($proxy);
return $new;
}
sub start {
my ($self, $tx) = @_;
# CONNECT failed (connection needs to be kept alive)
unless ($tx->keep_alive && $tx->res->is_status_class(200)) {
$old->req->error('Proxy connection failed');
return $self->$cb($old);
}
# Prevent proxy reassignment and start real transaction
$old->req->proxy(0);
my $id = $tx->connection;
return $self->_start($old->connection($id), $cb)
unless $tx->req->url->protocol eq 'https';
# TLS upgrade
my $loop = $self->_loop;
my $handle = $loop->stream($id)->steal_handle;
my $c = delete $self->{connections}{$id};
$loop->remove($id);
weaken $self;
$id = $self->_connect($self->transactor->endpoint($old),
$handle, sub { $self->_start($old->connection($id), $cb) });
$self->{connections}{$id} = $c;
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment