File Coverage

blib/lib/VT/API.pm
Criterion Covered Total %
statement 15 56 26.7
branch 0 28 0.0
condition 0 4 0.0
subroutine 5 13 38.4
pod 7 7 100.0
total 27 108 25.0


line stmt bran cond sub pod time code
1             package VT::API;
2 1     1   26098 use strict;
  1         3  
  1         45  
3 1     1   8 use Carp;
  1         2  
  1         83  
4            
5 1     1   1929 use JSON;
  1         19644  
  1         6  
6 1     1   2916 use HTTP::Request::Common;
  1         93169  
  1         178  
7 1     1   12769 use LWP::UserAgent;
  1         62316  
  1         858  
8            
9             our $VERSION = '0.12';
10            
11             sub new {
12 0 0   0 1   croak('Options to VT::API should be key/value pairs, '.
13             'not HASH reference') if ref($_[1]) eq 'HASH';
14            
15 0           my ($class, %opts) = @_;
16 0           my $self = {};
17            
18             # Public Key.
19 0 0         $self->{key} = $opts{key} or
20             croak('You should specify public API key');
21            
22             # LWP::UserAgent Object.
23 0   0       $self->{ua} = LWP::UserAgent->new(
      0        
24             agent => $opts{agent} || 'Perl/VT-API',
25             timeout => $opts{timeout} || 180,
26             );
27            
28 0           return bless $self, $class;
29             }
30            
31            
32             sub get_file_report {
33 0     0 1   my ($self, $resource) = @_;
34            
35 0 0         croak('You have not specified a resource (md5/sha1/sha256 or permalink '.
36             'identifier') if !defined $resource;
37            
38 0           $self->{res} = $self->{ua}->request(
39             POST 'https://www.virustotal.com/api/get_file_report.json', [
40             resource => $resource,
41             key => $self->{key},
42             ],
43             );
44            
45 0           return $self->_parse_json();
46             }
47            
48            
49             sub scan_file {
50 0     0 1   my ($self, $file) = @_;
51            
52 0 0         croak('You have not specified a file') if !defined $file;
53            
54 0           $self->{res} = $self->{ua}->request(
55             POST 'https://www.virustotal.com/api/scan_file.json',
56             Content_Type => 'form-data',
57             Content => [
58             file => [$file],
59             key => $self->{key},
60             ],
61             );
62            
63 0           return $self->_parse_json();
64             }
65            
66            
67             sub get_url_report {
68 0     0 1   my ($self, $resource) = @_;
69            
70 0 0         croak('You have not specified a resource (URL or permalink '.
71             'identifier') if !defined $resource;
72            
73 0           $self->{res} = $self->{ua}->request(
74             POST 'https://www.virustotal.com/api/get_url_report.json', [
75             resource => $resource,
76             key => $self->{key},
77             ],
78             );
79            
80 0           return $self->_parse_json();
81             }
82            
83            
84             sub scan_url {
85 0     0 1   my ($self, $url) = @_;
86            
87 0 0         croak('You have not specified a URL that should be '.
88             'scanned') if !defined $url;
89            
90 0           $self->{res} = $self->{ua}->request(
91             POST 'https://www.virustotal.com/api/scan_url.json', [
92             url => $url,
93             key => $self->{key},
94             ],
95             );
96            
97 0           return $self->_parse_json();
98             }
99            
100            
101             sub make_comment {
102 0     0 1   my ($self, $file_or_url, $comment, $tags) = @_;
103            
104 0 0         croak('You have not specified a file (md5/sha1/sha256 hash) or URL')
105             if !defined $file_or_url;
106 0 0         croak('You have not specified a comment')
107             if !defined $comment;
108            
109 0 0         $self->{res} = $self->{ua}->request(
    0          
    0          
110             POST 'https://www.virustotal.com/api/make_comment.json', [
111             ($file_or_url =~ /^https?:\/\//) ?
112             (url => $file_or_url) :
113             (file => $file_or_url),
114            
115             (comment => $comment),
116            
117             (defined $tags) ?
118             (tags => (ref($tags) eq 'ARRAY' ? join(',', @$tags) : $tags)) :
119             (),
120            
121             (key => $self->{key}),
122             ],
123             );
124            
125 0           return $self->_parse_json();
126             }
127            
128            
129             sub _parse_json {
130 0     0     my ($self) = @_;
131 0 0         return if !defined $self->{res};
132            
133 0           my $parsed;
134 0 0         if ($self->{res}->is_success()) {
135 0           undef $self->{errstr};
136            
137 0           eval { $parsed = from_json($self->{res}->content()) };
  0            
138 0 0         if ($@) {
139 0           $@ =~ s/ at .*//;
140 0           $self->{errstr} = $@;
141             }
142             }
143             else {
144 0           $self->{errstr} = $self->{res}->status_line;
145             }
146            
147 0           return $parsed;
148             }
149            
150            
151             sub errstr {
152 0     0 1   my ($self) = @_;
153 0           return $self->{errstr};
154             }
155            
156            
157             1;
158             __END__