#!/usr/bin/perl -w
use strict;
# Configuration (during development only):
my $verbose = 1;
# Configuration:
### This section would be part of the plugin's configuration.
### So, e.g., $push_images would become $Foswiki::cfg{PageOptimizerPlugin}{PushImages}.
# Only push elements that reside in certain paths, e.g. /pub/System/.
# Regular expression, empty string means "no restriction".
my $path_restriction = 'boring|\.gif';
# Push only files up to maximum size.
# Zero means "unlimited". Negative values mean "don't push at all".
my $max_single_filesize = 20480;
# Limit the total aggregated size of all pushed files.
# Zero means "unlimited". Negative values mean "don't push at all".
my $max_aggregated_filesize = 102400;
# If $max_aggregated_filesize is positive, we might want to push small files
# first, since that would allow for pushing many of them whereas otherwise
# one big file might use the entire budget. Boolean
my $small_files_first = 1;
# More boolean parameters
my $push_images = 1;
my $push_javascript = 1;
my $push_stylesheets = 1;
my $push_other_data = 1;
# HTML code to be parsed:
my $text = "
bla blubb
";
# Helper function:
sub vprint { print join(' ',@_) if $verbose; }
# Go!
&vprint("\n\n\n");
if ($max_single_filesize >= 0 and $max_aggregated_filesize >= 0) {
my $aggregated_filesize = 0;
my $dont_care = (($max_single_filesize == 0) and ($max_aggregated_filesize == 0) and (!$small_files_first));
sub check_filesize {
# There's no need to write "return 0 if $max_single_filesize < 0" here:
# If $max_single_filesize is negative, this function will never be called.
# However, we need to check the file size even if $max_single_filesize is 0
# because the files may still exceed the $max_aggregated_filesize limit.
if ($dont_care) {
&vprint("# carelessly pushing all files.\n");
return [1, -1];
}
### In the real foswiki plugin, we'll have to preprocess the path before running stat():
my @stat;
unless (@stat = stat($_[0])) {
&vprint("# File <$_[0]> not found.\n");
return [0, -1]; # Don't push a file if you can't even stat() it.
}
my $filesize = $stat[7];
if (($max_single_filesize > 0) and ($filesize > $max_single_filesize)) {
&vprint("# File $filesize exceeds the maximum filesize $max_single_filesize. No push.\n");
return [0, -1];
}
if (($max_aggregated_filesize > 0) and ($filesize+$aggregated_filesize > $max_aggregated_filesize)) {
&vprint("# Not pushing this $filesize byte file: That would exceed max.aggr.filesize of $max_aggregated_filesize.\n");
return [0, -1];
}
else {
$aggregated_filesize += $filesize;
&vprint("# Filesize $filesize is <= $max_single_filesize and aggr.filesize",
" $aggregated_filesize is <= $max_aggregated_filesize. Push!\n");
return [1, $filesize];
}
}
my @filetuplelist;
sub possibly_push {
# Arguments: filename, bool_from_config
my $file_to_push = $_[0];
unless ($_[1]) {
&vprint("# $file_to_push: Not pushing this kind of file.\n");
return unless $_[1];
}
my ($filesize_is_okay, $filesize) = @{&check_filesize($file_to_push)};
&vprint("# filesize_is_okay=<$filesize_is_okay> filesize=<$filesize> file_to_push=<$file_to_push>\n");
unless ($filesize_is_okay) {
&vprint("# $file_to_push: Unattractive file size.\n");
return;
}
### TODO:
### - return if the referenced element is not on the local server
### - Replace relative paths with absolute paths
unless ($path_restriction eq '' or $file_to_push =~ /$path_restriction/) {
&vprint("Path <$file_to_push> does not match path restriction <$path_restriction>\n");
return;
}
if ($small_files_first) {
&vprint("# Queueing $filesize byte file $file_to_push for push.\n");
push @filetuplelist, [$filesize, $file_to_push];
}
else {
&vprint("# Pushing $filesize byte file $file_to_push right now.\n");
&push_it_now($file_to_push);
}
}
sub push_it_now {
my $file_to_push = $_[0];
print "$file_to_push\n";
### H2PushResource is said to speed up things more than "Link ..." does.
#$response->pushHeader('H2PushResource', $_);
#$response->pushHeader('Link', "<$_>; rel=preload; as=$type" );
}
### Maybe we should have a stricter regexp here, e.g. script only with either
### language="javascript" or no language, or link only with rel="stylesheet", ...
### Note that "rel=" and "language=" can occur either before or after "src=".
while ($text =~ /(]*src=|