File Coverage

blib/lib/Mojo/UserAgent.pm
Criterion Covered Total %
statement 215 222 96.8
branch 86 102 84.3
condition 52 69 75.3
subroutine 55 56 98.2
pod 6 6 100.0
total 414 455 90.9


line stmt bran cond sub pod time code
1             package Mojo::UserAgent;
2 54     54   8734 use Mojo::Base 'Mojo::EventEmitter';
  54         167  
  54         359  
3              
4             # "Fry: Since when is the Internet about robbing people of their privacy?
5             # Bender: August 6, 1991."
6 54     54   8121 use Mojo::IOLoop;
  54         154  
  54         346  
7 54     54   314 use Mojo::Promise;
  54         123  
  54         400  
8 54     54   344 use Mojo::Util qw(monkey_patch term_escape);
  54         151  
  54         3267  
9 54     54   27033 use Mojo::UserAgent::CookieJar;
  54         201  
  54         452  
10 54     54   24220 use Mojo::UserAgent::Proxy;
  54         194  
  54         474  
11 54     54   25267 use Mojo::UserAgent::Server;
  54         229  
  54         599  
12 54     54   29293 use Mojo::UserAgent::Transactor;
  54         221  
  54         550  
13 54     54   412 use Scalar::Util qw(weaken);
  54         155  
  54         3281  
14              
15 54   50 54   389 use constant DEBUG => $ENV{MOJO_CLIENT_DEBUG} || 0;
  54         129  
  54         261402  
