<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package Catalyst::ActionRole::ConsumesContent;

use Moose::Role;

requires 'match', 'match_captures', 'list_extra_info';

has allowed_content_types =&gt; (
  is=&gt;'ro',
  required=&gt;1,
  lazy=&gt;1,
  isa=&gt;'ArrayRef',
  builder=&gt;'_build_allowed_content_types');

has normalized =&gt; (
  is=&gt;'ro',
  required=&gt;1,
  lazy=&gt;1,
  isa=&gt;'HashRef',
  builder=&gt;'_build_normalized');


sub _build_normalized {
  return +{
    JSON =&gt; 'application/json',
    JS =&gt; 'application/javascript',
    PERL =&gt; 'application/perl',
    HTML =&gt; 'text/html',
    XML =&gt; 'text/XML',
    Plain =&gt; 'text/plain',
    UrlEncoded =&gt; 'application/x-www-form-urlencoded',
    Multipart =&gt; 'multipart/form-data',
    HTMLForm =&gt; ['application/x-www-form-urlencoded','multipart/form-data'],
  };
}

sub _build_allowed_content_types {
    my $self = shift;
    my @proto = map {split ',', $_ } @{$self-&gt;attributes-&gt;{Consumes}};
    my @converted = map {
      if(my $normalized = $self-&gt;normalized-&gt;{$_}) {
        ref $normalized ? @$normalized : ($normalized);
      } else {
        $_;
      }
    } @proto;

    return \@converted;
}

around ['match','match_captures'] =&gt; sub {
    my ($orig, $self, $ctx, @args) = @_;
    if(my $content_type = $ctx-&gt;req-&gt;content_type) {
        return 0 unless $self-&gt;can_consume($content_type);
    }
    return $self-&gt;$orig($ctx, @args);
};

sub can_consume {
    my ($self, $request_content_type) = @_;
    my @matches = grep { lc($_) eq lc($request_content_type) }
      @{$self-&gt;allowed_content_types};
    return @matches ? 1:0;
}

around 'list_extra_info' =&gt; sub {
  my ($orig, $self, @args) = @_;
  return {
    %{ $self-&gt;$orig(@args) },
    CONSUMES =&gt; $self-&gt;allowed_content_types,
  };
};

1;

=head1 NAME

Catalyst::ActionRole::ConsumesContent - Match on HTTP Request Content-Type

=head1 SYNOPSIS

    package MyApp::Web::Controller::MyController;

    use base 'Catalyst::Controller';

    sub start : POST Chained('/') CaptureArg(0) { ... }

      sub is_json       : Chained('start') Consumes('application/json') { ... }
      sub is_urlencoded : Chained('start') Consumes('application/x-www-form-urlencoded') { ... }
      sub is_multipart  : Chained('start') Consumes('multipart/form-data') { ... }

      ## Alternatively, for common types...

      sub is_json       : Chained('start') Consume(JSON) { ... }
      sub is_urlencoded : Chained('start') Consumes(UrlEncoded) { ... }
      sub is_multipart  : Chained('start') Consumes(Multipart) { ... }

      ## Or allow more than one type

      sub is_more_than_one
        : Chained('start')
        : Consumes('application/x-www-form-urlencoded')
        : Consumes('multipart/form-data')
      {
        ## ...
      }

      1;

=head1 DESCRIPTION

This is an action role that lets your L&lt;Catalyst::Action&gt; match on the content
type of the incoming request.

Generally when there's a PUT or POST request, there's a request content body
with a matching MIME content type.  Commonly this will be one of the types
used with classic HTML forms ('application/x-www-form-urlencoded' for example)
but there's nothing stopping you specifying any valid content type.

For matching purposes, we match strings but the casing is insensitive.

=head1 REQUIRES

This role requires the following methods in the consuming class.

=head2 match

=head2 match_captures

Returns 1 if the action matches the existing request and zero if not.

=head1 METHODS

This role defines the following methods

=head2 match

=head2 match_captures

Around method modifier that return 1 if the request content type matches one of the
allowed content types (see L&lt;/http_methods&gt;) and zero otherwise.

=head2 allowed_content_types

An array of strings that are the allowed content types for matching this action.

=head2 can_consume

Boolean.  Does the current request match content type with what this actionrole
can consume?

=head2 list_extra_info

Add the accepted content type to the debug screen.

=head1 AUTHORS

Catalyst Contributors, see Catalyst.pm

=head1 COPYRIGHT

This library is free software. You can redistribute it and/or modify it under
the same terms as Perl itself.

=cut
</pre></body></html>