NAME

Apache2::API::Headers::AcceptCommon - Common base class for parsing HTTP Accept and Accept-Language headers

SYNOPSIS

use Apache2::API::Headers::Accept;
use Apache2::API::Headers::AcceptLanguage;

my $accept = Apache2::API::Headers::Accept->new( 'text/html;q=0.9,application/json' );
my $mime = $accept->match( ['text/html', 'application/json'] ); # => 'text/html'

my $al = Apache2::API::Headers::AcceptLanguage->new( 'fr-FR;q=0.9,en;q=0.8' );
my $locale = $lang->match( ['en', 'fr-FR'] ); # => 'fr-FR'

DESCRIPTION

Apache2::API::Headers::AcceptCommon implements a base class for parsing, sorting, and matching rules for HTTP headers that carry quality values (q), such as Accept and Accept-Language. Subclasses provide the domain-specific details:

  • how to parse a token, such as type/subtype vs. language tags

  • what counts as a full match vs partial match

  • how to detect wildcards and how specificity is scored

This base class guarantees:

  • Stable, decreasing sort by q (highest first)

  • Duplicate tokens keep the highest q

  • q=0 excludes a token

  • Empty/absent header means “everything acceptable” → first supported wins

  • Return values: empty string on “no match”, undef on error (with "error" in Module::Generic)

CONSTRUCTOR

new( $header, %opts )

Creates a new matcher. $header may be an empty string, but must always be provided. It returns a new object.

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

Read-only

Returns the header value initially provided during object instantiation.

match( \@supported_tokens )

Given an array reference of server-supported tokens, returns the best match as a string, based on quality and specificity.

If none could be found, it returns an empty string, or 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.

Semantics:

  • If no usable header was provided, the first entry in the array reference of supported tokens is returned.

  • For each client preference (sorted by q desc), exact matches are preferred over partial ones (as defined by the subclass), and then by specificity (subclasses implement _specificity).

  • Wildcards are treated as candidates with the lowest specificity. They never preempt an equal-q exact match.

  • Legacy tie-breaking is available, see "MATCH PRIORITY MODE".

preferences

Read-only.

Returns an array reference of the client tokens, sorted by decreasing quality weight (q) as submitted upon the HTTP request, with duplicates removed (keeping highest q). Always returns an array reference (even when cached).

So, for example:

my $accept = Apache2::API::Headers::Accept->new( 'text/html;q=0.9,application/json' );
my $prefs  = $accept->preferences; # ['application/json', 'text/html']

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.

MATCH PRIORITY MODE

Two policies are supported for tie-breaking when several tokens have the same q. You can choose per subclass:

  • Modern (default): tie favors header order (client’s order) and specificity.

  • Legacy 0.01 style: set the package variable Apache2::API::Headers::Accept::MATCH_PRIORITY_0_01_STYLE = 1 or Apache2::API::Headers::AcceptLanguage::MATCH_PRIORITY_0_01_STYLE = 1. At each equal-q bucket, the choice follows the server supported order (first match in \@supported), with full matches beating partial ones. Wildcards in the bucket are only used if nothing else is matched.

DIAGNOSTICS

This module registers warnings in category Apache2::API. With debugging enabled (via Module::Generic), you will see trace messages such as parsing steps and why a candidate was chosen.

THREAD SAFETY

All state is per object; no shared mutable globals. Thus, this module is safe to use in threads.

AUTHOR

Jacques Deguest <jack@deguest.jp>

SEE ALSO

Apache2::API::Headers::Accept, Apache2::API::Headers::AcceptLanguage, Module::Generic::HeaderValue, 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) 2025 DEGUEST Pte. Ltd.

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