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 53     53   9006 use Mojo::Base 'Mojo::EventEmitter';
  53         131  
  53         354  
3              
4             # "Fry: Since when is the Internet about robbing people of their privacy?
5             # Bender: August 6, 1991."
6 53     53   7945 use Mojo::IOLoop;
  53         283  
  53         462  
7 53     53   327 use Mojo::Promise;
  53         158  
  53         404  
8 53     53   372 use Mojo::Util qw(monkey_patch term_escape);
  53         161  
  53         3131  
9 53     53   25967 use Mojo::UserAgent::CookieJar;
  53         193  
  53         536  
10 53     53   24003 use Mojo::UserAgent::Proxy;
  53         303  
  53         587  
11 53     53   24436 use Mojo::UserAgent::Server;
  53         221  
  53         515  
12 53     53   28405 use Mojo::UserAgent::Transactor;
  53         579  
  53         481  
13 53     53   409 use Scalar::Util qw(weaken);
  53         169  
  53         3694  
14              
15 53   50 53   382 use constant DEBUG => $ENV{MOJO_CLIENT_DEBUG} || 0;
  53         147  
  53         252618  
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   21296 my ($self, $cb) = (shift, ref $_[-1] eq 'CODE' ? pop : undef);
        93      
        93      
        93      
        93      
        93      
        93      
