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"}]);

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