App-Pod

 view release on metacpan or  search on metacpan

t/cpan/Mojo2/UserAgent.pm  view on Meta::CPAN

    }

    # Blocking
    warn "-- Blocking request (@{[_url($tx)]})\n" if DEBUG;
    $self->_start( $self->ioloop,
        $tx => sub { shift->ioloop->stop; $tx = shift } );
    $self->ioloop->start;

    return $tx;
}

sub start_p {
    my ( $self, $tx ) = @_;
    my $promise = Mojo::Promise->new;
    $self->start( $tx => sub { shift->transactor->promisify( $promise, shift ) }
    );
    return $promise;
}

sub websocket {
    my ( $self, $cb ) = ( shift, pop );
    $self->start( $self->build_websocket_tx( @_ ), $cb );
}

sub websocket_p {
    my $self = shift;
    return $self->start_p( $self->build_websocket_tx( @_ ) );
}

sub _cleanup {
    my $self = shift;
    delete $self->{pid};
    $self->_finish( $_, 1 ) for keys %{ $self->{connections} // {} };
    return $self;
}

sub _connect {
    my ( $self, $loop, $tx, $handle ) = @_;

    my $t = $self->transactor;
    my ( $proto, $host, $port ) =
      $handle ? $t->endpoint( $tx ) : $t->peer( $tx );

    my %options = ( timeout => $self->connect_timeout );
    if ( $proto eq 'http+unix' ) { $options{path} = $host }
    else { @options{qw(address port)} = ( $host, $port ) }
    $options{socket_options} = $self->socket_options;
    $options{handle}         = $handle if $handle;

    # SOCKS
    if ( $proto eq 'socks' ) {
        @options{qw(socks_address socks_port)} = @options{qw(address port)};
        ( $proto, @options{qw(address port)} ) = $t->endpoint( $tx );
        my $userinfo = $tx->req->via_proxy( 0 )->proxy->userinfo;
        @options{qw(socks_user socks_pass)} = split /:/, $userinfo if $userinfo;
    }

    # TLS
    if ( $options{tls} = $proto eq 'https' ) {
        map { $options{"tls_$_"} = $self->$_ } qw(ca cert key);
        $options{tls_options}{SSL_verify_mode} = 0x00 if $self->insecure;
    }

    weaken $self;
    my $id;
    return $id = $loop->client(
        %options => sub {
            my ( $loop, $err, $stream ) = @_;

            # Connection error
            return unless $self;
            return $self->_error( $id, $err ) if $err;

            # Connection established
            $stream->on(
                timeout => sub { $self->_error( $id, 'Inactivity timeout' ) } );
            $stream->on( close => sub { $self && $self->_finish( $id, 1 ) } );
            $stream->on( error => sub { $self && $self->_error( $id, pop ) } );
            $stream->on( read  => sub { $self->_read( $id, pop ) } );
            $self->_process( $id );
        }
    );
}

sub _connect_proxy {
    my ( $self, $loop, $old, $cb ) = @_;

    # Start CONNECT request
    return undef unless my $new = $self->transactor->proxy_connect( $old );
    my $id;
    return $id = $self->_start(
        ( $loop, $new ) => sub {
            my ( $self, $tx ) = @_;

            # Real transaction
            $old->previous( $tx )->req->via_proxy( 0 );
            my $c = $self->{connections}{$id} =
              { cb => $cb, ioloop => $loop, tx => $old };

            # CONNECT failed
            return $self->_error( $id, 'Proxy connection failed' )
              if $tx->error || !$tx->res->is_success || !$tx->keep_alive;

            # Start real transaction without TLS upgrade
            return $self->_process( $id )
              unless $tx->req->url->protocol eq 'https';

            # TLS upgrade before starting the real transaction
            my $handle = $loop->stream( $id )->steal_handle;
            $self->_remove( $id );
            $id = $self->_connect( $loop, $old, $handle );
            $self->{connections}{$id} = $c;
        }
    );
}

sub _connection {
    my ( $self, $loop, $tx, $cb ) = @_;

    # Reuse connection
    my ( $proto, $host, $port ) = $self->transactor->endpoint( $tx );

t/cpan/Mojo2/UserAgent.pm  view on Meta::CPAN

    say 'WebSocket handshake failed!' and return unless $tx->is_websocket;
    $tx->on(json => sub ($tx, $hash) {
      say "WebSocket message via JSON: $hash->{msg}";
      $tx->finish;
    });
    $tx->send({json => {msg => 'Hello World!'}});
  });
  Mojo::IOLoop->start unless Mojo::IOLoop->is_running;

=head1 DESCRIPTION

