名称

Mojo::UserAgent-非阻塞I/O HTTP和WebSocket用户代理

简介

使用Mojo::UserAgent;#细粒度响应处理(因连接错误而失效)my$ua=Mojo::UserAgent->new;my$res=$ua->get('docs.mojolicious.org')->result;if($res->issuccess){说$res->主体}elsif($res->is_error){说$res->消息}elsif($res->code==301){say$res->headers->location}否则{说“随便…”}#向Unicode雪人问好并包含Accept头说$ua->get('ww。☃.净值?hello=there'=>{Accept=>'*/*'})->result->body;#使用CSS选择器从HTML和XML资源中提取数据说$ua->get('www.perl.org')->result->dom->at('title')->text;#从新闻网站上删除最新的头条新闻比如$ua->get('blogs.perl.org')->result->dom->find('h2>a')->map('text')->join(“\n”);#具有内容类型标头和内容的IPv6 PUT请求我的$tx=$ua->put('[::1]:3000'=>{'Content-Type'=>'text/plain'}=>'Hi!');#具有基本身份验证的快速JSON API请求my$url=Mojo::url->new('https://example.com/test.json')->用户信息('sri:☃');my$value=$ua->get($url)->result->json;#JSON POST(application/JSON)和TLS证书身份验证我的$tx=$ua->cert('tls.crt')->key('tls.key')->post('https://example.com'=>json=>{top=>'secret'});#表单POST(application/x-www-Form-urlencoded)我的$tx=$ua->帖子('https://metapan.org/search网站'=>form=>{q=>'mojo'});#通过Tor匿名搜索DuckDuckGo$ua->proxy->http('袜子://127.0.0.1:9050');说$ua->get('api.3g2upl4pq6kufc4m.inode/?q=mojolicios&format=json')->result->json('/Abstruct');#通过UNIX域套接字“/tmp/myapp.sock”获取请求(百分比编码斜杠)说$ua->get('http+unix://%2Ftmp%2Fmyapp.sock/test')->result->body;#遵循重定向从GitHub下载Mojolicious$ua->max_redirects(5)->获取('https://www.github.com/mojolicious/mojo/tarball/main网站')->结果->保存到('/home/sri/mojo.tar.gz');#非阻塞请求$ua->get('mojolicious.org'=>sub($ua,$tx){say$tx->result->dom->at('title')->text});除非Mojo::IOLoop->is_running,否则Mojo::IOLoop->启动;#并发非阻塞请求(与承诺同步)我的$mojo_promise=$ua->get_p('mojolicious.org');my$cpan_promise=$ua->get_p('span.org');Mojo::Promise->all($Mojo_Promise,$cpan_Promise)->then(sub($moho,$cpan){说$mojo->[0]->result->dom->at('title')->text;说$cpan->[0]->result->dom->at('title')->text;})->等待;#WebSocket连接通过UNIX域套接字发送和接收JSON$ua->websocket('ws+unix://%2Ftmp%2Fmyapp.sock/echo.json'=>sub($ua,$tx){说“WebSocket握手失败!”并返回,除非$tx->is_websocket;$tx->on(json=>sub($tx,$hash){说“WebSocket消息通过JSON:$hash->{msg}”;$tx->完成;});$tx->send({json=>{msg=>'Hello World!'}});});除非Mojo::IOLoop->is_running,否则Mojo::IOLoop->启动;

描述

Mojo::用户代理是一个功能齐全的非阻塞I/O HTTP和WebSocket用户代理,具有IPv6、TLS、SNI、IDNA、HTTP/SOCKS5代理、UNIX域套接字、Comet(长轮询)、Promises/a+、keep-alive、连接池、超时、cookie、多部分、gzip压缩和多事件循环支持。

如果分叉了一个新进程,所有连接都将自动重置,这允许多个进程共享同一个连接Mojo::用户代理物体安全。

为了获得更好的可伸缩性(epoll、kqueue)并提供非阻塞名称解析、SOCKS5以及TLS支持,可选模块电动汽车(4.32+),网络::DNS::本机(0.15+),IO::插槽::插槽(0.64+)和IO::套接字::SSL如果可能,将自动使用(2.009+)。也可以使用禁用单个功能MOJO_NO_NNR公司,MOJO_NO_SOCKS运动鞋MOJO_NO_TLS公司环境变量。

