NAME

Apache2::API::Headers::Accept - Parser and matcher for HTTP Accept header

SYNOPSIS

use Apache2::API::Headers::Accept;
my $accept = Apache2::API::Headers::Accept->new('text/html;q=0.9,application/json');
my $mime = $accept->match(['text/html', 'application/json']); # => 'text/html'
# inspect client preferences (by q, desc):
my $prefs = $a->preferences; # [ 'application/json', 'text/html' ]

DESCRIPTION

Parses the Accept header and selects the best media type among the types you can serve. It supports exact matches (type/subtype), type wildcards (type/*), and full wildcards (*/*), with quality values (q) per RFC 7231 and RFC 9110.

It inherits from Apache2::API::Headers::AcceptCommon.

The algorithm is as follows:

  • Specificity order (highest first): type/subtype > type/* > */*

  • q value primary sort; on tie, prefer more specific matches.

  • */* at same q never outranks a specific match; at strictly higher q it picks the first supported item.

  • Non-q parameters (e.g. charset, version) do not influence matching; they are parsed but ignored for selection.

CONSTRUCTOR

new( $header )

Creates a new instance with the given Accept header string, and returns it.

If an error occurred, it sets an error that can be retrieved with the error method, and it returns undef in scalar context, or an empty list in list context.

METHODS

match( \@supported_media_types )

Returns the best matching media type, as a string, from the provided list.

If no suitable media type could be found, it returns an empty string, so you need to check the return value if it is defined or not to differentiate from errors.

If an error occurred, it sets an error that can be retrieved with the error method, and it returns undef in scalar context, or an empty list in list context.

media_types

This is an alias to "preferences"

preferences

Read-only.

Returns an array reference of media types, submitted by the user in his HTTP request, sorted by decreasing quality (q), with duplicates removed (highest q kept).

If an error occurred, it sets an error that can be retrieved with the error method, and it returns undef in scalar context, or an empty list in list context.

EXAMPLES

1. More specific beats wildcard at same q

my $a = Apache2::API::Headers::Accept->new( 'text/html;q=0.9, text/*;q=0.9' );
$a->match( [ 'text/plain', 'text/html' ] );
# "text/html"

2. */* is a fallback only

my $a = Apache2::API::Headers::Accept->new( '*/*;q=0.9, application/json;q=0.9' );
$a->match( [ 'image/png', 'text/html', 'application/json' ] );
# "application/json"

3. */* with higher q wins and chooses first supported

my $a = Apache2::API::Headers::Accept->new( '*/*;q=1.0, application/json;q=0.9' );
$a->match( [ 'image/png', 'text/html', 'application/json' ] );
# "image/png"

LEGACY MATCH PRIORITY

Set $Apache2::API::Headers::Accept::MATCH_PRIORITY_0_01_STYLE to true to make equal-q ties follow the order of your offers (the array reference of supported medias), instead of the header order. Full matches still outrank partial ones. Wildcards in a bucket are only used if nothing else matches. (see "MATCH PRIORITY MODE" in Apache2::API::Headers::AcceptCommon for details).

PERFORMANCE

The matchers called with "match" in Apache2::API::Headers::AcceptCommon loops through the array reference of supported medias times the number of parsed acceptable medias as submitted by the client.

Typical HTTP Accept headers are small, so the performance should be very good.

"preferences" in Apache2::API::Headers::AcceptCommon and sorted results are cached per object.

AUTHOR

Jacques Deguest <jack@deguest.jp>

SEE ALSO

Apache2::API::Headers::AcceptCommon, Apache2::API::Headers::AcceptLanguage, RFC 7231, RFC 9110.

Apache2::API::DateTime, Apache2::API::Query, Apache2::API::Request, Apache2::API::Request::Params, Apache2::API::Request::Upload, Apache2::API::Response, Apache2::API::Status

Apache2::Request, Apache2::RequestRec, Apache2::RequestUtil

COPYRIGHT & LICENSE

Copyright (c) 2023 DEGUEST Pte. Ltd.

You can use, copy, modify and redistribute this package and associated files under the same terms as Perl itself.