File Coverage

blib/lib/Dancer2/Plugin/Cache/CHI.pm
Criterion Covered Total %
statement 52 55 94.5
branch 11 14 78.5
condition 4 7 57.1
subroutine 14 15 93.3
pod n/a
total 81 91 89.0


line stmt bran cond sub pod time code
1             package Dancer2::Plugin::Cache::CHI;
2             our $AUTHORITY = 'cpan:YANICK';
3             # ABSTRACT: Dancer plugin to cache response content (and anything else)
4             $Dancer2::Plugin::Cache::CHI::VERSION = '1.7.0';
5 6     6   2620758 use strict;
  6         30  
  6         152  
6 6     6   29 use warnings;
  6         10  
  6         172  
7 6     6   29 use Carp;
  6         11  
  6         438  
8 6     6   5099 use CHI;
  6         247499  
  6         201  
9              
10 6     6   56 use Dancer2 0.162000;
  6         55  
  6         151  
11              
12 6     6   72077 use Dancer2::Plugin;
  6         13794  
  6         38  
13              
14             register_hook 'before_create_cache';
15              
16              
17             my %cache;
18             my $cache_page; # actually hold the ref to the args
19             my $cache_page_key_generator = sub {
20             return $_[0]->request->path;
21             };
22              
23             on_plugin_import {
24             my $dsl = shift;
25              
26             $dsl->app->add_hook(
27             Dancer2::Core::Hook->new(
28             name => 'after',
29             code => sub {
30             return unless $cache_page;
31              
32             my $resp = shift;
33             cache($dsl)->set( $cache_page_key_generator->($dsl),
34             {
35             status => $resp->status,
36             headers => $resp->headers_to_array,
37             content => $resp->content
38             },
39             @$cache_page,
40             );
41              
42             $cache_page = undef;
43             }
44             ));
45             };
46              
47             register cache => sub {
48 60     60   111781 my $dsl = shift;
49 60   50     612 return $cache{$_[0]//''} ||= _create_cache( $dsl, @_ );
      66        
50             };
51              
52             my $honor_no_cache = 0;
53              
54             sub _create_cache {
55 5     5   13 my $dsl = shift;
56 5         12 my $namespace = shift;
57 5   50     48 my $args = shift || {};
58              
59 5         101 $dsl->execute_hook( 'before_create_cache' );
60              
61             my %setting = %{
62 5 50       644 $dsl->dancer_app->config->{plugins}{'Cache::CHI'} || {}
  5         44  
63             };
64              
65 5 50       222 $setting{namespace} = $namespace if defined $namespace;
66              
67 5         32 while( my ( $k, $v ) = each %$args ) {
68 0         0 $setting{$k} = $v;
69             }
70              
71             $honor_no_cache = delete $setting{honor_no_cache}
72 5 100       29 if exists $setting{honor_no_cache};
73              
74 5         55 return CHI->new(%setting);
75             }
76              
77              
78              
79             register check_page_cache => sub {
80 4     4   4754 my $dsl = shift;
81              
82             my $hook = sub {
83 33     33   2447469 my $context = shift;
84              
85             # Instead halt() now we use a more correct method - setting of a
86             # response to Dancer2::Core::Response object for a more correct returning of
87             # some HTTP headers (X-Powered-By, Server)
88              
89 33 100       111 my $cached = cache($dsl)->get( $cache_page_key_generator->($dsl) )
90             or return;
91              
92 9 100       1346 if ( $honor_no_cache ) {
93              
94 5         14 my $req = $dsl->request;
95              
96 6     6   12269 no warnings 'uninitialized';
  6         13  
  6         1981  
97              
98             return if grep {
99             # eval is there to protect from a regression in Dancer 1.31
100             # where headers can be undef
101 5 100       17 eval { $req->header($_) eq 'no-cache' }
  10         599  
  10         26  
102             } qw/ Cache-Control Pragma /;
103             }
104              
105             $context->set_response(
106             Dancer2::Core::Response->new(
107             is_halted => 1,
108             ref $cached eq 'HASH'
109             ?
110             (
111             status => $cached->{status},
112             headers => $cached->{headers},
113             content => $cached->{content}
114             )
115 7 50       273 :
116             ( content => $cached )
117             )
118             );
119 4         34 };
120              
121 4         140 $dsl->app->add_hook( Dancer2::Core::Hook->new(
122             name => 'before',
123             code => $hook,
124             ));
125             };
126              
127              
128             register cache_page => sub {
129 13     13   10092 shift;
130              
131 13         32 my ( $content, @args ) = @_;
132              
133 13         72 $cache_page = \@args;
134              
135 13         42 return $content;
136             };
137              
138              
139              
140             register cache_page_key => sub {
141 0     0   0 shift;
142 0         0 return $cache_page_key_generator->();
143             };
144              
145              
146             register cache_page_key_generator => sub {
147 1     1   1426 shift;
148 1         3 $cache_page_key_generator = shift;
149             };
150              
151              
152             for my $method ( qw/ set get remove clear compute / ) {
153             register 'cache_'.$method => sub {
154 11     11   117833 my $dsl = shift;
155 11         22 return cache($dsl)->$method( @_ );
156             }
157             }
158              
159              
160             register_plugin for_versions => [1,2];
161              
162             1;
163              
164             __END__