File Coverage

blib/lib/Plack/Middleware/Matomo.pm
Criterion Covered Total %
statement 64 68 94.1
branch 11 16 68.7
condition 3 6 50.0
subroutine 11 12 91.6
pod 1 1 100.0
total 90 103 87.3


line stmt bran cond sub pod time code
1             package Plack::Middleware::Matomo;
2              
3             our $VERSION = '0.11';
4              
5 1     1   152879 use strict;
  1         9  
  1         27  
6 1     1   5 use warnings;
  1         1  
  1         25  
7 1     1   548 use AnyEvent::HTTP;
  1         64606  
  1         89  
8 1     1   558 use Log::Any '$log';
  1         10511  
  1         6  
9 1     1   3015 use Plack::Request;
  1         90648  
  1         40  
10             use Plack::Util::Accessor
11 1     1   781 qw(apiv base_url idsite token_auth time_format oai_identifier_format view_paths download_paths ua urlref);
  1         254  
  1         7  
12 1     1   91 use URI;
  1         2  
  1         19  
13              
14 1     1   5 use parent 'Plack::Middleware';
  1         2  
  1         6  
15              
16             sub call {
17 3     3 1 35729 my ($self, $env) = @_;
18              
19 3         22 my $request = Plack::Request->new($env);
20 3         41 my $res = $self->app->($env);
21              
22             # only get requests
23 3 50       347 return $res unless $request->method =~ m{^get$}i;
24              
25 3         36 my ($action, $id);
26 3         9 my $view_paths = $self->view_paths;
27 3         17 my $download_paths = $self->download_paths;
28              
29 3         20 $log->info("Entering Matomo middleware at " . $request->path);
30              
31 3         37 foreach my $p (@$view_paths) {
32 3 100       17 if ($request->path =~ /$p/) {
33 1         20 $id = $1;
34 1         25 $action = "view";
35 1         13 last;
36             }
37             }
38 3         20 foreach my $p (@$download_paths) {
39 3 100       9 if ($request->path =~ /$p/) {
40 1         9 $id = $1;
41 1         2 $action = "download";
42 1         2 last;
43             }
44             }
45              
46 3 100       39 return $res unless $action;
47 2         11 $log->info("Action: $action");
48              
49 2   50     11 my $time_format = $self->time_format // '%Y-%m-%dT%H:%M:%SZ';
50 2         20 my $ip = $self->_anonymize_ip($request->address);
51 2         7 my $oai_id = sprintf($self->oai_identifier_format, $id);
52 2         16 my $cvar = '{"1":["oaipmhID","' . $oai_id . '"]}';
53              
54 2         6 my $rand = int(rand(10000));
55              
56 2   50     8 my $event = {
      50        
57             _id => $request->session // '',
58             action_name => $action,
59             apiv => $self->apiv // 1,
60             cvar => $cvar,
61             idsite => $self->idsite,
62             rand => $rand,
63             rec => 1,
64             token_auth => $self->token_auth,
65             url => $request->uri,
66             cip => $ip,
67             };
68              
69 2 50       689 $event->{ua} = $request->user_agent if $self->ua;
70 2 50       14 $event->{urlref} = $request->referer if $self->urlref;
71              
72 2 100       12 if ($action eq 'download') {
73 1         3 $event->{download} = $request->uri;
74             }
75              
76 2         180 $self->_push_to_matomo($event);
77              
78 2         32085 return $res;
79             }
80              
81             sub _anonymize_ip {
82 2     2   16 my ($self, $ip) = @_;
83              
84 2         13 $ip =~ s/\.\d+?$/\.0/;
85              
86 2         6 return $ip;
87             }
88              
89             sub _push_to_matomo {
90 2     2   4 my ($self, $event) = @_;
91              
92 2         7 my $uri = URI->new($self->base_url);
93 2         150 $uri->query_form($event);
94              
95 2         801 $log->debug("URL: " . $uri->as_string);
96              
97             http_head $uri->as_string, sub {
98 0     0     my ($body, $hdr) = @_;
99              
100 0 0         if ($hdr->{Status} =~ /^2/) {
101 0           $log->debug("Ok matomo endpoint: $hdr->{Status} $hdr->{Reason} for " . $uri->as_string);
102             } else {
103 0           $log->error("Could not reach matomo endpoint: $hdr->{Status} $hdr->{Reason} for " . $uri->as_string);
104             }
105 2         24 };
106             }
107              
108             1;
109              
110             __END__