请参见Mojolicious::Guides::Cookbook中的“用户代理”了解更多信息。

活动

Mojo::用户代理从继承所有事件Mojo::EventEmitter并且可以发射出以下新的气体。

准备

$ua->on(prepare=>sub($ua,$tx){…});

在重写相对URL和添加cookie之前,每当准备新事务时都会发出。这包括自动准备的代理连接请求和遵循的重定向。

$ua->on(prepare=>sub($ua,$tx)){$tx->req->url(Mojo::url->new(“/mock-mojolicious”))如果$tx->req->url->host eq“mojolicous.org”;});

开始

$ua->on(start=>sub($ua,$tx){…});

每当新事务即将启动时发出。这包括自动准备的代理连接请求和遵循的重定向。

$ua->打开(开始=>sub($ua,$tx){$tx->req->headers->header(“X-Bender”=>“咬我闪亮的金属屁股!”);});

属性

Mojo::用户代理实现以下属性。

加利福尼亚州

我的$ca=$ua->ca;$ua=$ua->ca('/etc/tls/ca.crt');

用于验证对等证书的TLS证书颁发机构文件的路径,默认为MOJO_CA文件环境变量。

#显示用于调试的证书颁发机构IO::Socket::SSL::set_defaults(SSL_verify_callback=>sub{say“Authority:$_[2]”and return$_[0]});

证书

我的$cert=$ua->cert;$ua=$ua->cert('/etc/tls/client.crt');

TLS证书文件的路径,默认为MOJO_CERT文件环境变量。

连接超时

我的$timeout=$ua->connect_timeout;$ua=$ua->connect_timeout(5);

在取消连接之前建立连接可能需要的最长时间(秒),默认为MOJO_连接_超时环境变量或10.

我的$cookiejar=$ua->cookieJAR;$ua=$ua->cookie_jar(Mojo::UserAgent::CookieJar->new);

Cookie jar用于此用户代理执行的请求,默认为Mojo::UserAgent::CookieJar对象。

#忽略所有Cookie$ua->cookie_jar->ignore(子{1});#忽略公共后缀的cookiemy$ps=IO::Socket::SSL::PublicSuffix->default;$ua->cookie_jar->ignore(sub($cookie)){返回undef,除非我的$domain=$cookie->domain;return($ps->public_suffix($domain))[0]eq“”;});#将自定义cookie添加到jar$ua->cookie_jar->添加(Mojo::Cookie::Response->new(name=>“foo”,值=>“bar”,domain=>“docs.mojolicious.org”,path=>“/Mojolicious”));

不活动超时

my$timeout=$ua->inactivity_timeout;$ua=$ua->inactivity_timeout(15);

连接在关闭之前可以处于非活动状态的最长时间(秒),默认为MOJO_无效_超时环境变量或40。将值设置为0将允许连接无限期处于非活动状态。

不安全的

我的$bool=$ua->不安全;$ua=$ua->不安全($bool);

访问HTTPS/WSS站点不需要有效的TLS证书,默认为MOJO_保险环境变量。

#禁用TLS证书验证以进行测试说$ua->unsecurity(1)->get('https://127.0.0.1:3000')->结果->代码;

奥洛普

我的$loop=$ua->ioloop;$ua=$ua->ioloop(Mojo::ioloop->new);

用于阻塞I/O操作的事件循环对象,默认为Mojo::IOLoop对象。

钥匙

我的$key=$ua->key;$ua=$ua->键('/etc/tls/client.crt');

TLS密钥文件的路径,默认为MOJO_KEY_FILE文件环境变量。

最大连接数

我的$max=$ua->max_connections;$ua=$ua->max_connections(5);

用户代理在开始关闭最旧的连接之前将保留的最大保持活动连接数,默认为5。将值设置为0将阻止任何连接保持活动状态。

最大导向数

我的$max=$ua->max_redirects;$ua=$ua->max_redirects(3);

用户代理在失败之前将遵循的最大重定向数,默认为MOJO_MAX_编辑环境变量或0.

