File Coverage

blib/lib/Mojo/UserAgent.pm
Criterion Covered Total %
statement 215 222 96.8
branch 88 102 86.2
condition 52 69 75.3
subroutine 55 56 98.2
pod 6 6 100.0
total 416 455 91.4


line stmt bran cond sub pod time code
1             package Mojo::UserAgent;
2 57     57   12121 use Mojo::Base 'Mojo::EventEmitter';
  57         135  
  57         493  
3              
4             # "Fry: Since when is the Internet about robbing people of their privacy?
5             # Bender: August 6, 1991."
6 57     57   13331 use Mojo::IOLoop;
  57         161  
  57         386  
7 57     57   504 use Mojo::Promise;
  57         238  
  57         537  
8 57     57   321 use Mojo::Util qw(monkey_patch term_escape);
  57         154  
  57         4149  
9 57     57   35495 use Mojo::UserAgent::CookieJar;
  57         432  
  57         486  
10 57     57   35178 use Mojo::UserAgent::Proxy;
  57         239  
  57         505  
11 57     57   34028 use Mojo::UserAgent::Server;
  57         333  
  57         550  
12 57     57   42548 use Mojo::UserAgent::Transactor;
  57         2288  
  57         2078  
13 57     57   1629 use Scalar::Util qw(weaken);
  57         151  
  57         5333  
14              
15 57   50 57   475 use constant DEBUG => $ENV{MOJO_CLIENT_DEBUG} || 0;
  57         144  
  57         359144  
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 106 100   106   27926 my ($self, $cb) = (shift, ref $_[-1] eq 'CODE' ? pop : undef);
        106      
        106      
        106      
        106      
        106      
        106      
