App-Pod

 view release on metacpan or  search on metacpan

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

    # Corrupted connection
    return $self->_remove( $id ) unless my $tx = $self->{connections}{$id}{tx};
    warn term_escape "-- Client <<< Server (@{[_url($tx)]})\n$chunk\n" if DEBUG;
    $tx->client_read( $chunk );
    $self->_finish( $id ) if $tx->is_finished;
}

sub _redirect {
    my ( $self, $c, $old ) = @_;
    return undef unless my $new = $self->transactor->redirect( $old );
    return undef unless @{ $old->redirects } < $self->max_redirects;
    return $self->_start( $c->{ioloop}, $new, delete $c->{cb} );
}

sub _remove {
    my ( $self, $id ) = @_;
    my $c = delete $self->{connections}{$id};
    $self->_dequeue( $c->{ioloop}, $id );
    $c->{ioloop}->remove( $id );
}

sub _reuse {
    my ( $self, $id, $close ) = @_;

    # Connection close
    my $c   = $self->{connections}{$id};
    my $tx  = delete $c->{tx};
    my $max = $self->max_connections;
    return $self->_remove( $id )
      if $close || !$tx || !$max || !$tx->keep_alive || $tx->error;

    # Keep connection alive
    my $queue = $self->{queue}{ $c->{ioloop} } //= [];
    $self->_remove( shift( @$queue )->[1] ) while @$queue && @$queue >= $max;
    push @$queue, [ join( ':', $self->transactor->endpoint( $tx ) ), $id ];
}

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

    # Application server
    $self->emit( prepare => $tx );
    my $url = $tx->req->url;
    if ( !$url->is_abs && ( my $server = $self->server ) ) {
        my $base = $loop == $self->ioloop ? $server->url : $server->nb_url;
        $url->scheme( $base->scheme )->host( $base->host )->port( $base->port );
    }

    $_->prepare( $tx ) for $self->proxy, $self->cookie_jar;
    my $max = $self->max_response_size;
    $tx->res->max_message_size( $max ) if defined $max;
    $self->emit( start => $tx );

    # Allow test servers sharing the same event loop to clean up connections
    !$loop->next_tick( sub { } ) and $loop->one_tick unless $loop->is_running;
    return undef unless my $id = $self->_connection( $loop, $tx, $cb );

    if ( my $t = $self->request_timeout ) {
        weaken $self;
        $self->{connections}{$id}{timeout} ||=
          $loop->timer( $t => sub { $self->_error( $id, 'Request timeout' ) } );
    }

    return $id;
}

sub _url { shift->req->url->to_abs }

sub _write {
    my ( $self, $id ) = @_;

    # Protect from resume event recursion
    my $c = $self->{connections}{$id};
    return if !( my $tx = $c->{tx} ) || $c->{writing};
    local $c->{writing} = 1;
    my $chunk = $tx->client_write;
    warn term_escape "-- Client >>> Server (@{[_url($tx)]})\n$chunk\n" if DEBUG;
    return unless length $chunk;

    weaken $self;
    $c->{ioloop}->stream( $id )
      ->write( $chunk => sub { $self && $self->_write( $id ) } );
}

1;

=encoding utf8

=head1 NAME

Mojo::UserAgent - Non-blocking I/O HTTP and WebSocket user agent

=head1 SYNOPSIS

  use Mojo::UserAgent;

  # Fine grained response handling (dies on connection errors)
  my $ua  = Mojo::UserAgent->new;
  my $res = $ua->get('docs.mojolicious.org')->result;
  if    ($res->is_success)  { say $res->body }
  elsif ($res->is_error)    { say $res->message }
  elsif ($res->code == 301) { say $res->headers->location }
  else                      { say 'Whatever...' }

  # Say hello to the Unicode snowman and include an Accept header
  say $ua->get('www.☃.net?hello=there' => {Accept => '*/*'})->result->body;

  # Extract data from HTML and XML resources with CSS selectors
  say $ua->get('www.perl.org')->result->dom->at('title')->text;

  # Scrape the latest headlines from a news site
  say $ua->get('blogs.perl.org')->result->dom->find('h2 > a')->map('text')->join("\n");

  # IPv6 PUT request with Content-Type header and content
  my $tx = $ua->put('[::1]:3000' => {'Content-Type' => 'text/plain'} => 'Hi!');

  # Quick JSON API request with Basic authentication
  my $url = Mojo::URL->new('https://example.com/test.json')->userinfo('sri:☃');
  my $value = $ua->get($url)->result->json;

  # JSON POST (application/json) with TLS certificate authentication



( run in 1.206 second using v1.01-cache-2.11-cpan-39bf76dae61 )