最大响应大小

我的$max=$ua->max_response_size;$ua=$ua->最大响应大小(16777216);

最大响应大小(字节),默认值为Mojo::message::Response中的“max_message_size”。将值设置为0将允许不确定大小的响应。请注意,如果您尝试使用方法解析过大的响应体,那么增加该值也会显著增加内存使用量Mojo::Message中的“dom”Mojo中的“json”::消息.

代理

我的$proxy=$ua->代理;$ua=$ua->proxy(Mojo::UserAgent::proxy->new);

代理管理器,默认为Mojo::UserAgent::代理对象。

#从环境中检测代理服务器$ua->proxy->detect;#手动配置HTTP代理(对HTTPS/WebSockets使用CONNECT)$ua->proxy->http('http://127.0.0.1:8080网址')->https('http://127.0.0.1:8080网址');#手动配置Tor(SOCKS5)$ua->proxy->http('袜子://127.0.0.1:9050')->https('袜子://127.0.0.1:9050');#手动配置UNIX域套接字(使用CONNECT for HTTPS/WebSockets)$ua->proxy->http('http+unix://%2Ftmp%2proxy.sock')->https('http+unix://%2Ftmp%2proxy.sock');

请求超时

我的$timeout=$ua->request_timeout;$ua=$ua->request_timeout(5);

在取消连接之前,建立连接、发送请求和接收整个响应所需的最长时间(以秒为单位)默认为MOJO_请求_超时环境变量或0。将值设置为0将允许用户代理无限期等待。每个后续重定向都会重置超时。

#总限制为5秒,其中3秒可能用于连接$ua->max_redirects(0)->连接超时(3)->请求超时(5);

服务器

我的$server=$ua->服务器;$ua=$ua->server(Mojo::UserAgent::server->new);

将使用处理应用程序服务器相对URL,默认为Mojo::UserAgent::服务器对象。

#模拟web服务$ua->server->app(Mojolicios->new);$ua->server->app->routes->get('/time'=>sub($c){$c->render(json=>{now=>time});});my$time=$ua->get('/time')->result->json->{now};#更改日志级别$ua->server->app->log->level(“fatal”);#当前用于处理相对URL阻塞的端口说$ua->server->url->port;#当前用于处理非阻塞相对URL的端口比如$ua->server->nb_url->port;

套接字选项(_O)

我的$options=$ua->socket_options;$ua=$ua->socket_options({LocalAddr=>'127.0.0.1'});

其他选项IO::套接字::IP打开新连接时。

tls选项

我的$options=$ua->tls_options;$ua=$ua->tls_options({SSL_cipher_list=>'默认值:!DH@截面标高=1'});

其他选项IO::套接字::SSL打开新连接时。

交易人

我的$t=$ua->transactor;$ua=$ua->transactor(Mojo::UserAgent::transactor->new);

事务生成器,默认为Mojo::用户代理::交易方对象。

#更改用户代理的名称$ua->交易人->名称(“MyUA 1.0”);#禁用压缩$ua->transactor->compressed(0);

方法

Mojo::用户代理从继承所有方法Mojo::EventEmitter并实现了以下新功能。

构建_tx

my$tx=$ua->build_tx(GET=>'example.com');my$tx=$ua->build_tx(PUT=>'http://example.com'=>{Accept=>'*/*'}=>'内容!');my$tx=$ua->build_tx(PUT=>'http://example.com'=>{Accept=>'*/*'}=>form=>{a=>'b'});my$tx=$ua->build_tx(PUT=>'http://example.com'=>{Accept=>'*/*'}=>json=>{a=>'b'});

生成Mojo::Transaction::HTTP具有的对象Mojo::UserAgent::Transactor中的“tx”.

#带有自定义cookie的请求my$tx=$ua->build_tx(GET=>'https://example.com/account');$tx->req->cookie({name=>'user',value=>'sri'});$tx=$ua->开始($tx);#停用gzip压缩my$tx=$ua->build_tx(GET=>'example.com');$tx->req->headers->remove(“接受编码”);$tx=$ua->开始($tx);#通过引发错误中断响应my$tx=$ua->build_tx(GET=>'http://example.com');$tx->res->打开(进度=>sub($res){返回,除非我的$server=$res->headers->server;如果$server=~/IIS/;,$res->error({message=>“噢,不,这是IIS!”});});$tx=$ua->开始($tx);

