File Coverage

blib/lib/Apache/CacheContent.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Apache::CacheContent;
2              
3 1     1   566 use strict;
  1         1  
  1         48  
4              
5             $Apache::CacheContent::VERSION = '0.12';
6             @Apache::CacheContent::ISA = qw(Apache);
7              
8 1     1   1452 use Apache;
  0            
  0            
9             use Apache::Constants qw(OK SERVER_ERROR DECLINED);
10             use Apache::File ();
11             use Apache::Log ();
12              
13             sub disk_cache ($$) {
14             my ($self, $r) = @_;
15              
16             my $log = $r->server->log;
17             my $file = $r->filename;
18              
19             # Convert configured minutes to days for -M test.
20             my $timeout = $self->ttl($r) / (24*60);
21              
22             # Test age of file.
23             if (-f $r->finfo && -M _ < $timeout) {
24             $log->info("using cache file '$file'");
25             return DECLINED;
26             }
27              
28             # No old file to use, so make a new one.
29             $log->info("generating '$file'");
30              
31             # First, create a request object from our Capture class below.
32             my $fake_r = Apache::CacheContent::Capture->new($r);
33              
34             # Call the handler() subroutine of the subclass,
35             # but pass it the fake $r so that we get the content back.
36             $self->handler($fake_r);
37              
38             # Now, write the content from handler() to a file on disk.
39             my $fh = Apache::File->new(">$file");
40              
41             unless ($fh) {
42             $log->error("Cannot open '$file': $!");
43             return SERVER_ERROR;
44             }
45              
46             # Dump the content.
47             print $fh $fake_r->data();
48              
49             # We need to call close() explicitly here or else
50             # the Content-Length header does not get set properly.
51             $fh->close;
52              
53             # Finally, reset the filename to point to the newly
54             # generated file and let Apache's default handler send it.
55             $r->filename($file);
56              
57             return OK;
58             }
59              
60             sub ttl {
61             # Get the cache time in minutes.
62             # Default to 1 hour.
63              
64             return shift->dir_config('CacheTTL') || 60;
65             }
66              
67             sub handler {
68              
69             my ($self, $r) = @_;
70              
71             $r->send_http_header('text/html'); # ignored...
72              
73             $r->print(" --- non-subclassed request --- ");
74             }
75              
76             # Package that capture's handler output and stash it away.
77              
78             package Apache::CacheContent::Capture;
79              
80             @Apache::CacheContent::Capture::ISA = qw(Apache);
81              
82             sub new {
83             my ($class, $r) = @_;
84              
85             $r ||= Apache->request;
86              
87             tie *STDOUT, $class, $r;
88              
89             return tied *STDOUT;
90             }
91              
92             sub print {
93             # Intercept print so we can stash the data.
94              
95             shift->{_data} .= join('', @_);
96             }
97              
98             sub data {
99             # Return stashed data.
100              
101             return shift->{_data};
102             }
103              
104             sub send_http_header {
105             # no-op - don't send headers from a PerlFixupHandler.
106             };
107              
108             # Capture regular print statements.
109              
110             sub TIEHANDLE {
111             my ($class, $r) = @_;
112              
113             return bless { _r => $r,
114             _data => undef
115             }, $class;
116             }
117              
118             sub PRINT {
119             shift->print(@_);
120             }
121              
122             1;
123              
124             __END__