16              
17             has ca => sub { $ENV{MOJO_CA_FILE} };
18             has cert => sub { $ENV{MOJO_CERT_FILE} };
19             has connect_timeout => sub { $ENV{MOJO_CONNECT_TIMEOUT} || 10 };
20             has cookie_jar => sub { Mojo::UserAgent::CookieJar->new };
21             has inactivity_timeout => sub { $ENV{MOJO_INACTIVITY_TIMEOUT} // 40 };
22             has insecure => sub { $ENV{MOJO_INSECURE} };
23             has 'max_response_size';
24             has ioloop => sub { Mojo::IOLoop->new };
25             has key => sub { $ENV{MOJO_KEY_FILE} };
26             has max_connections => 5;
27             has max_redirects => sub { $ENV{MOJO_MAX_REDIRECTS} || 0 };
28             has proxy => sub { Mojo::UserAgent::Proxy->new };
29             has request_timeout => sub { $ENV{MOJO_REQUEST_TIMEOUT} // 0 };
30             has server => sub { Mojo::UserAgent::Server->new(ioloop => shift->ioloop) };
31             has [qw(socket_options tls_options)] => sub { {} };
32             has transactor => sub { Mojo::UserAgent::Transactor->new };
33              
34             # Common HTTP methods
35             for my $name (qw(DELETE GET HEAD OPTIONS PATCH POST PUT)) {
36             monkey_patch __PACKAGE__, lc $name, sub {
37 93 100   93   20078 my ($self, $cb) = (shift, ref $_[-1] eq 'CODE' ? pop : undef);
        93      
        93      
        93      
        93      
        93      
        93      
38 93         361 return $self->start($self->build_tx($name, @_), $cb);
39             };
40             monkey_patch __PACKAGE__, lc($name) . '_p', sub {
41 18     18   84 my $self = shift;
        18      
        18      
        18      
        18      
        18      
        18      
42 18         65 return $self->start_p($self->build_tx($name, @_));
43             };
44             }
45              
46 63 50   63   55346 sub DESTROY { shift->_cleanup unless ${^GLOBAL_PHASE} eq 'DESTRUCT' }
47              
48 876     876 1 3990 sub build_tx { shift->transactor->tx(@_) }
49 70     70 1 245 sub build_websocket_tx { shift->transactor->websocket(@_) }
50              
51             sub start {
52 944     944 1 2479 my ($self, $tx, $cb) = @_;
53              
54             # Fork-safety
55 944 100 100     5559 $self->_cleanup->server->restart if $self->{pid} && $self->{pid} ne $$;
56 944   66     2846 $self->{pid} //= $$;
57              
58             # Non-blocking
59 944 100       2302 if ($cb) {
60 129         218 warn "-- Non-blocking request (@{[_url($tx)]})\n" if DEBUG;
61 129         753 return $self->_start(Mojo::IOLoop->singleton, $tx, $cb);
62             }
63              
64             # Blocking
65 815         1142 warn "-- Blocking request (@{[_url($tx)]})\n" if DEBUG;
66 815     815   2395 $self->_start($self->ioloop, $tx => sub { shift->ioloop->stop; $tx = shift });
  815         2634  
  815         3782  
67 815         2389 $self->ioloop->start;
68              
69 815         5623 return $tx;
70             }
71              
72             sub start_p {
73 44     44 1 137 my ($self, $tx) = @_;
74 44         201 my $promise = Mojo::Promise->new;
75 44     44   292 $self->start($tx => sub { shift->transactor->promisify($promise, shift) });
  44         186  
76 44         418 return $promise;
77             }
78              
79             sub websocket {
80 25     25 1 47219 my ($self, $cb) = (shift, pop);
81 25         104 $self->start($self->build_websocket_tx(@_), $cb);
82             }
83              
84             sub websocket_p {
85 3     3 1 3012 my $self = shift;
86 3         10 return $self->start_p($self->build_websocket_tx(@_));
87             }
88              
89             sub _cleanup {
90 66     66   184 my $self = shift;
91 66         177 delete $self->{pid};
92 66   100     140 $self->_finish($_, 1) for keys %{$self->{connections} // {}};
  66         601  
93 66         1024 return $self;
94             }
95              
96             sub _connect {
97 181     181   574 my ($self, $loop, $tx, $handle) = @_;
98              
99 181         590 my $t = $self->transactor;
100 181 50       1050 my ($proto, $host, $port) = $handle ? $t->endpoint($tx) : $t->peer($tx);
101              
102 181         1112 my %options = (timeout => $self->connect_timeout);
103 181 50       764 if ($proto eq 'http+unix') { $options{path} = $host }
  0         0  
104 181         778 else { @options{qw(address port)} = ($host, $port) }
105 181         742 $options{socket_options} = $self->socket_options;
106 181 50       626 $options{handle} = $handle if $handle;
107              
108             # SOCKS
109 181 100       793 if ($proto eq 'socks') {
110 1         6 @options{qw(socks_address socks_port)} = @options{qw(address port)};
111 1         4 ($proto, @options{qw(address port)}) = $t->endpoint($tx);
112 1         9 my $userinfo = $tx->req->via_proxy(0)->proxy->userinfo;
113 1 50       15 @options{qw(socks_user socks_pass)} = split /:/, $userinfo if $userinfo;
114             }
115              
116             # TLS
117 181 100       864 if ($options{tls} = $proto eq 'https') {
118 2         6 map { $options{"tls_$_"} = $self->$_ } qw(ca cert key);
  6         23  
119 2         9 $options{tls_options} = $self->tls_options;
120 2 50       8 $options{tls_options}{SSL_verify_mode} = 0x00 if $self->insecure;
121             }
122              
123 181         846 weaken $self;
124 181         337 my $id;
125             return $id = $loop->client(
126             %options => sub {
127 179     179   542 my ($loop, $err, $stream) = @_;
128              
129             # Connection error
130 179 50       659 return unless $self;
131 179 100       557 return $self->_error($id, $err) if $err;
132              
133             # Connection established
134 176         1250 $stream->on(timeout => sub { $self->_error($id, 'Inactivity timeout') });
  3         39  
135 176 100       1053 $stream->on(close => sub { $self && $self->_finish($id, 1) });
  160         1058  
136 176 0       965 $stream->on(error => sub { $self && $self->_error($id, pop) });
  0         0  
137 176         1052 $stream->on(read => sub { $self->_read($id, pop) });
  1090         4827  
138 176         737 $self->_process($id);
139             }
140 181         2118 );
141             }
142              
143             sub _connect_proxy {
144 186     186   571 my ($self, $loop, $old, $cb) = @_;
145              
146             # Start CONNECT request
147 186 100       665 return undef unless my $new = $self->transactor->proxy_connect($old);
148 2         5 my $id;
149             return $id = $self->_start(
150             ($loop, $new) => sub {
151 2     2   6 my ($self, $tx) = @_;
152              
153             # Real transaction
154 2         10 $old->previous($tx)->req->via_proxy(0);
155 2         11 my $c = $self->{connections}{$id} = {cb => $cb, ioloop => $loop, tx => $old};
156              
157             # CONNECT failed
158 2 50 66     8 return $self->_error($id, 'Proxy connection failed') if $tx->error || !$tx->res->is_success || !$tx->keep_alive;
      66        
159              
160             # Start real transaction without TLS upgrade
161 1 50       5 return $self->_process($id) unless $tx->req->url->protocol eq 'https';
162              
163             # TLS upgrade before starting the real transaction
164 0         0 my $handle = $loop->stream($id)->steal_handle;
165 0         0 $self->_remove($id);
166 0         0 $id = $self->_connect($loop, $old, $handle);
167 0         0 $self->{connections}{$id} = $c;
168             }
169 2         21 );
170             }
171              
172             sub _connection {
173 957     957   2653 my ($self, $loop, $tx, $cb) = @_;
174              
175             # Reuse connection
176 957         3037 my ($proto, $host, $port) = $self->transactor->endpoint($tx);
177 957         2094 my $id;
178 957 100       4675 if ($id = $self->_dequeue($loop, "$proto:$host:$port", 1)) {
179 771         1285 warn "-- Reusing connection $id ($proto://$host:$port)\n" if DEBUG;
180 771         1504 @{$self->{connections}{$id}}{qw(cb tx)} = ($cb, $tx);
  771         2991  
181 771 50       6393 $tx->kept_alive(1) unless $tx->connection;
182 771         2678 $self->_process($id);
183 771         3432 return $id;
184             }
185              
186             # CONNECT request to proxy required
187 186 100       903 if (my $id = $self->_connect_proxy($loop, $tx, $cb)) { return $id }
  2         8  
188              
189             # New connection
190 3     3   15 $tx->res->error({message => "Unsupported protocol: $proto"}) and return $loop->next_tick(sub { $self->$cb($tx) })
191 184 100 50     886 unless $proto eq 'http' || $proto eq 'https' || $proto eq 'http+unix';
      100        
      66        
192 181         765 $id = $self->_connect($loop, $tx);
193 181         501 warn "-- Connect $id ($proto://$host:$port)\n" if DEBUG;
194 181         1069 $self->{connections}{$id} = {cb => $cb, ioloop => $loop, tx => $tx};
195              
196 181         886 return $id;
197             }
198              
199             sub _dequeue {
200 1124     1124   2648 my ($self, $loop, $name, $test) = @_;
201              
202 1124   100     4592 my $old = $self->{queue}{$loop} //= [];
203 1124         2082 my ($found, @new);
204 1124         2580 for my $queued (@$old) {
205 887 100 50     3250 push @new, $queued and next if $found || !grep { $_ eq $name } @$queued;
  1726   100     5662  
206              
207             # Search for id/name and sort out corrupted connections if necessary
208 832 100       3045 next unless my $stream = $loop->stream($queued->[1]);
209 830 50 66     4195 $test && $stream->is_readable ? $stream->close : ($found = $queued->[1]);
210             }
211 1124         4090 @$old = @new;
212              
213 1124         3964 return $found;
214             }
215              
216             sub _error {
217 9     9   40 my ($self, $id, $err) = @_;
218 9         49 my $tx = $self->{connections}{$id}{tx};
219 9 100       90 $tx->res->error({message => $err}) if $tx;
220 9         70 $self->_finish($id, 1);
221             }
222              
223             sub _finish {
224 1222     1222   3042 my ($self, $id, $close) = @_;
225              
226             # Remove request timeout and finish transaction
227 1222 100       4143 return undef unless my $c = $self->{connections}{$id};
228 1077 100       2960 $c->{ioloop}->remove(delete $c->{timeout}) if $c->{timeout};
229 1077 100       3066 return $self->_reuse($id, $close) unless my $old = $c->{tx};
230              
231             # Premature connection close
232 1016         2963 my $res = $old->closed->res->finish;
233 1016 100 100     3353 $res->error({message => 'Premature connection close'}) if $close && !$res->code && !$res->error;
      100        
234              
235             # Always remove connection for WebSockets
236 1016 100       2907 return $self->_remove($id) if $old->is_websocket;
237 954         3383 $self->cookie_jar->collect($old);
238              
239             # Upgrade connection to WebSocket
240 954 100       3263 if (my $new = $self->transactor->upgrade($old)) {
241 62         259 weaken $self;
242 62     343   444 $new->on(resume => sub { $self->_write($id) });
  343         1035  
243 62         365 $c->{cb}($self, $c->{tx} = $new);
244 62         241 return $new->client_read($old->res->content->leftovers);
245             }
246              
247             # CONNECT requests always have a follow-up request
248 892 100       2518 $self->_reuse($id, $close) unless uc $old->req->method eq 'CONNECT';
249 892 100       4349 $res->error({message => $res->message, code => $res->code}) if $res->is_error;
250 892 100       3354 $c->{cb}($self, $old) unless $self->_redirect($c, $old);
251             }
252              
253             sub _process {
254 948     948   2410 my ($self, $id) = @_;
255              
256 948         2110 my $c = $self->{connections}{$id};
257 948         3413 my $stream = $c->{ioloop}->stream($id)->timeout($self->inactivity_timeout);
258 948         3783 my $tx = $c->{tx}->connection($id);
259 948         3321 my $handle = $stream->handle;
260 948 50       7940 unless ($handle->isa('IO::Socket::UNIX')) {
261 948         4280 $tx->local_address($handle->sockhost)->local_port($handle->sockport);
262 948         4306 $tx->remote_address($handle->peerhost)->remote_port($handle->peerport);
263             }
264              
265 948         4029 weaken $self;
266 948     10   6520 $tx->on(resume => sub { $self->_write($id) });
  10         38  
267 948         3400 $self->_write($id);
268             }
269              
270             sub _read {
271 1090     1090   3470 my ($self, $id, $chunk) = @_;
272              
273             # Corrupted connection
274 1090 50       4164 return $self->_remove($id) unless my $tx = $self->{connections}{$id}{tx};
275 1090         1649 warn term_escape "-- Client <<< Server (@{[_url($tx)]})\n$chunk\n" if DEBUG;
276 1090         4314 $tx->client_read($chunk);
277 1090 100       3558 $self->_finish($id) if $tx->is_finished;
278             }
279              
280             sub _redirect {
281 892     892   2125 my ($self, $c, $old) = @_;
282 892 100       2570 return undef unless my $new = $self->transactor->redirect($old);
283 30 100       67 return undef unless @{$old->redirects} < $self->max_redirects;
  30         103  
284 11         58 return $self->_start($c->{ioloop}, $new, delete $c->{cb});
285             }
286              
287             sub _remove {
288 167     167   555 my ($self, $id) = @_;
289 167         501 my $c = delete $self->{connections}{$id};
290 167 50       575 return unless $c->{ioloop};
291 167         701 $self->_dequeue($c->{ioloop}, $id);
292 167         1816 $c->{ioloop}->remove($id);
293             }
294              
295             sub _reuse {
296 951     951   2191 my ($self, $id, $close) = @_;
297              
298             # Connection close
299 951         2110 my $c = $self->{connections}{$id};
300 951         1926 my $tx = delete $c->{tx};
301 951         2791 my $max = $self->max_connections;
302 951 100 66     7602 return $self->_remove($id) if $close || !$tx || !$max || !$tx->keep_alive || $tx->error;
      66        
      66        
      100        
303              
304             # Keep connection alive
305 849   50     4269 my $queue = $self->{queue}{$c->{ioloop}} //= [];
306 849   100     2831 $self->_remove(shift(@$queue)->[1]) while @$queue && @$queue >= $max;
307 849         2526 push @$queue, [join(':', $self->transactor->endpoint($tx)), $id];
308             }
309              
310             sub _start {
311 957     957   2411 my ($self, $loop, $tx, $cb) = @_;
312              
313             # Application server
314 957         3796 $self->emit(prepare => $tx);
315 957         2501 my $url = $tx->req->url;
316 957 100 66     3690 if (!$url->is_abs && (my $server = $self->server)) {
317 897 100       2687 my $base = $loop == $self->ioloop ? $server->url : $server->nb_url;
318 897         2857 $url->scheme($base->scheme)->host($base->host)->port($base->port);
319             }
320              
321 957         4048 $_->prepare($tx) for $self->proxy, $self->cookie_jar;
322 957         3116 my $max = $self->max_response_size;
323 957 100       2613 $tx->res->max_message_size($max) if defined $max;
324 957         3723 $self->emit(start => $tx);
325              
326             # Allow test servers sharing the same event loop to clean up connections
327 957 100 33 914   3718 !$loop->next_tick(sub { }) and $loop->one_tick unless $loop->is_running;
328 957 100       7391 return undef unless my $id = $self->_connection($loop, $tx, $cb);
329              
330 954 100       3323 if (my $t = $self->request_timeout) {
331 20         73 weaken $self;
332 20   33 2   159 $self->{connections}{$id}{timeout} ||= $loop->timer($t => sub { $self->_error($id, 'Request timeout') });
  2         34  
333             }
334              
335 954         2496 return $id;
336             }
337              
338 0     0   0 sub _url { shift->req->url->to_abs }
339              
340             sub _write {
341 2481     2481   5368 my ($self, $id) = @_;
342              
343             # Protect from resume event recursion
344 2481         5455 my $c = $self->{connections}{$id};
345 2481 100 100     12387 return if !(my $tx = $c->{tx}) || $c->{writing};
346 2459         5766 local $c->{writing} = 1;
347 2459         7830 my $chunk = $tx->client_write;
348 2459         4003 warn term_escape "-- Client >>> Server (@{[_url($tx)]})\n$chunk\n" if DEBUG;
349 2459 100       7711 return unless length $chunk;
350              
351 1229         4177 weaken $self;
352 1229 100   1181   4750 $c->{ioloop}->stream($id)->write($chunk => sub { $self && $self->_write($id) });
  1181         4920  
353             }
354              
355             1;
356              
357             =encoding utf8
358              
359             =head1 NAME
360              
361             Mojo::UserAgent - Non-blocking I/O HTTP and WebSocket user agent
362              
363             =head1 SYNOPSIS
364              
365             use Mojo::UserAgent;
366              
367             # Fine grained response handling (dies on connection errors)
368             my $ua = Mojo::UserAgent->new;
369             my $res = $ua->get('docs.mojolicious.org')->result;
370             if ($res->is_success) { say $res->body }
371             elsif ($res->is_error) { say $res->message }
372             elsif ($res->code == 301) { say $res->headers->location }
373             else { say 'Whatever...' }
374              
375             # Say hello to the Unicode snowman and include an Accept header
376             say $ua->get('www.☃.net?hello=there' => {Accept => '*/*'})->result->body;
377              
378             # Extract data from HTML and XML resources with CSS selectors
379             say $ua->get('www.perl.org')->result->dom->at('title')->text;
380              
381             # Scrape the latest headlines from a news site
382             say $ua->get('blogs.perl.org')->result->dom->find('h2 > a')->map('text')->join("\n");
383              
384             # IPv6 PUT request with Content-Type header and content
385             my $tx = $ua->put('[::1]:3000' => {'Content-Type' => 'text/plain'} => 'Hi!');
386              
387             # Quick JSON API request with Basic authentication
388             my $url = Mojo::URL->new('https://example.com/test.json')->userinfo('sri:☃');
389             my $value = $ua->get($url)->result->json;
390              
391             # JSON POST (application/json) with TLS certificate authentication
392             my $tx = $ua->cert('tls.crt')->key('tls.key')->post('https://example.com' => json => {top => 'secret'});
393              
394             # Form POST (application/x-www-form-urlencoded)
395             my $tx = $ua->post('https://metacpan.org/search' => form => {q => 'mojo'});
396              
397             # Search DuckDuckGo anonymously through Tor
398             $ua->proxy->http('socks://127.0.0.1:9050');
399             say $ua->get('api.3g2upl4pq6kufc4m.onion/?q=mojolicious&format=json')->result->json('/Abstract');
400              
401             # GET request via UNIX domain socket "/tmp/myapp.sock" (percent encoded slash)
402             say $ua->get('http+unix://%2Ftmp%2Fmyapp.sock/test')->result->body;
403              
404             # Follow redirects to download Mojolicious from GitHub
405             $ua->max_redirects(5)
406             ->get('https://www.github.com/mojolicious/mojo/tarball/main')
407             ->result->save_to('/home/sri/mojo.tar.gz');
408              
409             # Non-blocking request
410             $ua->get('mojolicious.org' => sub ($ua, $tx) { say $tx->result->dom->at('title')->text });
411             Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
412              
413             # Concurrent non-blocking requests (synchronized with promises)
414             my $mojo_promise = $ua->get_p('mojolicious.org');
415             my $cpan_promise = $ua->get_p('cpan.org');
416             Mojo::Promise->all($mojo_promise, $cpan_promise)->then(sub ($mojo, $cpan) {
417             say $mojo->[0]->result->dom->at('title')->text;
418             say $cpan->[0]->result->dom->at('title')->text;
419             })->wait;
420              
421             # WebSocket connection sending and receiving JSON via UNIX domain socket
422             $ua->websocket('ws+unix://%2Ftmp%2Fmyapp.sock/echo.json' => sub ($ua, $tx) {
423             say 'WebSocket handshake failed!' and return unless $tx->is_websocket;
424             $tx->on(json => sub ($tx, $hash) {
425             say "WebSocket message via JSON: $hash->{msg}";
426             $tx->finish;
427             });
428             $tx->send({json => {msg => 'Hello World!'}});
429             });
430             Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
431              
432             =head1 DESCRIPTION
433              
434             L is a full featured non-blocking I/O HTTP and WebSocket user agent, with IPv6, TLS, SNI, IDNA,
435             HTTP/SOCKS5 proxy, UNIX domain socket, Comet (long polling), Promises/A+, keep-alive, connection pooling, timeout,
436             cookie, multipart, gzip compression and multiple event loop support.
437              
438             All connections will be reset automatically if a new process has been forked, this allows multiple processes to share
439             the same L object safely.
440              
441             For better scalability (epoll, kqueue) and to provide non-blocking name resolution, SOCKS5 as well as TLS support, the
442             optional modules L (4.32+), L (0.15+), L (0.64+) and L
443             (2.009+) will be used automatically if possible. Individual features can also be disabled with the C,
444             C and C environment variables.
445              
446             See L for more.
447              
448             =head1 EVENTS
449              
450             L inherits all events from L and can emit the following new ones.
451              
452             =head2 prepare
453              
454             $ua->on(prepare => sub ($ua, $tx) {...});
455              
456             Emitted whenever a new transaction is being prepared, before relative URLs are rewritten and cookies added. This
457             includes automatically prepared proxy C requests and followed redirects.
458              
459             $ua->on(prepare => sub ($ua, $tx) {
460             $tx->req->url(Mojo::URL->new('/mock-mojolicious')) if $tx->req->url->host eq 'mojolicious.org';
461             });
462              
463             =head2 start
464              
465             $ua->on(start => sub ($ua, $tx) {...});
466              
467             Emitted whenever a new transaction is about to start. This includes automatically prepared proxy C requests
468             and followed redirects.
469              
470             $ua->on(start => sub ($ua, $tx) {
471             $tx->req->headers->header('X-Bender' => 'Bite my shiny metal ass!');
472             });
473              
474             =head1 ATTRIBUTES
475              
476             L implements the following attributes.
477              
478             =head2 ca
479              
480             my $ca = $ua->ca;
481             $ua = $ua->ca('/etc/tls/ca.crt');
482              
483             Path to TLS certificate authority file used to verify the peer certificate, defaults to the value of the
484             C environment variable.
485              
486             # Show certificate authorities for debugging
487             IO::Socket::SSL::set_defaults(SSL_verify_callback => sub { say "Authority: $_[2]" and return $_[0] });
488              
489             =head2 cert
490              
491             my $cert = $ua->cert;
492             $ua = $ua->cert('/etc/tls/client.crt');
493              
494             Path to TLS certificate file, defaults to the value of the C environment variable.
495              
496             =head2 connect_timeout
497              
498             my $timeout = $ua->connect_timeout;
499             $ua = $ua->connect_timeout(5);
500              
501             Maximum amount of time in seconds establishing a connection may take before getting canceled, defaults to the value of
502             the C environment variable or C<10>.
503              
504             =head2 cookie_jar
505              
506             my $cookie_jar = $ua->cookie_jar;
507             $ua = $ua->cookie_jar(Mojo::UserAgent::CookieJar->new);
508              
509             Cookie jar to use for requests performed by this user agent, defaults to a L object.
510              
511             # Ignore all cookies
512             $ua->cookie_jar->ignore(sub { 1 });
513              
514             # Ignore cookies for public suffixes
515             my $ps = IO::Socket::SSL::PublicSuffix->default;
516             $ua->cookie_jar->ignore(sub ($cookie) {
517             return undef unless my $domain = $cookie->domain;
518             return ($ps->public_suffix($domain))[0] eq '';
519             });
520              
521             # Add custom cookie to the jar
522             $ua->cookie_jar->add(
523             Mojo::Cookie::Response->new(
524             name => 'foo',
525             value => 'bar',
526             domain => 'docs.mojolicious.org',
527             path => '/Mojolicious'
528             )
529             );
530              
531             =head2 inactivity_timeout
532              
533             my $timeout = $ua->inactivity_timeout;
534             $ua = $ua->inactivity_timeout(15);
535              
536             Maximum amount of time in seconds a connection can be inactive before getting closed, defaults to the value of the
537             C environment variable or C<40>. Setting the value to C<0> will allow connections to be
538             inactive indefinitely.
539              
540             =head2 insecure
541              
542             my $bool = $ua->insecure;
543             $ua = $ua->insecure($bool);
544              
545             Do not require a valid TLS certificate to access HTTPS/WSS sites, defaults to the value of the C
546             environment variable.
547              
548             # Disable TLS certificate verification for testing
549             say $ua->insecure(1)->get('https://127.0.0.1:3000')->result->code;
550              
551             =head2 ioloop
552              
553             my $loop = $ua->ioloop;
554             $ua = $ua->ioloop(Mojo::IOLoop->new);
555              
556             Event loop object to use for blocking I/O operations, defaults to a L object.
557              
558             =head2 key
559              
560             my $key = $ua->key;
561             $ua = $ua->key('/etc/tls/client.crt');
562              
563             Path to TLS key file, defaults to the value of the C environment variable.
564              
565             =head2 max_connections
566              
567             my $max = $ua->max_connections;
568             $ua = $ua->max_connections(5);
569              
570             Maximum number of keep-alive connections that the user agent will retain before it starts closing the oldest ones,
571             defaults to C<5>. Setting the value to C<0> will prevent any connections from being kept alive.
572              
573             =head2 max_redirects
574              
575             my $max = $ua->max_redirects;
576             $ua = $ua->max_redirects(3);
577              
578             Maximum number of redirects the user agent will follow before it fails, defaults to the value of the
579             C environment variable or C<0>.
580              
581             =head2 max_response_size
582              
583             my $max = $ua->max_response_size;
584             $ua = $ua->max_response_size(16777216);
585              
586             Maximum response size in bytes, defaults to the value of L. Setting the
587             value to C<0> will allow responses of indefinite size. Note that increasing this value can also drastically increase
588             memory usage, should you for example attempt to parse an excessively large response body with the methods
589             L or L.
590              
591             =head2 proxy
592              
593             my $proxy = $ua->proxy;
594             $ua = $ua->proxy(Mojo::UserAgent::Proxy->new);
595              
596             Proxy manager, defaults to a L object.
597              
598             # Detect proxy servers from environment
599             $ua->proxy->detect;
600              
601             # Manually configure HTTP proxy (using CONNECT for HTTPS/WebSockets)
602             $ua->proxy->http('http://127.0.0.1:8080')->https('http://127.0.0.1:8080');
603              
604             # Manually configure Tor (SOCKS5)
605             $ua->proxy->http('socks://127.0.0.1:9050')->https('socks://127.0.0.1:9050');
606              
607             # Manually configure UNIX domain socket (using CONNECT for HTTPS/WebSockets)
608             $ua->proxy->http('http+unix://%2Ftmp%2Fproxy.sock') ->https('http+unix://%2Ftmp%2Fproxy.sock');
609              
610             =head2 request_timeout
611              
612             my $timeout = $ua->request_timeout;
613             $ua = $ua->request_timeout(5);
614              
615             Maximum amount of time in seconds establishing a connection, sending the request and receiving a whole response may
616             take before getting canceled, defaults to the value of the C environment variable or C<0>.
617             Setting the value to C<0> will allow the user agent to wait indefinitely. The timeout will reset for every followed
618             redirect.
619              
620             # Total limit of 5 seconds, of which 3 seconds may be spent connecting
621             $ua->max_redirects(0)->connect_timeout(3)->request_timeout(5);
622              
623             =head2 server
624              
625             my $server = $ua->server;
626             $ua = $ua->server(Mojo::UserAgent::Server->new);
627              
628             Application server relative URLs will be processed with, defaults to a L object.
629              
630             # Mock web service
631             $ua->server->app(Mojolicious->new);
632             $ua->server->app->routes->get('/time' => sub ($c) {
633             $c->render(json => {now => time});
634             });
635             my $time = $ua->get('/time')->result->json->{now};
636              
637             # Change log level
638             $ua->server->app->log->level('fatal');
639              
640             # Port currently used for processing relative URLs blocking
641             say $ua->server->url->port;
642              
643             # Port currently used for processing relative URLs non-blocking
644             say $ua->server->nb_url->port;
645              
646             =head2 socket_options
647              
648             my $options = $ua->socket_options;
649             $ua = $ua->socket_options({LocalAddr => '127.0.0.1'});
650              
651             Additional options for L when opening new connections.
652              
653             =head2 tls_options
654              
655             my $options = $ua->tls_options;
656             $ua = $ua->tls_options({SSL_cipher_list => 'DEFAULT:!DH@SECLEVEL=1'});
657              
658             Additional options for L when opening new connections.
659              
660             =head2 transactor
661              
662             my $t = $ua->transactor;
663             $ua = $ua->transactor(Mojo::UserAgent::Transactor->new);
664              
665             Transaction builder, defaults to a L object.
666              
667             # Change name of user agent
668             $ua->transactor->name('MyUA 1.0');
669              
670             # Disable compression
671             $ua->transactor->compressed(0);
672              
673             =head1 METHODS
674              
675             L inherits all methods from L and implements the following new ones.
676              
677             =head2 build_tx
678              
679             my $tx = $ua->build_tx(GET => 'example.com');
680             my $tx = $ua->build_tx(PUT => 'http://example.com' => {Accept => '*/*'} => 'Content!');
681             my $tx = $ua->build_tx(PUT => 'http://example.com' => {Accept => '*/*'} => form => {a => 'b'});
682             my $tx = $ua->build_tx(PUT => 'http://example.com' => {Accept => '*/*'} => json => {a => 'b'});
683              
684             Generate L object with L.
685              
686             # Request with custom cookie
687             my $tx = $ua->build_tx(GET => 'https://example.com/account');
688             $tx->req->cookies({name => 'user', value => 'sri'});
689             $tx = $ua->start($tx);
690              
691             # Deactivate gzip compression
692             my $tx = $ua->build_tx(GET => 'example.com');
693             $tx->req->headers->remove('Accept-Encoding');
694             $tx = $ua->start($tx);
695              
696             # Interrupt response by raising an error
697             my $tx = $ua->build_tx(GET => 'http://example.com');
698             $tx->res->on(progress => sub ($res) {
699             return unless my $server = $res->headers->server;
700             $res->error({message => 'Oh noes, it is IIS!'}) if $server =~ /IIS/;
701             });
702             $tx = $ua->start($tx);
703              
704             =head2 build_websocket_tx
705              
706             my $tx = $ua->build_websocket_tx('ws://example.com');
707             my $tx = $ua->build_websocket_tx( 'ws://example.com' => {DNT => 1} => ['v1.proto']);
708              
709             Generate L object with L.
710              
711             # Custom WebSocket handshake with cookie
712             my $tx = $ua->build_websocket_tx('wss://example.com/echo');
713             $tx->req->cookies({name => 'user', value => 'sri'});
714             $ua->start($tx => sub ($ua, $tx) {
715             say 'WebSocket handshake failed!' and return unless $tx->is_websocket;
716             $tx->on(message => sub ($tx, $msg) {
717             say "WebSocket message: $msg";
718             $tx->finish;
719             });
720             $tx->send('Hi!');
721             });
722             Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
723              
724             =head2 delete
725              
726             my $tx = $ua->delete('example.com');
727             my $tx = $ua->delete('http://example.com' => {Accept => '*/*'} => 'Content!');
728             my $tx = $ua->delete('http://example.com' => {Accept => '*/*'} => form => {a => 'b'});
729             my $tx = $ua->delete('http://example.com' => {Accept => '*/*'} => json => {a => 'b'});
730              
731             Perform blocking C request and return resulting L object, takes the same arguments as
732             L (except for the C method, which is implied). You can also append a callback
733             to perform requests non-blocking.
734              
735             $ua->delete('http://example.com' => json => {a => 'b'} => sub ($ua, $tx) { say $tx->result->body });
736             Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
737              
738             =head2 delete_p
739              
740             my $promise = $ua->delete_p('http://example.com');
741              
742             Same as L, but performs all requests non-blocking and returns a L object instead of accepting
743             a callback.
744              
745             $ua->delete_p('http://example.com' => json => {a => 'b'})->then(sub ($tx) {
746             say $tx->result->body;
747             })->catch(sub ($err) {
748             warn "Connection error: $err";
749             })->wait;
750              
751             =head2 get
752              
753             my $tx = $ua->get('example.com');
754             my $tx = $ua->get('http://example.com' => {Accept => '*/*'} => 'Content!');
755             my $tx = $ua->get('http://example.com' => {Accept => '*/*'} => form => {a => 'b'});
756             my $tx = $ua->get('http://example.com' => {Accept => '*/*'} => json => {a => 'b'});
757              
758             Perform blocking C request and return resulting L object, takes the same arguments as
759             L (except for the C method, which is implied). You can also append a callback to
760             perform requests non-blocking.
761              
762             $ua->get('http://example.com' => json => {a => 'b'} => sub ($ua, $tx) { say $tx->result->body });
763             Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
764              
765             =head2 get_p
766              
767             my $promise = $ua->get_p('http://example.com');
768              
769             Same as L, but performs all requests non-blocking and returns a L object instead of accepting a
770             callback.
771              
772             $ua->get_p('http://example.com' => json => {a => 'b'})->then(sub ($tx) {
773             say $tx->result->body;
774             })->catch(sub ($err) {
775             warn "Connection error: $err";
776             })->wait;
777              
778             =head2 head
779              
780             my $tx = $ua->head('example.com');
781             my $tx = $ua->head('http://example.com' => {Accept => '*/*'} => 'Content!');
782             my $tx = $ua->head('http://example.com' => {Accept => '*/*'} => form => {a => 'b'});
783             my $tx = $ua->head('http://example.com' => {Accept => '*/*'} => json => {a => 'b'});
784              
785             Perform blocking C request and return resulting L object, takes the same arguments as
786             L (except for the C method, which is implied). You can also append a callback
787             to perform requests non-blocking.
788              
789             $ua->head('http://example.com' => json => {a => 'b'} => sub ($ua, $tx) { say $tx->result->body });
790             Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
791              
792             =head2 head_p
793              
794             my $promise = $ua->head_p('http://example.com');
795              
796             Same as L, but performs all requests non-blocking and returns a L object instead of accepting a
797             callback.
798              
799             $ua->head_p('http://example.com' => json => {a => 'b'})->then(sub ($tx) {
800             say $tx->result->body;
801             })->catch(sub ($err) {
802             warn "Connection error: $err";
803             })->wait;
804              
805             =head2 options
806              
807             my $tx = $ua->options('example.com');
808             my $tx = $ua->options('http://example.com' => {Accept => '*/*'} => 'Content!');
809             my $tx = $ua->options('http://example.com' => {Accept => '*/*'} => form => {a => 'b'});
810             my $tx = $ua->options('http://example.com' => {Accept => '*/*'} => json => {a => 'b'});
811              
812             Perform blocking C request and return resulting L object, takes the same arguments as
813             L (except for the C method, which is implied). You can also append a
814             callback to perform requests non-blocking.
815              
816             $ua->options('http://example.com' => json => {a => 'b'} => sub ($ua, $tx) { say $tx->result->body });
817             Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
818              
819             =head2 options_p
820              
821             my $promise = $ua->options_p('http://example.com');
822              
823             Same as L, but performs all requests non-blocking and returns a L object instead of
824             accepting a callback.
825              
826             $ua->options_p('http://example.com' => json => {a => 'b'})->then(sub ($tx) {
827             say $tx->result->body;
828             })->catch(sub ($err) {
829             warn "Connection error: $err";
830             })->wait;
831              
832             =head2 patch
833              
834             my $tx = $ua->patch('example.com');
835             my $tx = $ua->patch('http://example.com' => {Accept => '*/*'} => 'Content!');
836             my $tx = $ua->patch('http://example.com' => {Accept => '*/*'} => form => {a => 'b'});
837             my $tx = $ua->patch('http://example.com' => {Accept => '*/*'} => json => {a => 'b'});
838              
839             Perform blocking C request and return resulting L object, takes the same arguments as
840             L (except for the C method, which is implied). You can also append a callback
841             to perform requests non-blocking.
842              
843             $ua->patch('http://example.com' => json => {a => 'b'} => sub ($ua, $tx) { say $tx->result->body });
844             Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
845              
846             =head2 patch_p
847              
848             my $promise = $ua->patch_p('http://example.com');
849              
850             Same as L, but performs all requests non-blocking and returns a L object instead of accepting
851             a callback.
852              
853             $ua->patch_p('http://example.com' => json => {a => 'b'})->then(sub ($tx) {
854             say $tx->result->body;
855             })->catch(sub ($err) {
856             warn "Connection error: $err";
857             })->wait;
858              
859             =head2 post
860              
861             my $tx = $ua->post('example.com');
862             my $tx = $ua->post('http://example.com' => {Accept => '*/*'} => 'Content!');
863             my $tx = $ua->post('http://example.com' => {Accept => '*/*'} => form => {a => 'b'});
864             my $tx = $ua->post('http://example.com' => {Accept => '*/*'} => json => {a => 'b'});
865              
866             Perform blocking C request and return resulting L object, takes the same arguments as
867             L (except for the C method, which is implied). You can also append a callback
868             to perform requests non-blocking.
869              
870             $ua->post('http://example.com' => json => {a => 'b'} => sub ($ua, $tx) { say $tx->result->body });
871             Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
872              
873             =head2 post_p
874              
875             my $promise = $ua->post_p('http://example.com');
876              
877             Same as L, but performs all requests non-blocking and returns a L object instead of accepting a
878             callback.
879              
880             $ua->post_p('http://example.com' => json => {a => 'b'})->then(sub ($tx) {
881             say $tx->result->body;
882             })->catch(sub ($err) {
883             warn "Connection error: $err";
884             })->wait;
885              
886             =head2 put
887              
888             my $tx = $ua->put('example.com');
889             my $tx = $ua->put('http://example.com' => {Accept => '*/*'} => 'Content!');
890             my $tx = $ua->put('http://example.com' => {Accept => '*/*'} => form => {a => 'b'});
891             my $tx = $ua->put('http://example.com' => {Accept => '*/*'} => json => {a => 'b'});
892              
893             Perform blocking C request and return resulting L object, takes the same arguments as
894             L (except for the C method, which is implied). You can also append a callback to
895             perform requests non-blocking.
896              
897             $ua->put('http://example.com' => json => {a => 'b'} => sub ($ua, $tx) { say $tx->result->body });
898             Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
899              
900             =head2 put_p
901              
902             my $promise = $ua->put_p('http://example.com');
903              
904             Same as L, but performs all requests non-blocking and returns a L object instead of accepting a
905             callback.
906              
907             $ua->put_p('http://example.com' => json => {a => 'b'})->then(sub ($tx) {
908             say $tx->result->body;
909             })->catch(sub ($err) {
910             warn "Connection error: $err";
911             })->wait;
912              
913             =head2 start
914              
915             my $tx = $ua->start(Mojo::Transaction::HTTP->new);
916              
917             Perform blocking request for a custom L object, which can be prepared manually or with
918             L. You can also append a callback to perform requests non-blocking.
919              
920             my $tx = $ua->build_tx(GET => 'http://example.com');
921             $ua->start($tx => sub ($ua, $tx) { say $tx->result->body });
922             Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
923              
924             =head2 start_p
925              
926             my $promise = $ua->start_p(Mojo::Transaction::HTTP->new);
927              
928             Same as L, but performs all requests non-blocking and returns a L object instead of accepting
929             a callback.
930              
931             my $tx = $ua->build_tx(GET => 'http://example.com');
932             $ua->start_p($tx)->then(sub ($tx) {
933             say $tx->result->body;
934             })->catch(sub ($err) {
935             warn "Connection error: $err";
936             })->wait;
937              
938             =head2 websocket
939              
940             $ua->websocket('ws://example.com' => sub {...});
941             $ua->websocket('ws://example.com' => {DNT => 1} => ['v1.proto'] => sub {...});
942              
943             Open a non-blocking WebSocket connection with transparent handshake, takes the same arguments as
944             L. The callback will receive either a L or
945             L object, depending on if the handshake was successful.
946              
947             $ua->websocket('wss://example.com/echo' => ['v1.proto'] => sub ($ua, $tx) {
948             say 'WebSocket handshake failed!' and return unless $tx->is_websocket;
949             say 'Subprotocol negotiation failed!' and return unless $tx->protocol;
950             $tx->on(finish => sub ($tx, $code, $reason) { say "WebSocket closed with status $code." });
951             $tx->on(message => sub ($tx, $msg) {
952             say "WebSocket message: $msg";
953             $tx->finish;
954             });
955             $tx->send('Hi!');
956             });
957             Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
958              
959             You can activate C compression by setting the C header, this can result
960             in much better performance, but also increases memory usage by up to 300KiB per connection.
961              
962             $ua->websocket('ws://example.com/foo' => {
963             'Sec-WebSocket-Extensions' => 'permessage-deflate'
964             } => sub {...});
965              
966             =head2 websocket_p
967              
968             my $promise = $ua->websocket_p('ws://example.com');
969              
970             Same as L, but returns a L object instead of accepting a callback.
971              
972             $ua->websocket_p('wss://example.com/echo')->then(sub ($tx) {
973             my $promise = Mojo::Promise->new;
974             $tx->on(finish => sub { $promise->resolve });
975             $tx->on(message => sub ($tx, $msg) {
976             say "WebSocket message: $msg";
977             $tx->finish;
978             });
979             $tx->send('Hi!');
980             return $promise;
981             })->catch(sub ($err) {
982             warn "WebSocket error: $err";
983             })->wait;
984              
985             =head1 DEBUGGING
986              
987             You can set the C environment variable to get some advanced diagnostics information printed to
988             C.
989              
990             MOJO_CLIENT_DEBUG=1
991              
992             =head1 SEE ALSO
993              
994             L, L, L.
995              
996             =cut