构建websocket_tx

我的$tx=$ua->build_websocket_tx('ws://example.com');我的$tx=$ua->build_websocket_tx(“ws://example.com”=>{DNT=>1}=>[“v1.proto”]);

生成Mojo::Transaction::HTTP具有的对象Mojo::UserAgent::Transactor中的“websocket”.

#使用cookie自定义WebSocket握手我的$tx=$ua->build_websocket_tx('wss://example.com/echo');$tx->req->cookie({name=>'user',value=>'sri'});$ua->开始($tx=>sub($ua,$tx){说“WebSocket握手失败!”并返回,除非$tx->is_websocket;$tx->打开(消息=>sub($tx,$msg){说出“WebSocket消息:$msg”;$tx->完成;});$tx->send(“你好!”);});除非Mojo::IOLoop->is_running,否则Mojo::IOLoop->启动;

删除

我的$tx=$ua->delete('example.com');我的$tx=$ua->删除('http://example.com'=>{Accept=>'*/*'}=>'内容!');我的$tx=$ua->删除('http://example.com'=>{Accept=>'*/*'}=>form=>{a=>'b'});我的$tx=$ua->删除('http://example.com'=>{Accept=>'*/*'}=>json=>{a=>'b'});

执行阻塞删除请求并返回结果Mojo::Transaction::HTTP对象的参数与Mojo::UserAgent::Transactor中的“tx”(除了删除方法,这是隐含的)。您还可以附加回调来执行非阻塞请求。

$ua->删除('http://example.com'=>json=>{a=>'b'}=>sub($ua,$tx){say$tx->result->body});除非Mojo::IOLoop->is_running,否则Mojo::IOLoop->启动;

删除_p

我的$promise=$ua->delete_p('http://example.com');

等同于“删除”,但执行所有非阻塞请求并返回Mojo::承诺对象,而不是接受回调。

$ua->delete_p('http://example.com'=>json=>{a=>'b'})->然后(sub($tx){说$tx->result->body;})->catch(子($err){警告“连接错误:$err”;})->等待;

得到

我的$tx=$ua->get('example.com');我的$tx=$ua->get('http://example.com'=>{Accept=>'*/*'}=>'内容!');我的$tx=$ua->get('http://example.com'=>{Accept=>'*/*'}=>form=>{a=>'b'});我的$tx=$ua->get('http://example.com'=>{Accept=>'*/*'}=>json=>{a=>'b'});

执行阻塞GET(获取)请求并返回结果Mojo::Transaction::HTTP对象的参数与Mojo::UserAgent::Transactor中的“tx”(除了GET(获取)方法,这是隐含的)。您还可以附加回调来执行非阻塞请求。

$ua->get('http://example.com'=>json=>{a=>'b'}=>sub($ua,$tx){say$tx->result->body});除非Mojo::IOLoop->is_running,否则Mojo::IOLoop->启动;

获取(p)

我的$promise=$ua->getp('http://example.com');

等同于“获得”,但执行所有非阻塞请求并返回Mojo::承诺对象,而不是接受回调。

$ua->get_p('http://example.com'=>json=>{a=>'b'})->然后(sub($tx){说$tx->result->body;})->catch(子($err){警告“连接错误:$err”;})->等待;
我的$tx=$ua->头('example.com');我的$tx=$ua->头('http://example.com'=>{Accept=>'*/*'}=>'内容!');我的$tx=$ua->头('http://example.com'=>{Accept=>'*/*'}=>form=>{a=>'b'});我的$tx=$ua->头('http://example.com'=>{Accept=>'*/*'}=>json=>{a=>'b'});

执行阻塞头部请求并返回结果Mojo::Transaction::HTTP对象的参数与Mojo::UserAgent::Transactor中的“tx”(除了头部方法,这是隐含的)。您还可以附加回调来执行非阻塞请求。

$ua->头部('http://example.com'=>json=>{a=>'b'}=>sub($ua,$tx){say$tx->result->body});除非Mojo::IOLoop->is_running,否则Mojo::IOLoop->启动;

头部_p

我的$promise=$ua->head_p'http://example.com');

