NAME
Mojolicious::Plugin::WebFinger - Serve and Retrieve WebFinger Documents
SYNOPSIS
# Mojolicious
$app->plugin('WebFinger');
# Mojolicious::Lite
plugin 'WebFinger';
# Serves XRD or JRD from /.well-known/webfinger
# Discover WebFinger resources the blocking ...
print $c->webfinger('acct:bob@example.com')
->link('describedby')
->attrs('href');
# ... or non-blocking way
$c->webfinger('acct:bob@example.com' => sub {
my ($xrd, $header) = @_;
# ...
});
DESCRIPTION
Mojolicious::Plugin::WebFinger provides several functions for the WebFinger Protocol. It supports .well-known/webfinger
discovery as well as HostMeta and works with both XRD and JRD.
This module is an early release! There may be significant changes in the future.
METHODS
register
# Mojolicious
$app->plugin(WebFinger => {
expires => 100,
secure => 1
});
# Mojolicious::Lite
plugin 'WebFinger';
Called when registering the plugin. Accepts the optional parameters secure
, which is a boolean value which indicates that only secure transactions are allowed, and expires
, which is the number of seconds the served WebFinger document should be cached by the fetching client (defaults to 10 days). These parameters can be either set on registration or as part of the configuration file with the key WebFinger
.
HELPERS
webfinger
# In Controllers:
my $xrd = $self->webfinger('acct:me@sojolicio.us');
# Only secure discovery
my $xrd = $self->webfinger('acct:me@sojolicio.us', -secure);
# Use lrdd with host and resource description
my $xrd = $self->webfinger(
'sojolicio.us' => 'http://sojolicio.us/me.html', -secure
);
# Use rel parameters
my $xrd = $self->webfinger(
'acct:me@sojolicio.us' => ['describedBy'], -secure
);
# Use non-blocking
$self->webfinger(
'acct:me@sojolicio.us' => [qw/describedBy author/] => sub {
my $xrd = shift;
# ...
} => -modern);
# Serve local WebFinger documents
my $xrd = $self->webfinger('me');
Returns the WebFinger resource as an XRD object. Accepts the WebFinger resource, an optional array reference of relations, and an optional callback for non-blocking requests. The appended flag indicates, how the discovery should be done. -secure
indicates, that discovery is allowed only over https
. -modern
indicates, that only /.well-known/webfinger
is discovered over https
. -old
indicates, that only Host-Meta and lrdd discovery is used.
CALLBACKS
fetch_webfinger
# Establish a callback
$mojo->callback(
fetch_webfinger=> sub {
my ($c, $host, $res, $header) = @_;
# Get cached document
my $doc = $c->chi->get("webfinger-$host-$res");
return unless $doc;
# Get cached headers
my $headers = $c->chi->get("webfinger-$host-$res-headers");
# Return document
return ($c->new_xrd($doc), Mojo::Headers->new->parse($headers));
}
);
This callback is released before a WebFinger document is retrieved from a foreign server. The parameters passed to the callback include the current controller object, the host's name and the resource name.
If an XRD object associated with the requested host name is returned (and optionally a Mojo::Headers object), the retrieval will stop.
This can be used for caching.
The callback can be established with the callback helper or on registration. Callbacks may be changed for non-blocking requests.
prepare_webfinger
if ($c->callback(prepare_webfinger => sub {
my ($c, $res) = @_;
if ($res eq 'acct:akron@sojolicio.us') {
$c->stash('profile' => 'http://sojolicio.us/user/akron');
return 1;
};
})) {
print 'The requested resource exists!';
};
This callback is triggered before a WebFinger document is served. The current controller object and the requested resource is passed. A boolean value indicating the validity of the resource is expected. A rendered response in the callback will be respected and further serving won't be processed.
Data retrieved for the resource can be passed to the stash and rendered using the before_serving_webfinger hook.
The callback can be either set using the callback helper or on registration. Callbacks may be changed for non-blocking requests.
HOOKS
before_serving_webfinger
$mojo->hook(
before_serving_webfinger => sub {
my ($c, $res, $xrd) = @_;
if ($c->stash('profile')) {
$xrd->link(profile => { href => $c->stash('profile') } );
};
});
This hook is run before the requested WebFinger document is served. The hook passes the current controller object, the resource name and the XRD object.
after_fetching_webfinger
$mojo->hook(
after_fetching_webfinger => sub {
my ($c, $host, $res, $xrd, $headers) = @_;
# Store document in cache
$c->chi->set("webfinger-$host-$res" => $xrd->to_pretty_xml);
# Store headers in cache
$c->chi->set("webfinger-$host-$res-headers" => $headers->to_string);
}
);
This hook is run after a foreign WebFinger document is newly fetched. The parameters passed to the hook are the current controller object, the host name, the resource name, the XRD object and the headers object of the response.
This can be used for caching.
ROUTES
The route /.well-known/webfinger
is established as the lrdd endpoint webfinger
. This plugin depends on this route, and the resource
and rel
attributes. Although other routes are possible for WebFinger/lrdd in older drafts of the specification and different forms for the resource definition, this is assumed to be a future-proof best practice.
EXAMPLE
The examples/
folder contains a full working example application with serving and discovery. The example has an additional dependency of CHI. It can be started using the daemon, morbo or hypnotoad.
$ perl examples/webfingerapp daemon
This example may be a good starting point for your own implementation.
A less advanced application using non-blocking requests without caching is also available in the examples/
folder. It can be started using the daemon, morbo or hypnotoad as well.
$ perl examples/webfingerapp-async daemon
DEPENDENCIES
Mojolicious (best with SSL support), Mojolicious::Plugin::HostMeta.
AVAILABILITY
https://github.com/Akron/Mojolicious-Plugin-WebFinger
This plugin is part of the Sojolicious project.
COPYRIGHT AND LICENSE
Copyright (C) 2011-2013, Nils Diewald.
This program is free software, you can redistribute it and/or modify it under the same terms as Perl.