This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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