Codebase list libhttp-browserdetect-perl / c6ecc4d
Update upstream source from tag 'upstream/3.23' Update to upstream version '3.23' with Debian dir 0c48a89ca2e5dfd5b7b1f736a6f44f49e6f6882e gregor herrmann 4 years ago
16 changed file(s) with 743 addition(s) and 132 deletion(s). Raw diff Collapse all Expand all
1616 * Graham Barr
1717 * gregor herrmann
1818 * Hao Wu
19 * James Waters
1920 * joatis
2021 * Jon Jensen
2122 * ktat
00 Revision history for Perl extension HTTP::BrowserDetect.
1
2 3.23 2019-04-04 19:26:18Z
3 - Add BingPreview to bot checker (GH#162) (James Waters)
4
5 3.22 2019-03-07 15:11:01Z
6 - Add a u2f() method (GH#161) (Patrick Cronin and Olaf Alders)
7 - Don't warn on fake UA strings. (GH#160) (Olaf Alders)
18
29 3.21 2019-02-05 01:50:40Z
310 - Faster edge test (GH#158) (Marco Fontani)
0 This software is copyright (c) 2017 by Lee Semel.
0 This software is copyright (c) 2019 by Lee Semel.
11
22 This is free software; you can redistribute it and/or modify it under
33 the same terms as the Perl 5 programming language system itself.
1111
1212 --- The GNU General Public License, Version 1, February 1989 ---
1313
14 This software is Copyright (c) 2017 by Lee Semel.
14 This software is Copyright (c) 2019 by Lee Semel.
1515
1616 This is free software, licensed under:
1717
271271
272272 --- The Artistic License 1.0 ---
273273
274 This software is Copyright (c) 2017 by Lee Semel.
274 This software is Copyright (c) 2019 by Lee Semel.
275275
276276 This is free software, licensed under:
277277
2121 t/03-language.t
2222 t/04-random-order.t
2323 t/05_robot.t
24 t/99_blank_ua.t
24 t/99-warnings.t
2525 t/add-field.pl
2626 t/make-more-useragents.pl
2727 t/more-useragents.json
2828 t/perlcriticrc
2929 t/useragents.json
3030 tidyall.ini
31 xt/author/pod-spell.t
3132 xt/author/pod-syntax.t
3233 xt/author/synopsis.t
3334 xt/author/tidyall.t
4242 "Parallel::ForkManager" : "1.19",
4343 "Perl::Critic" : "1.132",
4444 "Perl::Tidy" : "20180220",
45 "Pod::Wordlist" : "0",
4546 "Test::CPAN::Changes" : "0.19",
4647 "Test::Code::TidyAll" : "0.50",
4748 "Test::More" : "0.96",
4849 "Test::Pod" : "1.41",
50 "Test::Spelling" : "0.12",
4951 "Test::Synopsis" : "0",
5052 "Test::Vars" : "0.014"
5153 }
8991 "web" : "https://github.com/oalders/http-browserdetect"
9092 }
9193 },
92 "version" : "3.21",
94 "version" : "3.23",
9395 "x_Dist_Zilla" : {
9496 "perl" : {
9597 "version" : "5.026001"
217219 "class" : "Dist::Zilla::Plugin::ExecDir",
218220 "name" : "@Author::OALDERS/ExecDir",
219221 "version" : "6.012"
222 },
223 {
224 "class" : "Dist::Zilla::Plugin::Test::PodSpelling",
225 "config" : {
226 "Dist::Zilla::Plugin::Test::PodSpelling" : {
227 "directories" : [
228 "bin",
229 "lib"
230 ],
231 "spell_cmd" : "",
232 "stopwords" : [
233 "Alders",
234 "Alders'",
235 "AnnoCPAN",
236 "Atsushi",
237 "Cebrin",
238 "Firebird",
239 "Florian",
240 "Heiko",
241 "Iceweasel",
242 "KHTML",
243 "Kato",
244 "Kurihara",
245 "Latypoff",
246 "McGregor",
247 "Oatis",
248 "Pelzer",
249 "Purkis",
250 "Rask",
251 "RealPlayer",
252 "Rifkin",
253 "Ritter",
254 "Smidsrod",
255 "Sorcinelli",
256 "UserAgent",
257 "Voelker",
258 "WAP",
259 "WebKit",
260 "WinNT",
261 "Yoshiki",
262 "adm",
263 "ahrefs",
264 "altavista",
265 "aol",
266 "apache",
267 "applecoremedia",
268 "askjeeves",
269 "audrey",
270 "avantgo",
271 "baidu",
272 "bingbot",
273 "browsex",
274 "dalvik",
275 "ds",
276 "dsi",
277 "elinks",
278 "facebook",
279 "firefox",
280 "galeon",
281 "getright",
282 "golib",
283 "googleadsbot",
284 "googleadsense",
285 "googlebot",
286 "googlebotimage",
287 "googlebotnews",
288 "googlebotvideo",
289 "googlefavicon",
290 "googlemobile",
291 "icab",
292 "ie",
293 "indy",
294 "infoseek",
295 "iopener",
296 "ios",
297 "ipad",
298 "iphone",
299 "ipod",
300 "ipsagent",
301 "khtml",
302 "kindlefire",
303 "konqueror",
304 "linkchecker",
305 "linkexchange",
306 "lotusnotes",
307 "lycos",
308 "macosx",
309 "macppc",
310 "merlynkline",
311 "mj",
312 "mozilla",
313 "msn",
314 "msnmobile",
315 "msoffice",
316 "nav",
317 "navgold",
318 "neoplanet",
319 "netfront",
320 "netscape",
321 "nutch",
322 "obigo",
323 "phplib",
324 "polaris",
325 "ps",
326 "psp",
327 "pubsub",
328 "puf",
329 "realplayer",
330 "rubylib",
331 "seamonkey",
332 "specialarchiver",
333 "staroffice",
334 "ucbrowser",
335 "userAgent",
336 "wap",
337 "webkit",
338 "webos",
339 "webtv",
340 "wget",
341 "winnt",
342 "winphone",
343 "yandex",
344 "yandexbot",
345 "yandeximages"
346 ],
347 "wordlist" : "Pod::Wordlist"
348 }
349 },
350 "name" : "@Author::OALDERS/Test::PodSpelling",
351 "version" : "2.007005"
220352 },
221353 {
222354 "class" : "Dist::Zilla::Plugin::PodSyntaxTests",
397529 }
398530 },
399531 "name" : "@Author::OALDERS/Git::GatherDir",
400 "version" : "2.045"
532 "version" : "2.046"
401533 },
402534 {
403535 "class" : "Dist::Zilla::Plugin::CopyFilesFromRelease",
433565 "changelog" : "Changes"
434566 },
435567 "Dist::Zilla::Role::Git::Repo" : {
436 "git_version" : "2.20.1",
568 "git_version" : "2.21.0",
437569 "repo_root" : "."
438570 }
439571 },
440572 "name" : "@Author::OALDERS/Git::Check",
441 "version" : "2.045"
573 "version" : "2.046"
442574 },
443575 {
444576 "class" : "Dist::Zilla::Plugin::Git::Contributors",
445577 "config" : {
446578 "Dist::Zilla::Plugin::Git::Contributors" : {
447 "git_version" : "2.20.1",
579 "git_version" : "2.21.0",
448580 "include_authors" : 0,
449581 "include_releaser" : 1,
450582 "order_by" : "name",
473605 "class" : "Dist::Zilla::Plugin::TravisCI::StatusBadge",
474606 "name" : "@Author::OALDERS/TravisCI::StatusBadge",
475607 "version" : "0.007"
608 },
609 {
610 "class" : "Dist::Zilla::Plugin::CheckIssues",
611 "name" : "@Author::OALDERS/CheckIssues",
612 "version" : "0.010"
476613 },
477614 {
478615 "class" : "Dist::Zilla::Plugin::ConfirmRelease",
535672 "config" : {
536673 "Dist::Zilla::Plugin::Git::Commit" : {
537674 "add_files_in" : [],
538 "commit_msg" : "v%v%n%n%c"
675 "commit_msg" : "v%V%n%n%c"
539676 },
540677 "Dist::Zilla::Role::Git::DirtyFiles" : {
541678 "allow_dirty" : [
552689 "changelog" : "Changes"
553690 },
554691 "Dist::Zilla::Role::Git::Repo" : {
555 "git_version" : "2.20.1",
692 "git_version" : "2.21.0",
556693 "repo_root" : "."
557694 },
558695 "Dist::Zilla::Role::Git::StringFormatter" : {
560697 }
561698 },
562699 "name" : "@Author::OALDERS/@Git::VersionManager/release snapshot",
563 "version" : "2.045"
700 "version" : "2.046"
564701 },
565702 {
566703 "class" : "Dist::Zilla::Plugin::Git::Tag",
569706 "branch" : null,
570707 "changelog" : "Changes",
571708 "signed" : 0,
572 "tag" : "v3.21",
573 "tag_format" : "v%v",
574 "tag_message" : "v%v"
709 "tag" : "v3.23",
710 "tag_format" : "v%V",
711 "tag_message" : "v%V"
575712 },
576713 "Dist::Zilla::Role::Git::Repo" : {
577 "git_version" : "2.20.1",
714 "git_version" : "2.21.0",
578715 "repo_root" : "."
579716 },
580717 "Dist::Zilla::Role::Git::StringFormatter" : {
582719 }
583720 },
584721 "name" : "@Author::OALDERS/@Git::VersionManager/Git::Tag",
585 "version" : "2.045"
722 "version" : "2.046"
586723 },
587724 {
588725 "class" : "Dist::Zilla::Plugin::BumpVersionAfterRelease::Transitional",
624761 "changelog" : "Changes"
625762 },
626763 "Dist::Zilla::Role::Git::Repo" : {
627 "git_version" : "2.20.1",
764 "git_version" : "2.21.0",
628765 "repo_root" : "."
629766 },
630767 "Dist::Zilla::Role::Git::StringFormatter" : {
632769 }
633770 },
634771 "name" : "@Author::OALDERS/@Git::VersionManager/post-release commit",
635 "version" : "2.045"
772 "version" : "2.046"
636773 },
637774 {
638775 "class" : "Dist::Zilla::Plugin::Git::Push",
644781 "remotes_must_exist" : 1
645782 },
646783 "Dist::Zilla::Role::Git::Repo" : {
647 "git_version" : "2.20.1",
784 "git_version" : "2.21.0",
648785 "repo_root" : "."
649786 }
650787 },
651788 "name" : "@Author::OALDERS/Git::Push",
652 "version" : "2.045"
789 "version" : "2.046"
653790 },
654791 {
655792 "class" : "Dist::Zilla::Plugin::Prereqs",
661798 },
662799 "name" : "DevelopRequires",
663800 "version" : "6.012"
801 },
802 {
803 "class" : "Dist::Zilla::Plugin::StaticInstall",
804 "config" : {
805 "Dist::Zilla::Plugin::StaticInstall" : {
806 "dry_run" : 0,
807 "mode" : "on"
808 }
809 },
810 "name" : "StaticInstall",
811 "version" : "0.012"
664812 },
665813 {
666814 "class" : "Dist::Zilla::Plugin::FinderCode",
733881 "Graham Barr <gbarr@pobox.com>",
734882 "gregor herrmann <gregor+github@comodo.priv.at>",
735883 "Hao Wu <hwu@intellisurvey.com>",
884 "James Waters <james@jcwaters.co.uk>",
736885 "joatis <joatis3@gmail.com>",
737886 "Jon Jensen <jon@endpoint.com>",
738887 "ktat <ktat.is@gmail.com>",
756905 "yeahoffline <frank.gasser@gmail.com>"
757906 ],
758907 "x_generated_by_perl" : "v5.26.1",
759 "x_serialization_backend" : "Cpanel::JSON::XS version 4.04"
908 "x_serialization_backend" : "Cpanel::JSON::XS version 4.04",
909 "x_static_install" : 1
760910 }
761911
3838 bugtracker: https://github.com/oalders/http-browserdetect/issues
3939 homepage: https://github.com/oalders/http-browserdetect
4040 repository: https://github.com/oalders/http-browserdetect.git
41 version: '3.21'
41 version: '3.23'
4242 x_Dist_Zilla:
4343 perl:
4444 version: '5.026001'
139139 class: Dist::Zilla::Plugin::ExecDir
140140 name: '@Author::OALDERS/ExecDir'
141141 version: '6.012'
142 -
143 class: Dist::Zilla::Plugin::Test::PodSpelling
144 config:
145 Dist::Zilla::Plugin::Test::PodSpelling:
146 directories:
147 - bin
148 - lib
149 spell_cmd: ''
150 stopwords:
151 - Alders
152 - "Alders'"
153 - AnnoCPAN
154 - Atsushi
155 - Cebrin
156 - Firebird
157 - Florian
158 - Heiko
159 - Iceweasel
160 - KHTML
161 - Kato
162 - Kurihara
163 - Latypoff
164 - McGregor
165 - Oatis
166 - Pelzer
167 - Purkis
168 - Rask
169 - RealPlayer
170 - Rifkin
171 - Ritter
172 - Smidsrod
173 - Sorcinelli
174 - UserAgent
175 - Voelker
176 - WAP
177 - WebKit
178 - WinNT
179 - Yoshiki
180 - adm
181 - ahrefs
182 - altavista
183 - aol
184 - apache
185 - applecoremedia
186 - askjeeves
187 - audrey
188 - avantgo
189 - baidu
190 - bingbot
191 - browsex
192 - dalvik
193 - ds
194 - dsi
195 - elinks
196 - facebook
197 - firefox
198 - galeon
199 - getright
200 - golib
201 - googleadsbot
202 - googleadsense
203 - googlebot
204 - googlebotimage
205 - googlebotnews
206 - googlebotvideo
207 - googlefavicon
208 - googlemobile
209 - icab
210 - ie
211 - indy
212 - infoseek
213 - iopener
214 - ios
215 - ipad
216 - iphone
217 - ipod
218 - ipsagent
219 - khtml
220 - kindlefire
221 - konqueror
222 - linkchecker
223 - linkexchange
224 - lotusnotes
225 - lycos
226 - macosx
227 - macppc
228 - merlynkline
229 - mj
230 - mozilla
231 - msn
232 - msnmobile
233 - msoffice
234 - nav
235 - navgold
236 - neoplanet
237 - netfront
238 - netscape
239 - nutch
240 - obigo
241 - phplib
242 - polaris
243 - ps
244 - psp
245 - pubsub
246 - puf
247 - realplayer
248 - rubylib
249 - seamonkey
250 - specialarchiver
251 - staroffice
252 - ucbrowser
253 - userAgent
254 - wap
255 - webkit
256 - webos
257 - webtv
258 - wget
259 - winnt
260 - winphone
261 - yandex
262 - yandexbot
263 - yandeximages
264 wordlist: Pod::Wordlist
265 name: '@Author::OALDERS/Test::PodSpelling'
266 version: '2.007005'
142267 -
143268 class: Dist::Zilla::Plugin::PodSyntaxTests
144269 name: '@Author::OALDERS/PodSyntaxTests'
279404 Dist::Zilla::Plugin::Git::GatherDir:
280405 include_untracked: 0
281406 name: '@Author::OALDERS/Git::GatherDir'
282 version: '2.045'
407 version: '2.046'
283408 -
284409 class: Dist::Zilla::Plugin::CopyFilesFromRelease
285410 config:
307432 allow_dirty_match: []
308433 changelog: Changes
309434 Dist::Zilla::Role::Git::Repo:
310 git_version: 2.20.1
435 git_version: 2.21.0
311436 repo_root: .
312437 name: '@Author::OALDERS/Git::Check'
313 version: '2.045'
438 version: '2.046'
314439 -
315440 class: Dist::Zilla::Plugin::Git::Contributors
316441 config:
317442 Dist::Zilla::Plugin::Git::Contributors:
318 git_version: 2.20.1
443 git_version: 2.21.0
319444 include_authors: 0
320445 include_releaser: 1
321446 order_by: name
337462 class: Dist::Zilla::Plugin::TravisCI::StatusBadge
338463 name: '@Author::OALDERS/TravisCI::StatusBadge'
339464 version: '0.007'
465 -
466 class: Dist::Zilla::Plugin::CheckIssues
467 name: '@Author::OALDERS/CheckIssues'
468 version: '0.010'
340469 -
341470 class: Dist::Zilla::Plugin::ConfirmRelease
342471 name: '@Author::OALDERS/ConfirmRelease'
384513 config:
385514 Dist::Zilla::Plugin::Git::Commit:
386515 add_files_in: []
387 commit_msg: v%v%n%n%c
516 commit_msg: v%V%n%n%c
388517 Dist::Zilla::Role::Git::DirtyFiles:
389518 allow_dirty:
390519 - Changes
398527 allow_dirty_match: []
399528 changelog: Changes
400529 Dist::Zilla::Role::Git::Repo:
401 git_version: 2.20.1
530 git_version: 2.21.0
402531 repo_root: .
403532 Dist::Zilla::Role::Git::StringFormatter:
404533 time_zone: local
405534 name: '@Author::OALDERS/@Git::VersionManager/release snapshot'
406 version: '2.045'
535 version: '2.046'
407536 -
408537 class: Dist::Zilla::Plugin::Git::Tag
409538 config:
411540 branch: ~
412541 changelog: Changes
413542 signed: 0
414 tag: v3.21
415 tag_format: v%v
416 tag_message: v%v
543 tag: v3.23
544 tag_format: v%V
545 tag_message: v%V
417546 Dist::Zilla::Role::Git::Repo:
418 git_version: 2.20.1
547 git_version: 2.21.0
419548 repo_root: .
420549 Dist::Zilla::Role::Git::StringFormatter:
421550 time_zone: local
422551 name: '@Author::OALDERS/@Git::VersionManager/Git::Tag'
423 version: '2.045'
552 version: '2.046'
424553 -
425554 class: Dist::Zilla::Plugin::BumpVersionAfterRelease::Transitional
426555 config:
452581 - (?^:^lib/.*\.pm$)
453582 changelog: Changes
454583 Dist::Zilla::Role::Git::Repo:
455 git_version: 2.20.1
584 git_version: 2.21.0
456585 repo_root: .
457586 Dist::Zilla::Role::Git::StringFormatter:
458587 time_zone: local
459588 name: '@Author::OALDERS/@Git::VersionManager/post-release commit'
460 version: '2.045'
589 version: '2.046'
461590 -
462591 class: Dist::Zilla::Plugin::Git::Push
463592 config:
466595 - origin
467596 remotes_must_exist: 1
468597 Dist::Zilla::Role::Git::Repo:
469 git_version: 2.20.1
598 git_version: 2.21.0
470599 repo_root: .
471600 name: '@Author::OALDERS/Git::Push'
472 version: '2.045'
601 version: '2.046'
473602 -
474603 class: Dist::Zilla::Plugin::Prereqs
475604 config:
478607 type: requires
479608 name: DevelopRequires
480609 version: '6.012'
610 -
611 class: Dist::Zilla::Plugin::StaticInstall
612 config:
613 Dist::Zilla::Plugin::StaticInstall:
614 dry_run: 0
615 mode: on
616 name: StaticInstall
617 version: '0.012'
481618 -
482619 class: Dist::Zilla::Plugin::FinderCode
483620 name: ':InstallModules'
535672 - 'Graham Barr <gbarr@pobox.com>'
536673 - 'gregor herrmann <gregor+github@comodo.priv.at>'
537674 - 'Hao Wu <hwu@intellisurvey.com>'
675 - 'James Waters <james@jcwaters.co.uk>'
538676 - 'joatis <joatis3@gmail.com>'
539677 - 'Jon Jensen <jon@endpoint.com>'
540678 - 'ktat <ktat.is@gmail.com>'
558696 - 'yeahoffline <frank.gasser@gmail.com>'
559697 x_generated_by_perl: v5.26.1
560698 x_serialization_backend: 'YAML::Tiny version 1.70'
699 x_static_install: 1
3333 "Test::Most" => 0,
3434 "Test::NoWarnings" => 0
3535 },
36 "VERSION" => "3.21",
36 "VERSION" => "3.23",
3737 "test" => {
3838 "TESTS" => "t/*.t"
3939 }
33
44 # VERSION
55
6 version 3.21
6 version 3.23
77
88 # SYNOPSIS
99
3737 print "MSIE\n" if $ua->ie;
3838 print "Mobile\n" if $ua->mobile;
3939 if ( $ua->browser_major(4) ) {
40 if ( $ua->browser_minor() > .5 ) {
40 if ( $ua->browser_minor > .5 ) {
4141 # ...;
4242 }
4343 }
44 if ( $ua->browser_version() > 4.5 ) {
44 if ( $ua->browser_version > 4.5 ) {
4545 # ...;
4646 }
4747
584584 been removed; please use HTTP::BrowserDetect->new() to pass the user
585585 agent string.
586586
587 ## u2f()
588
589 Returns true if this browser and version are known to support Universal Second
590 Factor (U2F). This method will need future updates as more browsers fully
591 support this standard.
592
587593 ## country()
588594
589595 Returns the country string as it may be found in the user agent string. This
860866
861867 # COPYRIGHT AND LICENSE
862868
863 This software is copyright (c) 2017 by Lee Semel.
869 This software is copyright (c) 2019 by Lee Semel.
864870
865871 This is free software; you can redistribute it and/or modify it under
866872 the same terms as the Perl 5 programming language system itself.
3636 requires "Parallel::ForkManager" => "1.19";
3737 requires "Perl::Critic" => "1.132";
3838 requires "Perl::Tidy" => "20180220";
39 requires "Pod::Wordlist" => "0";
3940 requires "Test::CPAN::Changes" => "0.19";
4041 requires "Test::Code::TidyAll" => "0.50";
4142 requires "Test::More" => "0.96";
4243 requires "Test::Pod" => "1.41";
44 requires "Test::Spelling" => "0.12";
4345 requires "Test::Synopsis" => "0";
4446 requires "Test::Vars" => "0.014";
4547 };
33 author = Olaf Alders <olaf@wundercounter.com> (current maintainer)
44 license = Perl_5
55 copyright_holder = Lee Semel
6 copyright_year = 2017
6 copyright_year = 2019
77 main_module = lib/HTTP/BrowserDetect.pm
88
99 [@Author::OALDERS]
1010 -remove = MinimumPerl
1111 -remove = Test::Perl::Critic
12 -remove = Test::PodSpelling
1312 -remove = PodCoverageTests
13 -remove = StaticInstall
1414
1515 [Prereqs / DevelopRequires]
1616 Code::TidyAll::Plugin::UniqueLines = 0.000003
17
18 [StaticInstall]
19 mode = on
44
55 package HTTP::BrowserDetect;
66
7 our $VERSION = '3.21';
7 our $VERSION = '3.23';
88
99 use vars qw(@ALL_TESTS);
1010
929929
930930 $self->{browser} = $browser;
931931 $self->{browser_string} = $browser_string || $BROWSER_NAMES{$browser}
932 if defined($browser);
932 if defined $browser;
933933
934934 # Other random tests
935935
957957 $self->{realplayer_version} = $1;
958958 ( $self->{major}, $self->{minor} )
959959 = split( /\./, $self->{realplayer_version} );
960 $self->{minor} = ".$self->{minor}" if defined( $self->{minor} );
960 $self->{minor} = ".$self->{minor}" if defined $self->{minor};
961961 }
962962 elsif ( $ua =~ /realplayer\s(\w+)/ ) {
963963 $self->{realplayer_version} = $1;
10591059 $robot_fragment = 'msnbot';
10601060 }
10611061 elsif (index( $ua, 'binglocalsearch' ) != -1
1062 || index( $ua, 'bingbot' ) != -1 ) {
1062 || index( $ua, 'bingbot' ) != -1
1063 || index( $ua, 'bingpreview' ) != -1 ) {
10631064 $r = 'bingbot';
10641065 $robot_tests->{bingbot} = 1;
10651066 $robot_fragment = 'bingbot';
12651266 # This isn't all keyed on ids (yet)
12661267 $self->{robot_string} = $ROBOT_NAMES{$id} || $ROBOT_NAMES{$r};
12671268 $robot_tests->{robot} = $r;
1268 $robot_fragment = $r if !defined($robot_fragment);
1269 $robot_fragment = $r if !defined $robot_fragment;
12691270 }
12701271 elsif ( $ua =~ /seek (?! mo (?: toolbar )? \s+ \d+\.\d+ )/x ) {
12711272
13131314 $robot_tests->{robot_id} = 'unknown';
13141315 }
13151316
1316 if ( defined($robot_fragment) ) {
1317 if ( defined $robot_fragment ) {
13171318
13181319 # Examine what surrounds the fragment; that leads us to the
13191320 # version and the string (if we haven't explicitly set one).
13541355
13551356 # Set robot_string, if we don't already have an explictly set
13561357 # one
1357 if ( !defined( $self->{robot_string} ) ) {
1358 if ( !defined $self->{robot_string} ) {
13581359 $self->{robot_string} = $full_string;
13591360 }
13601361 }
17211722
17221723 my $os_version = undef;
17231724
1724 if ( !defined($os) ) {
1725 if ( !defined $os ) {
17251726
17261727 # Nothing is going to work if we have no OS. Skip everything.
17271728 }
17851786 ### using a browser that needs some special method to determine
17861787 ### the version.
17871788
1788 if ( defined($browser) && $browser eq 'opera' ) {
1789 if ( defined $browser && $browser eq 'opera' ) {
17891790
17901791 # Opera has a 'compatible; ' section, but lies sometimes. It needs
17911792 # special handling.
18421843 if ( my ( $safari_build, $safari_minor ) = split /\./, $1 ) {
18431844 $major = int( $safari_build / 100 );
18441845 $minor = int( $safari_build % 100 );
1845 $beta = ".$safari_minor" if $safari_minor;
1846 $beta = ".$safari_minor" if defined $safari_minor;
18461847 }
18471848 }
18481849 elsif ( $ua =~ m{applewebkit\/([\d\.]{1,})}xi ) {
19371938
19381939 # If we didn't match a browser-specific test, we look for
19391940 # '$browser/x.y.z'
1940 if ( !defined($major) and defined( $self->{browser_string} ) ) {
1941 if ( !defined $major && defined $self->{browser_string} ) {
19411942 my $version_index = index( $ua, lc "$self->{browser_string}/" );
19421943 if ( $version_index != -1 ) {
19431944 my $version_str
19511952 }
19521953
19531954 # If that didn't work, we try 'Version/x.y.z'
1954 if ( !defined($major) ) {
1955 if ( !defined $major ) {
19551956 if ( $ua =~ m{version/(\d+)\.(\d+)([\w.]*)} ) {
19561957 $major = $1;
19571958 $minor = $2;
19611962
19621963 # If that didn't work, we start guessing. Just grab
19631964 # anything after a word and a slash.
1964 if ( !defined($major) ) {
1965 if ( !defined $major ) {
19651966
19661967 ( $major, $minor, $beta ) = (
19671968 $ua =~ m{
19781979 }
19791980
19801981 # If that didn't work, try even more generic.
1981 if ( !defined($major) ) {
1982 if ( !defined $major ) {
19821983
19831984 if ( $ua =~ /[A-Za-z]+\/(\d+)\;/ ) {
19841985 $major = $1;
19891990 # If that didn't work, give up.
19901991 $major = 0 if !$major;
19911992 $minor = 0 if !$minor;
1992 $beta = undef if ( defined($beta) && $beta eq q{} );
1993 $beta = undef if ( defined $beta && $beta eq q{} );
19931994
19941995 # Now set version tests
19951996
20052006 if ( $major == 4 && ".$minor" >= .5 )
20062007 || $major >= 5;
20072008 $version_tests->{navgold} = 1
2008 if defined($beta) && ( index( $beta, 'gold' ) != -1 );
2009 if defined $beta && ( index( $beta, 'gold' ) != -1 );
20092010 $version_tests->{nav6} = 1
20102011 if ( $major == 5 || $major == 6 ); # go figure
20112012 $version_tests->{nav6up} = 1 if $major >= 5;
20392040 $version_tests->{ie_compat_mode}
20402041 = ( $version_tests->{ie7}
20412042 && $tests->{trident}
2042 && $self->{engine_version} + 0 >= 4 );
2043 && defined $self->engine_version
2044 && $self->engine_version >= 4 );
20432045 }
20442046
20452047 if ( $browser_tests->{aol} ) {
24302432 sub robot_version {
24312433 my ($self) = @_;
24322434 my ( $major, $minor, $beta ) = $self->_robot_version;
2433 if ( defined($major) ) {
2434 if ( defined($minor) ) {
2435 if ( defined $major ) {
2436 if ( defined $minor ) {
24352437 return "$major$minor";
24362438 }
24372439 else {
24912493 sub os_version {
24922494 my ($self) = @_;
24932495 my ( $major, $minor, $beta ) = $self->_os_version;
2494 if ( defined($major) ) {
2495 return "$major$minor";
2496 return defined $major ? "$major$minor" : undef;
2497 }
2498
2499 sub os_major {
2500 my ($self) = @_;
2501 my ( $major, $minor, $beta ) = $self->_os_version;
2502 return $major;
2503 }
2504
2505 sub os_minor {
2506 my ($self) = @_;
2507 my ( $major, $minor, $beta ) = $self->_os_version;
2508 return $minor;
2509 }
2510
2511 sub os_beta {
2512 my ($self) = @_;
2513 my ( $major, $minor, $beta ) = $self->_os_version;
2514 return $beta;
2515 }
2516
2517 sub _realplayer_version {
2518 my ($self) = @_;
2519
2520 $self->_init_version unless $self->{version_tests};
2521 return $self->{realplayer_version} || 0;
2522 }
2523
2524 sub realplayer_browser {
2525 my ($self) = @_;
2526 return defined( $self->{browser} ) && $self->{browser} eq 'realplayer';
2527 }
2528
2529 sub gecko_version {
2530 my ($self) = @_;
2531
2532 if ( $self->gecko ) {
2533 return $self->{engine_version};
24962534 }
24972535 else {
24982536 return undef;
24992537 }
25002538 }
25012539
2502 sub os_major {
2503 my ($self) = @_;
2504 my ( $major, $minor, $beta ) = $self->_os_version;
2505 return $major;
2506 }
2507
2508 sub os_minor {
2509 my ($self) = @_;
2510 my ( $major, $minor, $beta ) = $self->_os_version;
2511 return $minor;
2512 }
2513
2514 sub os_beta {
2515 my ($self) = @_;
2516 my ( $major, $minor, $beta ) = $self->_os_version;
2517 return $beta;
2518 }
2519
2520 sub _realplayer_version {
2521 my ($self) = @_;
2522
2523 $self->_init_version unless $self->{version_tests};
2524 return $self->{realplayer_version} || 0;
2525 }
2526
2527 sub realplayer_browser {
2528 my ($self) = @_;
2529 return defined( $self->{browser} ) && $self->{browser} eq 'realplayer';
2530 }
2531
2532 sub gecko_version {
2533 my ($self) = @_;
2534
2535 if ( $self->gecko ) {
2536 return $self->{engine_version};
2537 }
2538 else {
2539 return undef;
2540 }
2541 }
2542
25432540 sub version {
25442541 my ($self) = @_;
25452542 $self->_init_version() unless $self->{version_tests};
25462543
2547 my $version = "$self->{major}$self->{minor}";
2548 return $version;
2544 return defined $self->{major} ? "$self->{major}$self->{minor}" : undef;
25492545 }
25502546
25512547 sub major {
25692565 my ( $major, $minor ) = $self->_public;
25702566
25712567 $minor ||= q{};
2572 return "$major$minor";
2568 return defined $major ? "$major$minor" : undef;
25732569 }
25742570
25752571 sub public_major {
25982594 my ( $major, $minor ) = $self->_public;
25992595 $minor ||= q{};
26002596
2601 return "$major$minor";
2597 return defined $major ? "$major$minor" : undef;
26022598 }
26032599
26042600 sub browser_major {
26622658 # Special case for specific worm that uses a malformed user agent
26632659 return ( '1', '.2', undef ) if $ua =~ m{safari/12x};
26642660 }
2661
2662 return ( undef, undef, undef ) unless defined $version;
26652663 my ( $major, $minor ) = split /\./, $version;
26662664 my $beta;
26672665 $minor =~ s/(\D.*)// and $beta = $1;
27542752 }
27552753 }
27562754
2757 return $self->{engine_version};
2755 return undef;
27582756 }
27592757
27602758 sub engine_major {
29262924 return keys %ROBOT_NAMES;
29272925 }
29282926
2927 # The list of U2F supported browsers is expected to increase:
2928 # https://www.bit-tech.net/news/tech/software/w3c-adopts-fidos-webauthn-standard/1/
2929
2930 sub u2f {
2931 my $self = shift;
2932
2933 # Chrome version 41 and up can U2F
2934 return 1
2935 if $self->chrome
2936 && $self->browser_major
2937 && $self->browser_major >= 41;
2938
2939 # Opera versions 40 and >= 42 can U2F
2940 return 1
2941 if $self->opera
2942 && $self->browser_major
2943 && ( $self->browser_major == 40
2944 || $self->browser_major >= 42 );
2945
2946 return undef;
2947 }
2948
29292949 # These method are only used by the test suite.
29302950 sub _all_tests {
29312951 return @ALL_TESTS;
29592979
29602980 =head1 VERSION
29612981
2962 version 3.21
2982 version 3.23
29632983
29642984 =head1 SYNOPSIS
29652985
29933013 print "MSIE\n" if $ua->ie;
29943014 print "Mobile\n" if $ua->mobile;
29953015 if ( $ua->browser_major(4) ) {
2996 if ( $ua->browser_minor() > .5 ) {
3016 if ( $ua->browser_minor > .5 ) {
29973017 # ...;
29983018 }
29993019 }
3000 if ( $ua->browser_version() > 4.5 ) {
3020 if ( $ua->browser_version > 4.5 ) {
30013021 # ...;
30023022 }
30033023
35403560 been removed; please use HTTP::BrowserDetect->new() to pass the user
35413561 agent string.
35423562
3563 =head2 u2f()
3564
3565 Returns true if this browser and version are known to support Universal Second
3566 Factor (U2F). This method will need future updates as more browsers fully
3567 support this standard.
3568
35433569 =head2 country()
35443570
35453571 Returns the country string as it may be found in the user agent string. This
38323858
38333859 =head1 COPYRIGHT AND LICENSE
38343860
3835 This software is copyright (c) 2017 by Lee Semel.
3861 This software is copyright (c) 2019 by Lee Semel.
38363862
38373863 This is free software; you can redistribute it and/or modify it under
38383864 the same terms as the Perl 5 programming language system itself.
1818 'Parallel::ForkManager' => '1.19',
1919 'Perl::Critic' => '1.132',
2020 'Perl::Tidy' => '20180220',
21 'Pod::Wordlist' => '0',
2122 'Test::CPAN::Changes' => '0.19',
2223 'Test::Code::TidyAll' => '0.50',
2324 'Test::More' => '0.96',
2425 'Test::Pod' => '1.41',
26 'Test::Spelling' => '0.12',
2527 'Test::Synopsis' => '0',
2628 'Test::Vars' => '0.014'
2729 }
0 #!/usr/bin/env perl
1
2 use strict;
3 use warnings;
4
5 use HTTP::BrowserDetect ();
6 use Test::FailWarnings;
7 use Test::More;
8
9 ok( my $ua = HTTP::BrowserDetect->new(undef), q{undef produces no warnings} );
10
11 subtest 'no warnings on fake MSIE' => sub {
12 my $ua = HTTP::BrowserDetect->new(
13 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/F3E)');
14 is( $ua->engine_version, undef, 'undef browser_version' );
15 is( $ua->engine_major, undef, 'undef engine_major' );
16 is( $ua->engine_minor, undef, 'undef engine_minor' );
17 is( $ua->engine_beta, undef, 'undef engine_beta' );
18 };
19
20 done_testing();
+0
-12
t/99_blank_ua.t less more
0 #!/usr/bin/env perl
1
2 use strict;
3 use warnings;
4
5 use HTTP::BrowserDetect;
6 use Test::More;
7 use Test::FailWarnings;
8
9 ok( my $ua = HTTP::BrowserDetect->new(undef), q{undef produces no warnings} );
10
11 done_testing();
33373337 "os_string" : "WinVista",
33383338 "robot" : null
33393339 },
3340 "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/F3E)" : {
3341 "engine_beta" : null,
3342 "engine_major" : null,
3343 "engine_minor" : null,
3344 "engine_version" : null,
3345 "match" : [
3346 "ie",
3347 "ie4up",
3348 "ie55up",
3349 "ie5up",
3350 "ie7",
3351 "trident",
3352 "win32",
3353 "windows",
3354 "winnt",
3355 "winvista"
3356 ]
3357 },
33403358 "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; HPDTDF; Tablet PC 2.0; .NET4.0C; .NET4.0E; SE 2.X MetaSr 1.0)" : {
33413359 "browser" : "ie",
33423360 "browser_major" : "7",
1078210800 "os_string" : "Mac OS X",
1078310801 "os_version" : "10.11",
1078410802 "robot" : null
10803 },
10804 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36" : {
10805 "match" : [
10806 "chrome",
10807 "mac",
10808 "macosx",
10809 "webkit"
10810 ],
10811 "u2f" : 1
1078510812 },
1078610813 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_2) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41 Safari/535.1" : {
1078710814 "browser" : "chrome",
1275212779 "win32",
1275312780 "win7",
1275412781 "safari",
12755 "webkit"
12782 "webkit",
12783 "robot",
12784 "bingbot"
1275612785 ],
1275712786 "os" : "windows",
1275812787 "os_string" : "Win7",
12759 "robot" : null
12788 "robot" : "bingbot",
12789 "robot_name" : "Bingbot"
1276012790 },
1276112791 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML like Gecko) Chrome/13.0.782.112 Safari/535.1" : {
1276212792 "browser" : "chrome",
1839718427 "os_version" : "4.2",
1839818428 "robot" : null
1839918429 },
18430 "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) GSA/65.0.225212226 Mobile/14F89 Safari/6" : {
18431 "browser_major" : null,
18432 "browser_minor" : null,
18433 "browser_version" : null,
18434 "match" : [
18435 "device",
18436 "ios",
18437 "iphone",
18438 "mobile",
18439 "safari",
18440 "webkit"
18441 ]
18442 },
1840018443 "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/10 Mobile/16A366 Safari/605.1.15 GAYL/2.0.8b1" : {
1840118444 "browser_major" : 10,
1840218445 "browser_minor" : null,
2031820361 "robot_major" : "1",
2031920362 "robot_minor" : ".8",
2032020363 "robot_name" : "Apache Nutch",
20321 "robot_version" : "1.8"
20364 "robot_version" : "1.8",
20365 "u2f" : null
2032220366 },
2032320367 "visionutils/0.2" : {
2032420368 "browser_major" : 0,
0 use strict;
1 use warnings;
2 use Test::More;
3
4 # generated by Dist::Zilla::Plugin::Test::PodSpelling 2.007005
5 use Test::Spelling 0.12;
6 use Pod::Wordlist;
7
8
9 add_stopwords(<DATA>);
10 all_pod_files_spelling_ok( qw( bin lib ) );
11 __DATA__
12 Alders
13 Alders'
14 Alexandr
15 Alexey
16 Andrew
17 AnnoCPAN
18 Anwar
19 Aran
20 Atsushi
21 Balakrishnan
22 Barr
23 Bilodeau
24 Blake
25 BrowserDetect
26 Cebrin
27 Christopher
28 Ciornii
29 Daniel
30 David
31 Deltac
32 Douglas
33 Doye
34 Findlay
35 Firebird
36 Florian
37 Fontani
38 Graham
39 HTTP
40 Hao
41 Heiko
42 Iceweasel
43 Ihnen
44 James
45 Jensen
46 Jon
47 KHTML
48 Kato
49 Kimball
50 Kollar
51 Kurihara
52 Latypoff
53 Lee
54 MFONTANI
55 Marco
56 Maros
57 McGregor
58 Mohammad
59 Moise
60 Nicolas
61 Oatis
62 Olaf
63 Olivier
64 Paul
65 Pelzer
66 Perlover
67 Peter
68 Purkis
69 Ramanan
70 Rask
71 RealPlayer
72 Rifkin
73 Ritter
74 Robin
75 Ronald
76 Semel
77 Smidsrod
78 Smidsrød
79 Sorcinelli
80 Stadie
81 Surikov
82 Thom
83 UserAgent
84 Uwe
85 Voelker
86 WAP
87 Walsham
88 Waters
89 WebKit
90 Wilson
91 WinNT
92 Wu
93 Yoshiki
94 adm
95 ahrefs
96 alexchorny
97 altavista
98 andrew
99 aol
100 apache
101 applecoremedia
102 askjeeves
103 audrey
104 avantgo
105 baidu
106 ben
107 bingbot
108 bluefeet
109 browsex
110 cho45
111 current
112 dalvik
113 daniel
114 davidihnen
115 doug
116 ds
117 dsi
118 elinks
119 facebook
120 firefox
121 frank
122 galeon
123 gbarr
124 getright
125 golib
126 googleadsbot
127 googleadsense
128 googlebot
129 googlebotimage
130 googlebotnews
131 googlebotvideo
132 googlefavicon
133 googlemobile
134 gregor
135 hengst
136 herrmann
137 hwu
138 icab
139 ie
140 indy
141 info
142 infoseek
143 iopener
144 ios
145 ipad
146 iphone
147 ipod
148 ipsagent
149 james
150 joatis
151 joatis3
152 jon
153 khtml
154 kindlefire
155 konqueror
156 ktat
157 lee
158 lib
159 linkchecker
160 linkexchange
161 lotusnotes
162 lsaunders
163 lycos
164 macosx
165 macppc
166 maintainer
167 maros
168 merlynkline
169 mj
170 mohammad
171 mozilla
172 msn
173 msnmobile
174 msoffice
175 nav
176 navgold
177 neoplanet
178 netfront
179 netscape
180 nic
181 notbenh
182 nutch
183 obigo
184 olaf
185 olivier
186 paul
187 perlover
188 phplib
189 polaris
190 ps
191 psp
192 pubsub
193 puf
194 ramanan90
195 realplayer
196 reneeb
197 rkimball
198 robin
199 rubylib
200 seamonkey
201 specialarchiver
202 staroffice
203 surikov
204 thom
205 ucbrowser
206 userAgent
207 uwe
208 viacheslav
209 vti
210 wap
211 webkit
212 webos
213 webtv
214 wget
215 winnt
216 winphone
217 yandex
218 yandexbot
219 yandeximages
220 yeahoffline