等同于“头部”,但执行所有非阻塞请求并返回Mojo::承诺对象,而不是接受回调。

$ua->head_p('http://example.com'=>json=>{a=>'b'})->然后(sub($tx){说$tx->result->body;})->catch(子($err){警告“连接错误:$err”;})->等待;

选项

我的$tx=$ua->选项('example.com');我的$tx=$ua->选项('http://example.com'=>{Accept=>'*/*'}=>'内容!');我的$tx=$ua->选项('http://example.com'=>{Accept=>'*/*'}=>form=>{a=>'b'});我的$tx=$ua->选项('http://example.com'=>{Accept=>'*/*'}=>json=>{a=>'b'});

执行阻塞选项请求并返回结果Mojo::Transaction::HTTP对象的参数与Mojo::UserAgent::Transactor中的“tx”(除了选项方法,这是隐含的)。您还可以附加回调来执行非阻塞请求。

$ua->选项('http://example.com'=>json=>{a=>'b'}=>sub($ua,$tx){say$tx->result->body});除非Mojo::IOLoop->is_running,否则Mojo::IOLoop->启动;

选项_p

我的$promise=$ua->options_p('http://example.com');

等同于“选项”,但执行所有非阻塞请求并返回Mojo::承诺对象,而不是接受回调。

$ua->options_p('http://example.com'=>json=>{a=>'b'})->然后(sub($tx){说$tx->result->body;})->捕获(sub($err){警告“连接错误:$err”;})->等待;

补丁

我的$tx=$ua->补丁('example.com');我的$tx=$ua->补丁('http://example.com'=>{Accept=>'*/*'}=>'内容!');我的$tx=$ua->补丁('http://example.com'=>{Accept=>'*/*'}=>form=>{a=>'b'});我的$tx=$ua->补丁('http://example.com'=>{Accept=>'*/*'}=>json=>{a=>'b'});

执行阻塞补丁请求并返回结果Mojo::Transaction::HTTP对象的参数与Mojo::UserAgent::Transactor中的“tx”(除了补丁方法,这是隐含的)。您还可以附加回调来执行非阻塞请求。

$ua->补丁('http://example.com'=>json=>{a=>'b'}=>sub($ua,$tx){say$tx->result->body});除非Mojo::IOLoop->is_running,否则Mojo::IOLoop->启动;

补丁_p

我的$promise=$ua->patch_p('http://example.com');

等同于“补丁”,但执行所有非阻塞请求并返回Mojo::承诺对象,而不是接受回调。

$ua->patch_p('http://example.com'=>json=>{a=>'b'})->然后(sub($tx){说$tx->result->body;})->catch(子($err){警告“连接错误:$err”;})->等待;

邮递

我的$tx=$ua->帖子('example.com');我的$tx=$ua->帖子('http://example.com'=>{Accept=>'*/*'}=>'内容!');我的$tx=$ua->帖子('http://example.com'=>{Accept=>'*/*'}=>form=>{a=>'b'});我的$tx=$ua->帖子('http://example.com'=>{Accept=>'*/*'}=>json=>{a=>'b'});

执行阻塞邮政请求并返回结果Mojo::Transaction::HTTP对象的参数与Mojo::UserAgent::Transactor中的“tx”(除了邮政方法,这是隐含的)。您还可以附加回调来执行非阻塞请求。

$ua->帖子('http://example.com'=>json=>{a=>'b'}=>sub($ua,$tx){say$tx->result->body});除非Mojo::IOLoop->is_running,否则Mojo::IOLoop->启动;

后p

我的$promise=$ua->postp('http://example.com');

等同于“发布”,但执行所有非阻塞请求并返回Mojo::承诺对象,而不是接受回调。

$ua->post_p('http://example.com'=>json=>{a=>'b'})->然后(sub($tx){说$tx->result->body;})->catch(子($err){警告“连接错误:$err”;})->等待;

