1 package HTTP
::AnyUA
::Backend
::Mojo
::UserAgent
;
2 # ABSTRACT: A unified programming interface for Mojo::UserAgent
6 This module adds support for the HTTP client L<Mojo::UserAgent> to be used with the unified
7 programming interface provided by L<HTTP::AnyUA>.
9 If installed, requests will return L<Future::Mojo> rather than L<Future>. This allows the use of the
10 C<< ->get >> method to await a result.
15 * The C<url> field in the response has the auth portion (if any) removed from the URL.
20 * L<HTTP::AnyUA::Backend>
27 our $VERSION = '9999.999'; # VERSION
29 use parent
'HTTP::AnyUA::Backend';
37 $future_class = 'Future';
38 eval 'use Future::Mojo'; ## no critic
39 $future_class = 'Future::Mojo' if !$@;
43 sub response_is_future
{ 1 }
47 my ($method, $url, $args) = @_;
49 my $future = $future_class->new;
51 my $tx = $self->_munge_request(@_);
53 $self->ua->start($tx => sub {
57 my $resp = $self->_munge_response($tx, $args->{data_callback
});
59 if ($resp->{success
}) {
77 my $headers = $args->{headers
} || {};
78 my $content = $args->{content
};
84 for my $header (keys %$headers) {
85 if (lc($header) eq 'content-length') {
86 $content_length = $headers->{$header};
91 # if we don't know the length we have to just read it all in
92 $content = HTTP
::AnyUA
::Util
::coderef_content_to_string
($content) if !$content_length;
94 push @content, $content if ref($content) ne 'CODE';
97 my $tx = $self->ua->build_tx($method => $url => $headers => @content);
99 if (ref($content) eq 'CODE') {
100 $tx->req->headers->content_length($content_length);
105 my $chunk = $content->() || '';
106 undef $drain if !$chunk;
107 $body->write($chunk, $drain);
109 $tx->req->content->$drain;
112 if (my $data_cb = $args->{data_callback
}) {
113 # stream the response
115 Scalar
::Util
::weaken
($tx_copy);
116 $tx->res->content->unsubscribe('read')->on(read => sub {
117 my ($content, $bytes) = @_;
118 my $resp = $self->_munge_response($tx_copy, undef);
119 $data_cb->($bytes, $resp);
126 sub _munge_response
{
133 success
=> !!$tx->res->is_success,
134 url
=> $tx->req->url->to_string,
135 status
=> $tx->res->code,
136 reason
=> $tx->res->message,
140 # lowercase header keys
141 my $headers = $tx->res->headers->to_hash;
142 for my $header (keys %$headers) {
143 $resp->{headers
}{lc($header)} = delete $headers->{$header};
146 my $version = $tx->res->version;
147 $resp->{protocol
} = "HTTP/$version" if $version;
150 for my $redirect (@{$tx->redirects}) {
151 push @{$resp->{redirects
} ||= []}, $self->_munge_response($redirect, undef, 1);
155 my $err = $tx->error;
156 if ($err && !$err->{code
}) {
157 return HTTP
::AnyUA
::Util
::internal_exception
($err->{message
}, $resp);
160 my $body = $tx->res->body;
161 $resp->{content
} = $body if $body && !$data_cb;