diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index 2884baf73..b464d2617 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -2,6 +2,7 @@ - fixed #11250: i18n Asset_EMSSubmissionForm::delete created items label help - fixed #11251: perload.perl tries to load t/lib/WebGUI/Test.pm - fixed #11249: Recaptcha https bug + - fixed #11200: Navigation in AssetProxy cached in browser 7.8.5 - added the EMS submission subsystem diff --git a/docs/upgrades/upgrade_7.8.5-7.8.6.pl b/docs/upgrades/upgrade_7.8.5-7.8.6.pl index c75bf482d..1c3374a44 100644 --- a/docs/upgrades/upgrade_7.8.5-7.8.6.pl +++ b/docs/upgrades/upgrade_7.8.5-7.8.6.pl @@ -31,6 +31,7 @@ my $quiet; # this line required my $session = start(); # this line required # upgrade functions go here +addMaxCacheOverrideSetting($session); finish($session); # this line required @@ -44,6 +45,16 @@ finish($session); # this line required # print "DONE!\n" unless $quiet; #} +#---------------------------------------------------------------------------- +# Describe what our function does +sub addMaxCacheOverrideSetting { + my $session = shift; + print "\tAdding maximum cache timeout setting... " unless $quiet; + # and here's our code + $session->setting->add('maxCacheTimeout', 86400) unless $session->setting->has('maxCacheTimeout'); + print "DONE!\n" unless $quiet; +} + # -------------- DO NOT EDIT BELOW THIS LINE -------------------------------- diff --git a/lib/WebGUI/Content/Asset.pm b/lib/WebGUI/Content/Asset.pm index 1993e3052..e938e239c 100644 --- a/lib/WebGUI/Content/Asset.pm +++ b/lib/WebGUI/Content/Asset.pm @@ -112,7 +112,9 @@ sub handler { my $asset = getAsset($session, getRequestedAssetUrl($session)); # display from cache if page hasn't been modified. - if ($var->get("userId") eq "1" && defined $asset && !$http->ifModifiedSince($asset->getContentLastModified)) { + if ($var->get("userId") eq "1" + && defined $asset + && !$http->ifModifiedSince($asset->getContentLastModified, $session->setting->get('maxCacheTimeout'))) { $http->setStatus("304","Content Not Modified"); $http->sendHeader; $session->close; diff --git a/lib/WebGUI/Operation/Settings.pm b/lib/WebGUI/Operation/Settings.pm index 04f909f92..910772929 100644 --- a/lib/WebGUI/Operation/Settings.pm +++ b/lib/WebGUI/Operation/Settings.pm @@ -204,6 +204,14 @@ sub definition { hoverHelp=>$i18n->get("Enable Metadata description"), defaultValue=>$setting->get("metaDataEnabled") }); + push(@fields, { + tab=>"content", + fieldType=>"interval", + name=>"maxCacheTimeout", + label=>$i18n->get("Maximum cache timeout"), + hoverHelp=>$i18n->get("Maximum cache timeout description"), + defaultValue=>$setting->get("maxCacheTimeout") + }); # user interface settings push(@fields, { tab=>"ui", diff --git a/lib/WebGUI/Session/Http.pm b/lib/WebGUI/Session/Http.pm index 67b65678d..68349d2e3 100644 --- a/lib/WebGUI/Session/Http.pm +++ b/lib/WebGUI/Session/Http.pm @@ -205,19 +205,36 @@ sub getStreamedFile { #------------------------------------------------------------------- -=head2 ifModifiedSince ( epoch ) +=head2 ifModifiedSince ( epoch [, maxCacheTimeout] ) Returns 1 if the epoch is greater than the modified date check. +=head3 epoch + +The date that the requested content was last modified in epoch format. + +=head3 maxCacheTimeout + +A modifier to the epoch, that allows us to set a maximum timeout where content will appear to +have changed and a new page request will be allowed to be processed. + =cut sub ifModifiedSince { - my $self = shift; - my $epoch = shift; + my $self = shift; + my $epoch = shift; + my $maxCacheTimeout = shift; require APR::Date; my $modified = $self->session->request->headers_in->{'If-Modified-Since'}; return 1 if ($modified eq ""); $modified = APR::Date::parse_http($modified); + ##Implement a step function that increments the epoch time in integer multiples of + ##the maximum cache time. Used to handle the case where layouts containing macros + ##(like assetproxied Navigations) can be periodically updated. + if ($maxCacheTimeout) { + my $delta = time() - $epoch; + $epoch += $delta - ($delta % $maxCacheTimeout); + } return ($epoch > $modified); } diff --git a/lib/WebGUI/i18n/English/WebGUI.pm b/lib/WebGUI/i18n/English/WebGUI.pm index e8278847c..b18136427 100644 --- a/lib/WebGUI/i18n/English/WebGUI.pm +++ b/lib/WebGUI/i18n/English/WebGUI.pm @@ -4660,6 +4660,16 @@ Users may override this setting in their profile. lastUpdated => 0, }, + 'Maximum cache timeout' => { + message => 'Maximum cache timeout', + lastUpdated => 0, + }, + + 'Maximum cache timeout description' => { + message => 'This timeout will override the content check that is done before generating a page. It can help with caching problems for macros and Navigations. Setting it to 0 will disable the timeout. A setting of several hours is recommended.', + lastUpdated => 0, + }, + }; 1; diff --git a/t/Session/Http.t b/t/Session/Http.t index f38cbbb51..2ee64ea5d 100644 --- a/t/Session/Http.t +++ b/t/Session/Http.t @@ -23,9 +23,7 @@ use Data::Dumper; use Test::More; # increment this value for each test you create use Test::Deep; -my $num_tests = 53; - -plan tests => $num_tests; +plan tests => 57; my $session = WebGUI::Test->session; @@ -401,6 +399,22 @@ is_deeply( $session->user({userId => 1}); +#################################################### +# +# ifModifiedSince +# +#################################################### +##Clear request object to run a new set of requests +$request = WebGUI::PseudoRequest->new(); +$session->{_request} = $request; +$request->headers_in->{'If-Modified-Since'} = ''; +ok $session->http->ifModifiedSince(0), 'ifModifiedSince: empty header always returns true'; + +$request->headers_in->{'If-Modified-Since'} = $session->datetime->epochToHttp(WebGUI::Test->webguiBirthday); +ok $session->http->ifModifiedSince(WebGUI::Test->webguiBirthday + 5), '... epoch check, true'; +ok !$session->http->ifModifiedSince(WebGUI::Test->webguiBirthday - 5), '... epoch check, false'; +ok $session->http->ifModifiedSince(WebGUI::Test->webguiBirthday - 5, 3600), '... epoch check, made true by maxCacheTimeout'; + #################################################### # # Utility functions @@ -428,7 +442,3 @@ sub deltaHttpTimes { my $dt2 = $httpParser->parse_datetime($http2); my $delta_time = $dt1-$dt2; } - - -END { -}