38 93         397 return $self->start($self->build_tx($name, @_), $cb);
39             };
40             monkey_patch __PACKAGE__, lc($name) . '_p', sub {
41 18     18   80 my $self = shift;
        18      
        18      
        18      
        18      
        18      
        18      
42 18         63 return $self->start_p($self->build_tx($name, @_));
43             };
44             }
45              
46 62 50   62   54155 sub DESTROY { shift->_cleanup unless ${^GLOBAL_PHASE} eq 'DESTRUCT' }
47              
48 864     864 1 3796 sub build_tx { shift->transactor->tx(@_) }
49 70     70 1 276 sub build_websocket_tx { shift->transactor->websocket(@_) }
50              
51             sub start {
52 932     932 1 2598 my ($self, $tx, $cb) = @_;
53              
54             # Fork-safety
55 932 100 100     5908 $self->_cleanup->server->restart if $self->{pid} && $self->{pid} ne $$;
56 932   66     3169 $self->{pid} //= $$;
57              
58             # Non-blocking
59 932 100       2332 if ($cb) {
60 129         220 warn "-- Non-blocking request (@{[_url($tx)]})\n" if DEBUG;
61 129         696 return $self->_start(Mojo::IOLoop->singleton, $tx, $cb);
62             }
63              
64             # Blocking
65 803         1195 warn "-- Blocking request (@{[_url($tx)]})\n" if DEBUG;
66 803     803   2359 $self->_start($self->ioloop, $tx => sub { shift->ioloop->stop; $tx = shift });
  803         2708  
  803         3848  
67 803         2827 $self->ioloop->start;
68              
69 803         5778 return $tx;
70             }
71              
72             sub start_p {
73 44     44 1 144 my ($self, $tx) = @_;
74 44         194 my $promise = Mojo::Promise->new;
75 44     44   704 $self->start($tx => sub { shift->transactor->promisify($promise, shift) });
  44         141  
76 44         488 return $promise;
77             }
78              
79             sub websocket {
80 25     25 1 54133 my ($self, $cb) = (shift, pop);
81 25         91 $self->start($self->build_websocket_tx(@_), $cb);
82             }
83              
84             sub websocket_p {
85 3     3 1 3311 my $self = shift;
86 3         12 return $self->start_p($self->build_websocket_tx(@_));
87             }
88              
89             sub _cleanup {
90 65     65   641 my $self = shift;
91 65         199 delete $self->{pid};
92 65   100     160 $self->_finish($_, 1) for keys %{$self->{connections} // {}};
  65         571  
93 65         938 return $self;
94             }
95              
96             sub _connect {
97 180     180   575 my ($self, $loop, $tx, $handle) = @_;
98              
99 180         555 my $t = $self->transactor;
100 180 50       966 my ($proto, $host, $port) = $handle ? $t->endpoint($tx) : $t->peer($tx);
101              
102 180         1033 my %options = (timeout => $self->connect_timeout);
103 180 50       740 if ($proto eq 'http+unix') { $options{path} = $host }
  0         0  
104 180         760 else { @options{qw(address port)} = ($host, $port) }
105 180         744 $options{socket_options} = $self->socket_options;
106 180 50       704 $options{handle} = $handle if $handle;
107              
108             # SOCKS
109 180 100       739 if ($proto eq 'socks') {
110 1         5 @options{qw(socks_address socks_port)} = @options{qw(address port)};
111 1         4 ($proto, @options{qw(address port)}) = $t->endpoint($tx);
112 1         6 my $userinfo = $tx->req->via_proxy(0)->proxy->userinfo;
113 1 50       6 @options{qw(socks_user socks_pass)} = split /:/, $userinfo if $userinfo;
114             }
115              
116             # TLS
117 180 100       910 if ($options{tls} = $proto eq 'https') {
118 2         6 map { $options{"tls_$_"} = $self->$_ } qw(ca cert key);
  6         22  
119 2         7 $options{tls_options} = $self->tls_options;
120 2 50       10 $options{tls_options}{SSL_verify_mode} = 0x00 if $self->insecure;
121             }
122              
123 180         842 weaken $self;
124 180         351 my $id;
125             return $id = $loop->client(
126             %options => sub {
127 178     178   524 my ($loop, $err, $stream) = @_;
128              
129             # Connection error
130 178 50       635 return unless $self;
131 178 100       582 return $self->_error($id, $err) if $err;
132              
133             # Connection established
134 175         1251 $stream->on(timeout => sub { $self->_error($id, 'Inactivity timeout') });
  3         40  
135 175 100       1029 $stream->on(close => sub { $self && $self->_finish($id, 1) });
  159         1194  
136 175 0       1004 $stream->on(error => sub { $self && $self->_error($id, pop) });
  0         0  
137 175         1053 $stream->on(read => sub { $self->_read($id, pop) });
  1073         4946  
138 175         875 $self->_process($id);
139             }
140 180         1947 );
141             }
142              
143             sub _connect_proxy {
144 185     185   723 my ($self, $loop, $old, $cb) = @_;
145              
146             # Start CONNECT request
147 185 100       603 return undef unless my $new = $self->transactor->proxy_connect($old);
148 2         6 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         13 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       7 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         27 );
170             }
171              
172             sub _connection {
173 945     945   2712 my ($self, $loop, $tx, $cb) = @_;
174              
175             # Reuse connection
176 945         3186 my ($proto, $host, $port) = $self->transactor->endpoint($tx);
177 945         1942 my $id;
178 945 100       4558 if ($id = $self->_dequeue($loop, "$proto:$host:$port", 1)) {
179 760         1240 warn "-- Reusing connection $id ($proto://$host:$port)\n" if DEBUG;
180 760         1625 @{$self->{connections}{$id}}{qw(cb tx)} = ($cb, $tx);
  760         3141  
181 760 50       6385 $tx->kept_alive(1) unless $tx->connection;
182 760         2659 $self->_process($id);
183 760         3522 return $id;
184             }
185              
186             # CONNECT request to proxy required
187 185 100       975 if (my $id = $self->_connect_proxy($loop, $tx, $cb)) { return $id }
  2         9  
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 183 100 50     875 unless $proto eq 'http' || $proto eq 'https' || $proto eq 'http+unix';
      100        
      66        
192 180         793 $id = $self->_connect($loop, $tx);
193 180         511 warn "-- Connect $id ($proto://$host:$port)\n" if DEBUG;
194 180         1082 $self->{connections}{$id} = {cb => $cb, ioloop => $loop, tx => $tx};
195              
196 180         894 return $id;
197             }
198              
199             sub _dequeue {
200 1111     1111   2823 my ($self, $loop, $name, $test) = @_;
201              
202 1111   100     4676 my $old = $self->{queue}{$loop} //= [];
203 1111         2006 my ($found, @new);
204 1111         2643 for my $queued (@$old) {
205 875 100 50     3275 push @new, $queued and next if $found || !grep { $_ eq $name } @$queued;
  1702   100     5821  
206              
207             # Search for id/name and sort out corrupted connections if necessary
208 820 100       3212 next unless my $stream = $loop->stream($queued->[1]);
209 818 50 66     4066 $test && $stream->is_readable ? $stream->close : ($found = $queued->[1]);
210             }
211 1111         3746 @$old = @new;
212              
213 1111         3991 return $found;
214             }
215              
216             sub _error {
217 9     9   48 my ($self, $id, $err) = @_;
218 9         48 my $tx = $self->{connections}{$id}{tx};
219 9 100       93 $tx->res->error({message => $err}) if $tx;
220 9         56 $self->_finish($id, 1);
221             }
222              
223             sub _finish {
224 1208     1208   3195 my ($self, $id, $close) = @_;
225              
226             # Remove request timeout and finish transaction
227 1208 100       4147 return undef unless my $c = $self->{connections}{$id};
228 1064 100       2927 $c->{ioloop}->remove(delete $c->{timeout}) if $c->{timeout};
229 1064 100       2964 return $self->_reuse($id, $close) unless my $old = $c->{tx};
230              
231             # Premature connection close
232 1004         3005 my $res = $old->closed->res->finish;
233 1004 100 100     3404 $res->error({message => 'Premature connection close'}) if $close && !$res->code && !$res->error;
      100        
234              
235             # Always remove connection for WebSockets
236 1004 100       3266 return $self->_remove($id) if $old->is_websocket;
237 942         2992 $self->cookie_jar->collect($old);
238              
239             # Upgrade connection to WebSocket
240 942 100       3204 if (my $new = $self->transactor->upgrade($old)) {
241 62         280 weaken $self;
242 62     340   434 $new->on(resume => sub { $self->_write($id) });
  340         962  
243 62         511 $c->{cb}($self, $c->{tx} = $new);
244 62         268 return $new->client_read($old->res->content->leftovers);
245             }
246              
247             # CONNECT requests always have a follow-up request
248 880 100       2691 $self->_reuse($id, $close) unless uc $old->req->method eq 'CONNECT';
249 880 100       4069 $res->error({message => $res->message, code => $res->code}) if $res->is_error;
250 880 100       3575 $c->{cb}($self, $old) unless $self->_redirect($c, $old);
251             }
252              
253             sub _process {
254 936     936   2437 my ($self, $id) = @_;
255              
256 936         2047 my $c = $self->{connections}{$id};
257 936         3316 my $stream = $c->{ioloop}->stream($id)->timeout($self->inactivity_timeout);
258 936         3968 my $tx = $c->{tx}->connection($id);
259 936         3541 my $handle = $stream->handle;
260 936 50       8167 unless ($handle->isa('IO::Socket::UNIX')) {
261 936         4108 $tx->local_address($handle->sockhost)->local_port($handle->sockport);
262 936         4444 $tx->remote_address($handle->peerhost)->remote_port($handle->peerport);
263             }
264              
265 936         3981 weaken $self;
266 936     10   6497 $tx->on(resume => sub { $self->_write($id) });
  10         48  
267 936         3601 $self->_write($id);
268             }
269              
270             sub _read {
271 1073     1073   3460 my ($self, $id, $chunk) = @_;
272              
273             # Corrupted connection
274 1073 50       4323 return $self->_remove($id) unless my $tx = $self->{connections}{$id}{tx};
275 1073         1558 warn term_escape "-- Client <<< Server (@{[_url($tx)]})\n$chunk\n" if DEBUG;
276 1073         4256 $tx->client_read($chunk);
277 1073 100       3754 $self->_finish($id) if $tx->is_finished;
278             }
279              
280             sub _redirect {
281 880     880   2674 my ($self, $c, $old) = @_;
282 880 100       2263 return undef unless my $new = $self->transactor->redirect($old);
283 30 100       393 return undef unless @{$old->redirects} < $self->max_redirects;
  30         121  
284 11         69 return $self->_start($c->{ioloop}, $new, delete $c->{cb});
285             }
286              
287             sub _remove {
288 166     166   536 my ($self, $id) = @_;
289 166         539 my $c = delete $self->{connections}{$id};
290 166 50       639 return unless $c->{ioloop};
291 166         771 $self->_dequeue($c->{ioloop}, $id);
292 166         830 $c->{ioloop}->remove($id);
293             }
294              
295             sub _reuse {
296 938     938   2315 my ($self, $id, $close) = @_;
297              
298             # Connection close
299 938         2118 my $c = $self->{connections}{$id};
300 938         1978 my $tx = delete $c->{tx};
301 938         2752 my $max = $self->max_connections;
302 938 100 66     7273 return $self->_remove($id) if $close || !$tx || !$max || !$tx->keep_alive || $tx->error;
      66        
      66        
      100        
303              
304             # Keep connection alive
305 837   50     4289 my $queue = $self->{queue}{$c->{ioloop}} //= [];
306 837   100     2915 $self->_remove(shift(@$queue)->[1]) while @$queue && @$queue >= $max;
307 837         2592 push @$queue, [join(':', $self->transactor->endpoint($tx)), $id];
308             }
309              
310             sub _start {
311 945     945   2846 my ($self, $loop, $tx, $cb) = @_;
312              
313             # Application server
314 945         3935 $self->emit(prepare => $tx);
315 945         2541 my $url = $tx->req->url;
316 945 100 66     3949 if (!$url->is_abs && (my $server = $self->server)) {
317 885 100       2383 my $base = $loop == $self->ioloop ? $server->url : $server->nb_url;
318 885         3059 $url->scheme($base->scheme)->host($base->host)->port($base->port);
319             }
320              
321 945         4284 $_->prepare($tx) for $self->proxy, $self->cookie_jar;
322 945         3315 my $max = $self->max_response_size;
323 945 100       2932 $tx->res->max_message_size($max) if defined $max;
324 945         3586 $self->emit(start => $tx);
325              
326             # Allow test servers sharing the same event loop to clean up connections
327 945 100 33 902   3898 !$loop->next_tick(sub { }) and $loop->one_tick unless $loop->is_running;
328 945 100       7234 return undef unless my $id = $self->_connection($loop, $tx, $cb);
329              
330 942 100       3278 if (my $t = $self->request_timeout) {
331 20         68 weaken $self;
332 20   33 2   150 $self->{connections}{$id}{timeout} ||= $loop->timer($t => sub { $self->_error($id, 'Request timeout') });
  2         25  
333             }
334              
335 942         2429 return $id;
336             }
337              
338 0     0   0 sub _url { shift->req->url->to_abs }
339              
340             sub _write {
341 2453     2453   5289 my ($self, $id) = @_;
342              
343             # Protect from resume event recursion
344 2453         5497 my $c = $self->{connections}{$id};
345 2453 100 100     12421 return if !(my $tx = $c->{tx}) || $c->{writing};
346 2431         5763 local $c->{writing} = 1;
347 2431         7679 my $chunk = $tx->client_write;
348 2431         4022 warn term_escape "-- Client >>> Server (@{[_url($tx)]})\n$chunk\n" if DEBUG;
349 2431 100       7716 return unless length $chunk;
350              
351 1217         4373 weaken $self;
352 1217 100   1168   4754 $c->{ioloop}->stream($id)->write($chunk => sub { $self && $self->_write($id) });
  1168         4898  
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