L<Mojo::UserAgent> is a full featured non-blocking I/O HTTP and WebSocket user agent, with IPv6, TLS, SNI, IDNA,
HTTP/SOCKS5 proxy, UNIX domain socket, Comet (long polling), Promises/A+, keep-alive, connection pooling, timeout,
cookie, multipart, gzip compression and multiple event loop support.

All connections will be reset automatically if a new process has been forked, this allows multiple processes to share
the same L<Mojo::UserAgent> object safely.

For better scalability (epoll, kqueue) and to provide non-blocking name resolution, SOCKS5 as well as TLS support, the
optional modules L<EV> (4.32+), L<Net::DNS::Native> (0.15+), L<IO::Socket::Socks> (0.64+) and L<IO::Socket::SSL>
(2.009+) will be used automatically if possible. Individual features can also be disabled with the C<MOJO_NO_NNR>,
C<MOJO_NO_SOCKS> and C<MOJO_NO_TLS> environment variables.

See L<Mojolicious::Guides::Cookbook/"USER AGENT"> for more.

=head1 EVENTS

L<Mojo::UserAgent> inherits all events from L<Mojo::EventEmitter> and can emit the following new ones.

=head2 prepare

  $ua->on(prepare => sub ($ua, $tx) {...});

Emitted whenever a new transaction is being prepared, before relative URLs are rewritten and cookies added. This
includes automatically prepared proxy C<CONNECT> requests and followed redirects.

  $ua->on(prepare => sub ($ua, $tx) {
    $tx->req->url(Mojo::URL->new('/mock-mojolicious')) if $tx->req->url->host eq 'mojolicious.org';
  });

=head2 start

  $ua->on(start => sub ($ua, $tx) {...});

Emitted whenever a new transaction is about to start. This includes automatically prepared proxy C<CONNECT> requests
and followed redirects.

  $ua->on(start => sub ($ua, $tx) {
    $tx->req->headers->header('X-Bender' => 'Bite my shiny metal ass!');
  });

=head1 ATTRIBUTES

L<Mojo::UserAgent> implements the following attributes.

=head2 ca

  my $ca = $ua->ca;
  $ua    = $ua->ca('/etc/tls/ca.crt');

Path to TLS certificate authority file used to verify the peer certificate, defaults to the value of the
C<MOJO_CA_FILE> environment variable.

  # Show certificate authorities for debugging
  IO::Socket::SSL::set_defaults(SSL_verify_callback => sub { say "Authority: $_[2]" and return $_[0] });

=head2 cert

  my $cert = $ua->cert;
  $ua      = $ua->cert('/etc/tls/client.crt');

Path to TLS certificate file, defaults to the value of the C<MOJO_CERT_FILE> environment variable.

=head2 connect_timeout

  my $timeout = $ua->connect_timeout;
  $ua         = $ua->connect_timeout(5);

Maximum amount of time in seconds establishing a connection may take before getting canceled, defaults to the value of
the C<MOJO_CONNECT_TIMEOUT> environment variable or C<10>.

=head2 cookie_jar

  my $cookie_jar = $ua->cookie_jar;
  $ua            = $ua->cookie_jar(Mojo::UserAgent::CookieJar->new);

Cookie jar to use for requests performed by this user agent, defaults to a L<Mojo::UserAgent::CookieJar> object.

  # Ignore all cookies
  $ua->cookie_jar->ignore(sub { 1 });

  # Ignore cookies for public suffixes
  my $ps = IO::Socket::SSL::PublicSuffix->default;
  $ua->cookie_jar->ignore(sub ($cookie) {
    return undef unless my $domain = $cookie->domain;
    return ($ps->public_suffix($domain))[0] eq '';
  });

  # Add custom cookie to the jar
  $ua->cookie_jar->add(
    Mojo::Cookie::Response->new(
      name   => 'foo',
      value  => 'bar',
      domain => 'docs.mojolicious.org',
      path   => '/Mojolicious'
    )
  );

=head2 inactivity_timeout

  my $timeout = $ua->inactivity_timeout;
  $ua         = $ua->inactivity_timeout(15);

Maximum amount of time in seconds a connection can be inactive before getting closed, defaults to the value of the
C<MOJO_INACTIVITY_TIMEOUT> environment variable or C<40>. Setting the value to C<0> will allow connections to be
inactive indefinitely.

=head2 insecure

  my $bool = $ua->insecure;
  $ua      = $ua->insecure($bool);

Do not require a valid TLS certificate to access HTTPS/WSS sites, defaults to the value of the C<MOJO_INSECURE>
environment variable.



( run in 1.793 second using v1.01-cache-2.11-cpan-13bb782fe5a )