我的$tx=$ua->put('example.com');我的$tx=$ua->put('http://example.com'=>{Accept=>'*/*'}=>'内容!');我的$tx=$ua->put('http://example.com'=>{Accept=>'*/*'}=>form=>{a=>'b'});我的$tx=$ua->put('http://example.com'=>{Accept=>'*/*'}=>json=>{a=>'b'});

执行阻塞PUT(输出)请求并返回结果Mojo::Transaction::HTTP对象的参数与Mojo::UserAgent::Transactor中的“tx”(除了PUT(输出)方法,这是隐含的)。您还可以附加回调来执行非阻塞请求。

$ua->put(')http://example.com'=>json=>{a=>'b'}=>sub($ua,$tx){say$tx->result->body});除非Mojo::IOLoop->is_running,否则Mojo::IOLoop->启动;

输入p

我的$promise=$ua->putp('http://example.com');

等同于“放入”,但执行所有非阻塞请求并返回Mojo::承诺对象,而不是接受回调。

$ua->put_p('http://example.com'=>json=>{a=>'b'})->然后(sub($tx){说$tx->result->body;})->捕获(sub($err){警告“连接错误:$err”;})->等待;

开始

my$tx=$ua->start(Mojo::Transaction::HTTP->new);

执行自定义的阻止请求Mojo::Transaction::HTTP对象,可以手动或使用“build_tx”。您还可以附加回调以执行非阻塞请求。

my$tx=$ua->build_tx(GET=>'http://example.com');$ua->start($tx=>sub($ua,$tx){说$tx->result->body});除非Mojo::IOLoop->is_running,否则Mojo::IOLoop->启动;

启动_p

my$promise=$ua->start_p(Mojo::Transaction::HTTP->new);

等同于“开始”,但执行所有非阻塞请求并返回Mojo::承诺对象,而不是接受回调。

my$tx=$ua->build_tx(GET=>'http://example.com');$ua->start_p($tx)->然后(sub($tx){说$tx->result->body;})->catch(子($err){警告“连接错误:$err”;})->等待;

网络套接字

$ua->websocket(“ws://example.com”=>sub{…});$ua->websocket(“ws://example.com”=>{DNT=>1}=>['v1.proto']=>sub{…});

使用透明握手打开非阻塞WebSocket连接,参数与Mojo::UserAgent::Transactor中的“websocket”。回调将收到Mojo::Transaction::WebSocketMojo::Transaction::HTTP对象,具体取决于握手是否成功。

$ua->websocket('wss://example.com/echo'=>['v1.proto']=>子($ua,$tx){说“WebSocket握手失败!”并返回,除非$tx->is_websocket;说“子协议协商失败!”并返回,除非$tx->协议;$tx->on(finish=>sub($tx,$code,$reason){say“WebSocket closed with status$code”});$tx->打开(消息=>sub($tx,$msg){说出“WebSocket消息:$msg”;$tx->完成;});$tx->send(“你好!”);});除非Mojo::IOLoop->is_running,否则Mojo::IOLoop->启动;

您可以激活永久消息泄漏通过设置Sec-WebSocket-扩展标头,这可以带来更好的性能,但也会将每个连接的内存使用量增加高达300KiB。

$ua->websocket(“ws://example.com/foo”=>{“Sec-WebSocket-Extensions”=>“permessage-deflate”}=>子{…});

网络套接字_p

我的$promise=$ua->websocket_p('ws://example.com');

等同于“网络套接字”,但返回一个Mojo::承诺对象,而不是接受回调。

$ua->websocket_p('wss://example.com/echo')->然后(sub($tx){my$promise=Mojo::promise->new;$tx->on(finish=>sub{$promise->resolve});$tx->打开(消息=>sub($tx,$msg){说出“WebSocket消息:$msg”;$tx->完成;});$tx->send(“你好!”);返回$promise;})->catch(子($err){警告“WebSocket错误:$err”;})->等待;

调试

您可以设置MOJO_CLIENT_DEBUG公司将一些高级诊断信息打印到的环境变量STDERR公司.

MOJO_CLIENT_DEBUG=1

另请参阅

Mojolicious公司,Mojolicious::指南,https://mojolicious.org.