File Coverage

blib/lib/Mojolicious/Plugin/IsBot.pm
Criterion Covered Total %
statement 20 20 100.0
branch 2 2 100.0
condition 2 3 66.6
subroutine 5 5 100.0
pod 1 1 100.0
total 30 31 96.7


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::IsBot;
2              
3 1     1   611265 use Mojo::Base 'Mojolicious::Plugin';
  1         3  
  1         9  
4              
5             our $VERSION = '0.001';
6              
7             our @EXPORT_OK = qw(is_bot);
8              
9             # Credits to: https://github.com/omrilotan/isbot
10             my $BOT_HEADERS = [
11             qr/\sdaum[ \/]/,
12             qr/\sdeusu\//,
13             qr/\syadirectfetcher/,
14             qr/(?:^|\s)site/,
15             qr/(?:^|[^g])news/,
16             qr/@[a-z]/,
17             qr/\\(at\\)[a-z]/,
18             qr/\(github\.com/,
19             qr/\\[at\\][a-z]/,
20             qr/^12345/,
21             qr/^
22             qr/[\s]{50,}/,
23             qr/^active/,
24             qr/^ad muncher/,
25             qr/^amaya/,
26             qr/^anglesharp/,
27             qr/^anonymous/,
28             qr/^avsdevicesdk/,
29             qr/^axios/,
30             qr/^bidtellect/,
31             qr/^biglotron/,
32             qr/^btwebclient/,
33             qr/^castro/,
34             qr/^clamav[\s\/]/,
35             qr/^client/,
36             qr/^cobweb/,
37             qr/^coccoc/,
38             qr/^custom/,
39             qr/^ddg[_-]android/,
40             qr/^discourse/,
41             qr/^dispatch\/\d/,
42             qr/^downcast/,
43             qr/^duckduckgo/,
44             qr/^facebook/,
45             qr/^fdm[\s\/]\d/,
46             qr/^getright/,
47             qr/^gozilla/,
48             qr/^hatena/,
49             qr/^hobbit/,
50             qr/^hotzonu/,
51             qr/^hwcdn/,
52             qr/^jeode/,
53             qr/^jetty/,
54             qr/^jigsaw/,
55             qr/^linkdex/,
56             qr/^lwp[-:\s]/,
57             qr/^metauri/,
58             qr/^microsoft\sbits/,
59             qr/^movabletype/,
60             qr/^mozilla\/\d\.\d\s(compatible;?\\)$/,
61             qr/^mozilla\/\d\.\d\s\w*$/,
62             qr/^navermailapp/,
63             qr/^netsurf/,
64             qr/^offline\sexplorer/,
65             qr/^php/,
66             qr/^postman/,
67             qr/^postrank/,
68             qr/^python/,
69             qr/^read/,
70             qr/^reed/,
71             qr/^restsharp/,
72             qr/^snapchat/,
73             qr/^space\sbison/,
74             qr/^svn/,
75             qr/^swcd\s/,
76             qr/^taringa/,
77             qr/^test\scertificate\sinfo/,
78             qr/^thumbor/,
79             qr/^tumblr/,
80             qr/^user-agent:mozilla/,
81             qr/^valid/,
82             qr/^venus\/fedoraplanet/,
83             qr/^w3c/,
84             qr/^webbandit/,
85             qr/^webcopier/,
86             qr/^wget/,
87             qr/^whatsapp/,
88             qr/^xenu\slink\ssleuth/,
89             qr/^yahoo/,
90             qr/^yandex/,
91             qr/^zdm\/\d/,
92             qr/^zoom\smarketplace/,
93             qr/^\{\{.*\}\}$/,
94             qr/adbeat\.com/,
95             qr/appinsights/,
96             qr/archive/,
97             qr/ask\sjeeves\/teoma/,
98             qr/bit\.ly/,
99             qr/bluecoat\sdrtr/,
100             qr/bot/,
101             qr/browsex/,
102             qr/burpcollaborator/,
103             qr/capture/,
104             qr/catch/,
105             qr/check/,
106             qr/chrome-lighthouse/,
107             qr/chromeframe/,
108             qr/cloud/,
109             qr/crawl/,
110             qr/cryptoapi/,
111             qr/dareboost/,
112             qr/datanyze/,
113             qr/dataprovider/,
114             qr/dejaclick/,
115             qr/dmbrowser/,
116             qr/download/,
117             qr/evc-batch.*/,
118             qr/feed/,
119             qr/firephp/,
120             qr/freesafeip/,
121             qr/ghost/,
122             qr/gomezagent/,
123             qr/google/,
124             qr/headlesschrome/,
125             qr/http/,
126             qr/httrack/,
127             qr/hubspot\smarketing\sgrader/,
128             qr/hydra/,
129             qr/ibisbrowser/,
130             qr/images/,
131             qr/iplabel/,
132             qr/ips-agent/,
133             qr/java/,
134             qr/library/,
135             qr/mail\.ru/,
136             qr/manager/,
137             qr/monitor/,
138             qr/morningscore/,
139             qr/neustar\swpm/,
140             qr/nutch/,
141             qr/offbyone/,
142             qr/optimize/,
143             qr/pageburst/,
144             qr/pagespeed/,
145             qr/perl/, # :(
146             qr/phantom/,
147             qr/pingdom/,
148             qr/powermarks/,
149             qr/preview/,
150             qr/proxy/,
151             qr/ptst[\s\/]\d/,
152             qr/reader/,
153             qr/rexx;/,
154             qr/rigor/,
155             qr/rss/,
156             qr/scan/,
157             qr/scrape/,
158             qr/search/,
159             qr/serp\s\?reputation\s\?management/,
160             qr/server/,
161             qr/sogou/,
162             qr/sparkler/,
163             qr/speedcurve/,
164             qr/spider/,
165             qr/splash/,
166             qr/statuscake/,
167             qr/stumbleupon\.com/,
168             qr/supercleaner/,
169             qr/synapse/,
170             qr/synthetic/,
171             qr/taginspector/,
172             qr/torrent/,
173             qr/tracemyfile/,
174             qr/transcoder/,
175             qr/trendsmapresolver/,
176             qr/twingly\srecon/,
177             qr/url/,
178             qr/virtuoso/,
179             qr/wappalyzer/,
180             qr/webglance/,
181             qr/webkit2png/,
182             qr/websitemetadataretriever/,
183             qr/whatcms/,
184             qr/wordpress/,
185             qr/zgrab/
186             ];
187              
188             sub register {
189 1     1 1 340428 my $app = $_[1];
190              
191             {
192 1     1   3151 no warnings 'all';
  1         3  
  1         44  
  1         2  
193 1     1   4 no strict 'refs';
  1         17  
  1         227  
194 1         9 *{"Mojo::Message::Request::is_bot"} = sub {
195 43     43   72365 my $self = shift;
196 43   66     175 my $str = $self->headers->user_agent // shift;
197              
198 43         1127 foreach my $p (@$BOT_HEADERS) {
199 5805 100       19564 if ( $str =~ $p ) {
200 23         181 return 1;
201             }
202             }
203              
204 20         188 return 0;
205 1         5 };
206             }
207              
208 1         4 return $_[0];
209             }
210              
211             =encoding utf8
212              
213             =head1 Name
214              
215             Mojolicious::Plugin::IsBot
216              
217             =head1 Synopsis
218              
219             A super simple Mojolicious plugin to test if a User-Agent header is possbily a bot.
220              
221             Works by adding a C method to L.
222              
223             =head2 Example
224              
225             use Mojolicious::Lite -signatures;
226              
227             plugin('IsBot');
228              
229             get '/' => sub {
230             my $s = shift;
231            
232             return $s->render(text => 'You are bot!') if $s->req->is_bot;
233            
234             $s->render(text => 'You are not bot!');
235             };
236              
237             app->start;
238              
239             =head2 License
240              
241             Is::Bot is provided under the Artistic 2.0 license.