38 106         641 return $self->start($self->build_tx($name, @_), $cb);
39             };
40             monkey_patch __PACKAGE__, lc($name) . '_p', sub {
41 18     18   53 my $self = shift;
        18      
        18      
        18      
        18      
        18      
        18      
42 18         78 return $self->start_p($self->build_tx($name, @_));
43             };
44             }
45              
46 77 50   77   106045 sub DESTROY { shift->_cleanup unless ${^GLOBAL_PHASE} eq 'DESTRUCT' }
47              
48 918     918 1 5008 sub build_tx { shift->transactor->tx(@_) }
49 83     83 1 340 sub build_websocket_tx { shift->transactor->websocket(@_) }
50              
51             sub start {
52 1008     1008 1 3192 my ($self, $tx, $cb) = @_;
53              
54             # Fork-safety
55 1008 100 100     16423 $self->_cleanup->server->restart if $self->{pid} && $self->{pid} ne $$;
56 1008   66     4902 $self->{pid} //= $$;
57              
58             # Non-blocking
59 1008 100       3220 if ($cb) {
60 158         260 warn "-- Non-blocking request (@{[_url($tx)]})\n" if DEBUG;
61 158         1050 return $self->_start(Mojo::IOLoop->singleton, $tx, $cb);
62             }
63              
64             # Blocking
65 850         1613 warn "-- Blocking request (@{[_url($tx)]})\n" if DEBUG;
66 850     850   3962 $self->_start($self->ioloop, $tx => sub { shift->ioloop->stop; $tx = shift });
  850         3726  
  850         5142  
67 850         3069 $self->ioloop->start;
68              
69 850         12140 return $tx;
70             }
71              
72             sub start_p {
73 44     44 1 98 my ($self, $tx) = @_;
74 44         205 my $promise = Mojo::Promise->new;
75 44     44   272 $self->start($tx => sub { shift->transactor->promisify($promise, shift) });
  44         135  
76 44         353 return $promise;
77             }
78              
79             sub websocket {
80 25     25 1 76361 my ($self, $cb) = (shift, pop);
81 25         149 $self->start($self->build_websocket_tx(@_), $cb);
82             }
83              
84             sub websocket_p {
85 3     3 1 4052 my $self = shift;
86 3         30 return $self->start_p($self->build_websocket_tx(@_));
87             }
88              
89             sub _cleanup {
90 80     80   205 my $self = shift;
91 80         259 delete $self->{pid};
92 80   100     174 $self->_finish($_, 1) for keys %{$self->{connections} // {}};
  80         786  
93 80         1466 return $self;
94             }
95              
96             sub _connect {
97 222     222   706 my ($self, $loop, $tx, $handle) = @_;
98              
99 222         1251 my $t = $self->transactor;
100 222 50       1226 my ($proto, $host, $port) = $handle ? $t->endpoint($tx) : $t->peer($tx);
101              
102 222         1515 my %options = (timeout => $self->connect_timeout);
103 222 50       979 if ($proto eq 'http+unix') { $options{path} = $host }
  0         0  
104 222         1935 else { @options{qw(address port)} = ($host, $port) }
105 222         873 $options{socket_options} = $self->socket_options;
106 222 50       725 $options{handle} = $handle if $handle;
107              
108             # SOCKS
109 222 100       774 if ($proto eq 'socks') {
110 1         3 @options{qw(socks_address socks_port)} = @options{qw(address port)};
111 1         3 ($proto, @options{qw(address port)}) = $t->endpoint($tx);
112 1         5 my $userinfo = $tx->req->via_proxy(0)->proxy->userinfo;
113 1 50       2 @options{qw(socks_user socks_pass)} = split /:/, $userinfo if $userinfo;
114             }
115              
116             # TLS
117 222 100       1138 if ($options{tls} = $proto eq 'https') {
118 2         4 map { $options{"tls_$_"} = $self->$_ } qw(ca cert key);
  6         16  
119 2         5 $options{tls_options} = $self->tls_options;
120 2 50       6 $options{tls_options}{SSL_verify_mode} = 0x00 if $self->insecure;
121             }
122              
123 222         633 weaken $self;
124 222         425 my $id;
125             return $id = $loop->client(
126             %options => sub {
127 220     220   605 my ($loop, $err, $stream) = @_;
128              
129             # Connection error
130 220 50       786 return unless $self;
131 220 100       755 return $self->_error($id, $err) if $err;
132              
133             # Connection established
134 217         1760 $stream->on(timeout => sub { $self->_error($id, 'Inactivity timeout') });
  3         51  
135 217 100       1233 $stream->on(close => sub { $self && $self->_finish($id, 1) });
  189         1360  
136 217 0       1405 $stream->on(error => sub { $self && $self->_error($id, pop) });
  0         0  
137 217         1030 $stream->on(read => sub { $self->_read($id, pop) });
  1175         7487  
138 217         1013 $self->_process($id);
139             }
140 222         3116 );
141             }
142              
143             sub _connect_proxy {
144 227     227   1123 my ($self, $loop, $old, $cb) = @_;
145              
146             # Start CONNECT request
147 227 100       810 return undef unless my $new = $self->transactor->proxy_connect($old);
148 2         3 my $id;
149             return $id = $self->_start(
150             ($loop, $new) => sub {
151 2     2   7 my ($self, $tx) = @_;
152              
153             # Real transaction
154 2         9 $old->previous($tx)->req->via_proxy(0);
155 2         12 my $c = $self->{connections}{$id} = {cb => $cb, ioloop => $loop, tx => $old};
156              
157             # CONNECT failed
158 2 50 66     9 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       3 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         17 );
170             }
171              
172             sub _connection {
173 1023     1023   3128 my ($self, $loop, $tx, $cb) = @_;
174              
175             # Reuse connection
176 1023         4490 my ($proto, $host, $port) = $self->transactor->endpoint($tx);
177 1023         2365 my $id;
178 1023 100       6551 if ($id = $self->_dequeue($loop, "$proto:$host:$port", 1)) {
179 796         1497 warn "-- Reusing connection $id ($proto://$host:$port)\n" if DEBUG;
180 796         1868 @{$self->{connections}{$id}}{qw(cb tx)} = ($cb, $tx);
  796         4433  
181 796 50       9579 $tx->kept_alive(1) unless $tx->connection;
182 796         7806 $self->_process($id);
183 796         5331 return $id;
184             }
185              
186             # CONNECT request to proxy required
187 227 100       1018 if (my $id = $self->_connect_proxy($loop, $tx, $cb)) { return $id }
  2         7  
188              
189             # New connection
190 3     3   13 $tx->res->error({message => "Unsupported protocol: $proto"}) and return $loop->next_tick(sub { $self->$cb($tx) })
191 225 100 50     1000 unless $proto eq 'http' || $proto eq 'https' || $proto eq 'http+unix';
      100        
      66        
192 222         1071 $id = $self->_connect($loop, $tx);
193 222         526 warn "-- Connect $id ($proto://$host:$port)\n" if DEBUG;
194 222         2077 $self->{connections}{$id} = {cb => $cb, ioloop => $loop, tx => $tx};
195              
196 222         1092 return $id;
197             }
198              
199             sub _dequeue {
200 1219     1219   3595 my ($self, $loop, $name, $test) = @_;
201              
202 1219   100     7467 my $old = $self->{queue}{$loop} //= [];
203 1219         2703 my ($found, @new);
204 1219         3531 for my $queued (@$old) {
205 922 100 50     4618 push @new, $queued and next if $found || !grep { $_ eq $name } @$queued;
  1802   100     6700  
206              
207             # Search for id/name and sort out corrupted connections if necessary
208 867 100       4791 next unless my $stream = $loop->stream($queued->[1]);
209 865 50 66     6419 $test && $stream->is_readable ? $stream->close : ($found = $queued->[1]);
210             }
211 1219         4752 @$old = @new;
212              
213 1219         5095 return $found;
214             }
215              
216             sub _error {
217 9     9   42 my ($self, $id, $err) = @_;
218 9         39 my $tx = $self->{connections}{$id}{tx};
219 9 100       84 $tx->res->error({message => $err}) if $tx;
220 9         46 $self->_finish($id, 1);
221             }
222              
223             sub _finish {
224 1310     1310   4151 my ($self, $id, $close) = @_;
225              
226             # Remove request timeout and finish transaction
227 1310 100       6520 return undef unless my $c = $self->{connections}{$id};
228 1153 100       4368 $c->{ioloop}->remove(delete $c->{timeout}) if $c->{timeout};
229 1153 100       4242 return $self->_reuse($id, $close) unless my $old = $c->{tx};
230              
231             # Premature connection close
232 1082         4279 my $res = $old->closed->res->finish;
233 1082 100 100     4076 $res->error({message => 'Premature connection close'}) if $close && !$res->code && !$res->error;
      100        
234              
235             # Always remove connection for WebSockets
236 1082 100       3707 return $self->_remove($id) if $old->is_websocket;
237 1020         4808 $self->cookie_jar->collect($old);
238              
239             # Upgrade connection to WebSocket
240 1020 100       4907 if (my $new = $self->transactor->upgrade($old)) {
241 74         181 weaken $self;
242 74     362   663 $new->on(resume => sub { $self->_write($id) });
  362         1526  
243 74         525 $c->{cb}($self, $c->{tx} = $new);
244 74         330 return $new->client_read($old->res->content->leftovers);
245             }
246              
247             # CONNECT requests always have a follow-up request
248 946 100       3322 $self->_reuse($id, $close) unless uc $old->req->method eq 'CONNECT';
249 946 100       8572 $res->error({message => $res->message, code => $res->code}) if $res->is_error;
250 946 100       5107 $c->{cb}($self, $old) unless $self->_redirect($c, $old);
251             }
252              
253             sub _process {
254 1014     1014   3204 my ($self, $id) = @_;
255              
256 1014         2862 my $c = $self->{connections}{$id};
257 1014         4646 my $stream = $c->{ioloop}->stream($id)->timeout($self->inactivity_timeout);
258 1014         5230 my $tx = $c->{tx}->connection($id);
259 1014         4385 my $handle = $stream->handle;
260 1014 50       12399 unless ($handle->isa('IO::Socket::UNIX')) {
261 1014         7130 $tx->local_address($handle->sockhost)->local_port($handle->sockport);
262 1014         5602 $tx->remote_address($handle->peerhost)->remote_port($handle->peerport);
263             }
264              
265 1014         3223 weaken $self;
266 1014     10   8622 $tx->on(resume => sub { $self->_write($id) });
  10         54  
267 1014         5329 $self->_write($id);
268             }
269              
270             sub _read {
271 1175     1175   4359 my ($self, $id, $chunk) = @_;
272              
273             # Corrupted connection
274 1175 100       6199 return $self->_remove($id) unless my $tx = $self->{connections}{$id}{tx};
275 1174         2339 warn term_escape "-- Client <<< Server (@{[_url($tx)]})\n$chunk\n" if DEBUG;
276 1174         6436 $tx->client_read($chunk);
277 1174 100       22664 $self->_finish($id) if $tx->is_finished;
278             }
279              
280             sub _redirect {
281 946     946   2679 my ($self, $c, $old) = @_;
282 946 100       3044 return undef unless my $new = $self->transactor->redirect($old);
283 34 100       81 return undef unless @{$old->redirects} < $self->max_redirects;
  34         158  
284 13         91 return $self->_start($c->{ioloop}, $new, delete $c->{cb});
285             }
286              
287             sub _remove {
288 197     197   549 my ($self, $id) = @_;
289 197         572 my $c = delete $self->{connections}{$id};
290 197 100       759 return unless $c->{ioloop};
291 196         1088 $self->_dequeue($c->{ioloop}, $id);
292 196         993 $c->{ioloop}->remove($id);
293             }
294              
295             sub _reuse {
296 1015     1015   2793 my ($self, $id, $close) = @_;
297              
298             # Connection close
299 1015         2855 my $c = $self->{connections}{$id};
300 1015         2527 my $tx = delete $c->{tx};
301 1015         4337 my $max = $self->max_connections;
302 1015 100 66     9827 return $self->_remove($id) if $close || !$tx || !$max || !$tx->keep_alive || $tx->error;
      66        
      66        
      100        
303              
304             # Keep connection alive
305 884   50     5899 my $queue = $self->{queue}{$c->{ioloop}} //= [];
306 884   100     3643 $self->_remove(shift(@$queue)->[1]) while @$queue && @$queue >= $max;
307 884         3686 push @$queue, [join(':', $self->transactor->endpoint($tx)), $id];
308             }
309              
310             sub _start {
311 1023     1023   3258 my ($self, $loop, $tx, $cb) = @_;
312              
313             # Application server
314 1023         5303 $self->emit(prepare => $tx);
315 1023         3412 my $url = $tx->req->url;
316 1023 100 66     5739 if (!$url->is_abs && (my $server = $self->server)) {
317 952 100       3137 my $base = $loop == $self->ioloop ? $server->url : $server->nb_url;
318 952         3827 $url->scheme($base->scheme)->host($base->host)->port($base->port);
319             }
320              
321 1023         6025 $_->prepare($tx) for $self->proxy, $self->cookie_jar;
322 1023         7306 my $max = $self->max_response_size;
323 1023 100       3375 $tx->res->max_message_size($max) if defined $max;
324 1023         4909 $self->emit(start => $tx);
325              
326             # Allow test servers sharing the same event loop to clean up connections
327 1023 100 33 978   26402 !$loop->next_tick(sub { }) and $loop->one_tick unless $loop->is_running;
328 1023 100       10755 return undef unless my $id = $self->_connection($loop, $tx, $cb);
329              
330 1020 100       4554 if (my $t = $self->request_timeout) {
331 20         49 weaken $self;
332 20   33 2   235 $self->{connections}{$id}{timeout} ||= $loop->timer($t => sub { $self->_error($id, 'Request timeout') });
  2         28  
333             }
334              
335 1020         3260 return $id;
336             }
337              
338 0     0   0 sub _url { shift->req->url->to_abs }
339              
340             sub _write {
341 2632     2632   6816 my ($self, $id) = @_;
342              
343             # Protect from resume event recursion
344 2632         7548 my $c = $self->{connections}{$id};
345 2632 100 100     16485 return if !(my $tx = $c->{tx}) || $c->{writing};
346 2610         7490 local $c->{writing} = 1;
347 2610         11451 my $chunk = $tx->client_write;
348 2610         4691 warn term_escape "-- Client >>> Server (@{[_url($tx)]})\n$chunk\n" if DEBUG;
349 2610 100       9605 return unless length $chunk;
350              
351 1296         3176 weaken $self;
352 1296 100   1247   7788 $c->{ioloop}->stream($id)->write($chunk => sub { $self && $self->_write($id) });
  1247         6922  
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