Name
SPVM::Mojo::UserAgent - Non-blocking I/O HTTP and WebSocket user agent
Description
Mojo::UserAgent class in SPVM is a full featured non-blocking I/O HTTP and WebSocket user agent, with IPv6, TLS, SNI, IDNA, HTTP proxy, UNIX domain socket, Comet (long polling), Promises/A+, keep-alive, connection pooling, timeout, cookie, multipart, gzip compression and multiple event loop support.
Usage
use Mojo::UserAgent;
# Fine grained response handling (dies on connection errors)
my $ua = Mojo::UserAgent->new;
my $res = $ua->get("docs.mojolicious.org")->result;
if ($res->is_success) { say $res->body }
elsif ($res->is_error) { say $res->message }
elsif ($res->code == 301) { say $res->headers->location }
else { say "Whatever..." }
# Say hello to the Unicode snowman and include an Accept header
say $ua->get("www.☃.net?hello=there" => {Accept => "*/*"})->result->body;
# IPv6 PUT request with Content-Type header and content
my $tx = $ua->put("[::1]:3000" => {"Content-Type" => "text/plain"} => "Hi!");
# Quick JSON API request with Basic authentication
my $url = (my $_ = Mojo::URL->new("https://example.com/test.json"), $_->set_userinfo("sri:☃"), $_);
my $value = $ua->get($url)->result->json;
# JSON POST (application/json) with TLS certificate authentication
my $tx = ($ua->set_cert("tls.crt"), $ua->set_key("tls.key"), $ua->post("https://example.com" => [(object)json => {top => "secret"}]));
# Form POST (application/x-www-form-urlencoded)
my $tx = $ua->post("https://metacpan.org/search" => [(object)form => {q => "mojo"}]);
# Search DuckDuckGo anonymously through Tor
$ua->proxy->http("socks://127.0.0.1:9050");
$ua->get("api.3g2upl4pq6kufc4m.onion/?q=mojolicious&format=json")->result->json;
# GET request via UNIX domain socket "/tmp/myapp.sock" (percent encoded slash)
say $ua->get("http+unix://%2Ftmp%2Fmyapp.sock/test")->result->body;
# Follow redirects to download Mojolicious from GitHub
($ua->set_max_redirects(5),
$ua->get("https://www.github.com/mojolicious/mojo/tarball/main")
->result->save_to("/home/sri/mojo.tar.gz"));
Class Methods
new
static method new : Mojo::UserAgent ();
Create a new Mojo::UserAgent object, and return it.
Instance Methods
build_tx
method build_tx : Mojo::Transaction::HTTP ($method : string, $url : object of string|Mojo::URL, $args1 : object = undef, $args2 : object = undef);
Generate Mojo::Transaction::HTTP object with Mojo::UserAgent::Transactor#tx.
Examples:
my $tx = $ua->build_tx(GET => "example.com");
my $tx = $ua->build_tx(PUT => "http://example.com" => {Accept => "*/*"} => "Content!");
my $tx = $ua->build_tx(PUT => "http://example.com" => {Accept => "*/*"} => [(object)form => {a => "b"}]);
my $tx = $ua->build_tx(PUT => "http://example.com" => {Accept => "*/*"} => [(object)json => {a => "b"}]);
# Request with custom cookie
my $tx = $ua->build_tx(GET => "https://example.com/account");
$tx->req->cookies({name => "user", value => "sri"});
$tx = $ua->start($tx);
# Deactivate gzip compression
my $tx = $ua->build_tx(GET => "example.com");
$tx->req->headers->remove("Accept-Encoding");
$tx = $ua->start($tx);
# Interrupt response by raising an error
my $tx = $ua->build_tx(GET => "http://example.com");
$tx->res->on(progress => method ($res : Mojo::Message::Response) {
unless (my $server = $res->headers->server) {
return;
}
if (Re->m($server, "IIS")) {
die "Oh noes, it is IIS!";
}
});
$tx = $ua->start($tx);
build_websocket_tx
Not yet implemented.
delete
method delete : Mojo::Transaction::HTTP ($url : object of string|Mojo::URL, $args1 : object = undef, $args2 : object = undef);
Perform blocking DELETE
request and return resulting Mojo::Transaction::HTTP object, takes the same arguments as "tx" in Mojo::UserAgent::Transactor (except for the DELETE
method, which is implied).
Examples:
my $tx = $ua->delete("example.com");
my $tx = $ua->delete("http://example.com" => {Accept => "*/*"} => "Content!");
my $tx = $ua->delete("http://example.com" => {Accept => "*/*"} => [(object)form => {a => "b"}]);
my $tx = $ua->delete("http://example.com" => {Accept => "*/*"} => [(object)json => {a => "b"}]);
get
method get : Mojo::Transaction::HTTP ($url : object of string|Mojo::URL, $args1 : object = undef, $args2 : object = undef);
Perform blocking GET
request and return resulting Mojo::Transaction::HTTP object, takes the same arguments as "tx" in Mojo::UserAgent::Transactor (except for the GET
method, which is implied).
Examples:
my $tx = $ua->get("example.com");
my $tx = $ua->get("http://example.com" => {Accept => "*/*"} => "Content!");
my $tx = $ua->get("http://example.com" => {Accept => "*/*"} => [(object)form => {a => "b"}]);
my $tx = $ua->get("http://example.com" => {Accept => "*/*"} => [(object)json => {a => "b"}]);
head
method head : Mojo::Transaction::HTTP ($url : object of string|Mojo::URL, $args1 : object = undef, $args2 : object = undef);
Perform blocking HEAD
request and return resulting Mojo::Transaction::HTTP object, takes the same arguments as "tx" in Mojo::UserAgent::Transactor (except for the HEAD
method, which is implied).
Examples:
my $tx = $ua->head("example.com");
my $tx = $ua->head("http://example.com" => {Accept => "*/*"} => "Content!");
my $tx = $ua->head("http://example.com" => {Accept => "*/*"} => [(object)form => {a => "b"}]);
my $tx = $ua->head("http://example.com" => {Accept => "*/*"} => [(object)json => {a => "b"}]);
options
method options : Mojo::Transaction::HTTP ($url : object of string|Mojo::URL, $args1 : object = undef, $args2 : object = undef);
Perform blocking OPTIONS
request and return resulting Mojo::Transaction::HTTP object, takes the same arguments as "tx" in Mojo::UserAgent::Transactor (except for the OPTIONS
method, which is implied).
Examples:
my $tx = $ua->options("example.com");
my $tx = $ua->options("http://example.com" => {Accept => "*/*"} => "Content!");
my $tx = $ua->options("http://example.com" => {Accept => "*/*"} => [(object)form => {a => "b"}]);
my $tx = $ua->options("http://example.com" => {Accept => "*/*"} => [(object)json => {a => "b"}]);
patch
method patch : Mojo::Transaction::HTTP ($url : object of string|Mojo::URL, $args1 : object = undef, $args2 : object = undef);
Perform blocking PATCH
request and return resulting Mojo::Transaction::HTTP object, takes the same arguments as "tx" in Mojo::UserAgent::Transactor (except for the PATCH
method, which is implied).
Examples:
my $tx = $ua->patch("example.com");
my $tx = $ua->patch("http://example.com" => {Accept => "*/*"} => "Content!");
my $tx = $ua->patch("http://example.com" => {Accept => "*/*"} => [(object)form => {a => "b"}]);
my $tx = $ua->patch("http://example.com" => {Accept => "*/*"} => [(object)json => {a => "b"}]);
post
method post : Mojo::Transaction::HTTP ($url : object of string|Mojo::URL, $args1 : object = undef, $args2 : object = undef);
Perform blocking POST
request and return resulting Mojo::Transaction::HTTP object, takes the same arguments as "tx" in Mojo::UserAgent::Transactor (except for the POST
method, which is implied).
Examples:
my $tx = $ua->post("example.com");
my $tx = $ua->post("http://example.com" => {Accept => "*/*"} => "Content!");
my $tx = $ua->post("http://example.com" => {Accept => "*/*"} => [(object)form => {a => "b"}]);
my $tx = $ua->post("http://example.com" => {Accept => "*/*"} => [(object)json => {a => "b"}]);
put
method put : Mojo::Transaction::HTTP ($url : object of string|Mojo::URL, $args1 : object = undef, $args2 : object = undef);
Perform blocking PUT
request and return resulting Mojo::Transaction::HTTP object, takes the same arguments as "tx" in Mojo::UserAgent::Transactor (except for the PUT
method, which is implied).
Examples:
my $tx = $ua->put("example.com");
my $tx = $ua->put("http://example.com" => {Accept => "*/*"} => "Content!");
my $tx = $ua->put("http://example.com" => {Accept => "*/*"} => [(object)form => {a => "b"}]);
my $tx = $ua->put("http://example.com" => {Accept => "*/*"} => [(object)json => {a => "b"}]);
start
method start : Mojo::Transaction::HTTP ($tx : Mojo::Transaction::HTTP);
Perform blocking request for a custom Mojo::Transaction::HTTP object, which can be prepared manually or with "build_tx".
Examples:
my $tx = $ua->start(Mojo::Transaction::HTTP->new);
websocket
Not yet implemented.
See Also
Copyright & License
Copyright (c) 2025 Yuki Kimoto
MIT License