The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Mojolicious::Plugin::HostMeta - Serve and Retrieve Host-Meta Documents

SYNOPSIS

  # Mojolicious
  $app->plugin('HostMeta');

  # Mojolicious::Lite
  plugin 'HostMeta';

  # Serves XRD or JRD from /.well-known/host-meta

  # Blocking requests
  print $c->hostmeta('gmail.com')->link('lrrd');

  # Non-blocking requests
  $c->hostmeta('gmail.com' => sub {
    print shift->link('lrrd');
  });

DESCRIPTION

Mojolicious::Plugin::HostMeta is a Mojolicious plugin to serve and request well-known Host-Meta documents.

METHODS

register

  # Mojolicious
  $app->plugin(HostMeta => {
    expires => 100
  });

  # Mojolicious::Lite
  plugin 'HostMeta';

Called when registering the plugin. Accepts one optional parameter expires, which is the number of seconds the served host-meta should be cached by the fetching client. Defaults to 10 days. All parameters can be set either as part of the configuration file with the key HostMeta or on registration (that can be overwritten by configuration).

HELPERS

hostmeta

  # In Controller:
  my $xrd = $c->hostmeta;
  $xrd = $c->hostmeta('gmail.com');
  $xrd = $c->hostmeta('sojolicio.us' => ['hub']);
  $xrd = $c->hostmeta('sojolicio.us', { 'X-MyHeader' => 'Fun' } => ['hub']);
  $xrd = $c->hostmeta('gmail.com', -secure);

  # Non blocking
  $c->hostmeta('gmail.com' => ['hub'] => sub {
    my $xrd = shift;
    # ...
  }, -secure);

This helper returns host-meta documents as XML::Loy::XRD objects with the XML::Loy::HostMeta extension.

If no host name is given, the local host-meta document is returned. If a host name is given, the corresponding host-meta document is retrieved from the host and returned.

An additional hash reference or a Mojo::Headers object can be used to pass header information for retrieval. An additional array reference may limit the relations to be retrieved (see the WebFinger specification for further explanation). A final -secure flag indicates, that discovery is allowed only over https without redirections.

This method can be used in a blocking or non-blocking way. For non-blocking retrieval, pass a callback function as the last argument before the optional -secure flag to the method. As the first passed response is the XML::Loy::XRD document, you have to use an offset of 0 in begin for parallel requests using Mojo::IOLoop::Delay.

CALLBACKS

fetch_hostmeta

  # Establish a callback
  $app->callback(
    fetch_hostmeta => sub {
      my ($c, $host) = @_;

      my $doc = $c->chi->get("hostmeta-$host");
      return unless $doc;

      my $header = $c->chi->get("hostmeta-$host-headers");

      # Return document
      return ($c->new_xrd($doc), Mojo::Headers->new->parse($header));
    }
  );

This callback is released before a host-meta document is retrieved from a foreign server. The parameters passed to the callback include the current controller object and the host's name.

If a XML::Loy::XRD document associated with the requested host name is returned (and optionally a Mojo::Headers object), the retrieval will stop.

The callback can be established with the callback helper or on registration.

This can be used for caching.

Callbacks may be changed for non-blocking requests.

HOOKS

prepare_hostmeta

  $app->hook(prepare_hostmeta => sub {
    my ($c, $xrd) = @_;
    $xrd->link(permanent => '/perma.html');
  };

This hook is run when the host's own host-meta document is first prepared. The hook passes the current controller object and the host-meta document as an XML::Loy::XRD object. This hook is only emitted once for each subscriber.

before_serving_hostmeta

  $app->hook(before_serving_hostmeta => sub {
    my ($c, $xrd) = @_;
    $xrd->link(lrdd => './well-known/host-meta');
  };

This hook is run before the host's own host-meta document is served. The hook passes the current controller object and the host-meta document as an XML::Loy::XRD object. This should be used for dynamical changes of the document for each request.

after_fetching_hostmeta

  $app->hook(
    after_fetching_hostmeta => sub {
      my ($c, $host, $xrd, $headers) = @_;

      # Store in cache
      my $chi = $c->chi;
      $chi->set("hostmeta-$host" => $xrd->to_string);
      $chi->set("hostmeta-$host-headers" => $headers->to_string);
    }
  );

This hook is run after a foreign host-meta document is newly fetched. The parameters passed to the hook are the current controller object, the host name, the XRD document as an XML::Loy::XRD object and the headers object of the response.

This can be used for caching.

ROUTES

The route /.well-known/host-meta is established and serves the host's own host-meta document. An endpoint called host-meta is established.

EXAMPLES

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/hostmetaapp 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/hostmetaapp-async daemon

DEPENDENCIES

Mojolicious (best with SSL support), Mojolicious::Plugin::Util::Endpoint, Mojolicious::Plugin::Util::Callback, Mojolicious::Plugin::XRD.

AVAILABILITY

  https://github.com/Akron/Mojolicious-Plugin-HostMeta

This plugin is part of the Sojolicious project.

COPYRIGHT AND LICENSE

Copyright (C) 2011-2015, Nils Diewald.

This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0.