CGI-Info
view release on metacpan or search on metacpan
lib/CGI/Info.pm view on Meta::CPAN
return $self->{is_ai};
}
# Allow environment variable override for testing or manual classification
if(defined(my $override = $ENV{'IS_AI'})) {
return $self->{is_ai} = $override ? 1 : 0;
}
my $agent = $ENV{'HTTP_USER_AGENT'};
my $remote = $ENV{'REMOTE_ADDR'};
unless($remote && $agent) {
# Probably not running in CGI - assume not an AI crawler
return 0;
}
# Known AI training and inference crawlers, matched against the User-Agent.
# We intentionally do not consult the shared IP/agent cache here: is_robot()
# stores 'robot' for many of the same UAs, and reading 'robot' != 'ai' would
# produce a false negative. Instance-level caching ($self->{is_ai}) above is
# sufficient to avoid redundant regex evaluation within a single request.
# Sources: vendor documentation and public bot lists.
# Anthropic: ClaudeBot, Claude-Web, anthropic-ai
# OpenAI: GPTBot, ChatGPT-User, OAI-SearchBot
# Google: Google-Extended (AI training opt-out token)
# Meta: meta-externalagent, FacebookBot (AI training)
# Apple: Applebot-Extended (AI training subset)
# Perplexity: PerplexityBot
# Amazon: Amazonbot (Amazon AI / Alexa AI)
# You.com: YouBot
# Diffbot: Diffbot
# Cohere: cohere-ai
# Common Crawl: CCBot (primary data source for many LLM trainers)
# ByteDance: Bytespider (TikTok / AI training)
# Allen AI: AI2Bot
# Timpi: TimpiBot
if($agent =~ /ClaudeBot|Claude-Web|anthropic-ai|GPTBot|ChatGPT-User|OAI-SearchBot|Google-Extended|meta-externalagent|FacebookBot|Applebot-Extended|PerplexityBot|Amazonbot|YouBot|Diffbot|cohere-ai|CCBot|Bytespider|AI2Bot|TimpiBot/i) {
# Enforce is_ai => is_robot so callers need not check both
$self->{is_robot} = 1;
return $self->{is_ai} = 1;
}
$self->{is_ai} = 0;
return 0;
}
=head2 browser_type
Returns a string classifying the visitor's client. The possible values are:
=over 4
=item * C<'mobile'> -- smartphone or tablet (checked first)
=item * C<'ai'> -- known AI training or inference crawler (see L</is_ai>)
=item * C<'search'> -- search-engine crawler
=item * C<'robot'> -- other automated client
=item * C<'web'> -- ordinary desktop or laptop browser
=back
use Carp;
use Template;
use CGI::Info;
my $info = CGI::Info->new();
my $dir = $info->rootdir() . '/templates/' . $info->browser_type();
my $filename = ref($info);
$filename =~ s/::/\//g;
$filename = "$dir/$filename.tmpl";
(-f $filename && -r $filename)
or croak "Cannot open template '$filename'";
my $template = Template->new();
$template->process($filename, {}) or croak $template->error();
=cut
sub browser_type {
my $self = shift;
if($self->is_mobile()) {
return 'mobile';
}
if($self->is_ai()) {
return 'ai';
}
if($self->is_search_engine()) {
return 'search';
}
if($self->is_robot()) {
return 'robot';
}
return 'web';
}
=head2 get_cookie
Returns a cookie's value, or undef if no name is given, or the requested
cookie isn't in the jar.
Deprecated - use cookie() instead.
use CGI::Info;
my $i = CGI::Info->new();
my $name = $i->get_cookie(cookie_name => 'name');
print "Your name is $name\n";
my $address = $i->get_cookie('address');
print "Your address is $address\n";
=cut
sub get_cookie {
my $self = shift;
( run in 0.937 second using v1.01-cache-2.11-cpan-9789f410c06 )