summaryrefslogtreecommitdiffstats
path: root/index.cgi
diff options
context:
space:
mode:
authorDylan William Hardison <dylan@hardison.net>2017-03-28 03:05:10 +0200
committerDylan William Hardison <dylan@hardison.net>2017-04-04 03:43:30 +0200
commit9f9e989704b5274afba6a1de0b7bdcc6e7296314 (patch)
tree01cc75a06bfb6cf60960fa72de90ad1084a6dfdb /index.cgi
parent30c35b3aefc582e1bb123b309f9c4971c04094ee (diff)
downloadbugzilla-9f9e989704b5274afba6a1de0b7bdcc6e7296314.tar.gz
bugzilla-9f9e989704b5274afba6a1de0b7bdcc6e7296314.tar.xz
Bug 1350909 - Make index.cgi cache-friendly for logged out requests
Diffstat (limited to 'index.cgi')
-rwxr-xr-xindex.cgi67
1 files changed, 48 insertions, 19 deletions
diff --git a/index.cgi b/index.cgi
index 56513aff7..420a162b6 100755
--- a/index.cgi
+++ b/index.cgi
@@ -16,43 +16,72 @@ use Bugzilla;
use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::Update;
+use Digest::MD5 qw(md5_hex);
+use List::MoreUtils qw(any);
# Check whether or not the user is logged in
my $user = Bugzilla->login(LOGIN_OPTIONAL);
my $cgi = Bugzilla->cgi;
-my $template = Bugzilla->template;
my $vars = {};
+# Yes, I really want to avoid two calls to the id method.
+my $user_id = $user->id;
+
+# We only cache unauthenticated requests now, because invalidating is harder for logged in users.
+my $can_cache = $user_id == 0;
+
# And log out the user if requested. We do this first so that nothing
# else accidentally relies on the current login.
if ($cgi->param('logout')) {
Bugzilla->logout();
$user = Bugzilla->user;
+ $user_id = 0;
+ $can_cache = 0;
$vars->{'message'} = "logged_out";
# Make sure that templates or other code doesn't get confused about this.
$cgi->delete('logout');
}
-$cgi->content_security_policy(script_src => ['self', 'nonce']);
+# our weak etag is based on the bugzilla version parameter (BMO customization) and the announcehtml
+# if either change, the cache will be considered invalid.
+my @etag_parts = (Bugzilla->params->{bugzilla_version}, Bugzilla->params->{announcehtml});
+my $weak_etag = q{W/"} . md5_hex(@etag_parts) . q{"};
+my $if_none_match = $cgi->http('If-None-Match');
+
+# load balancer (or client) will check back with us after max-age seconds
+# If the etag in If-None-Match is unchanged, we quickly respond without doing much work.
+my @cache_control = (
+ $can_cache ? 'public' : 'no-cache',
+ sprintf('max-age=%d', 60 * 5),
+);
-###############################################################################
-# Main Body Execution
-###############################################################################
+if ($can_cache && $if_none_match && any { $_ eq $weak_etag } split(/,\s*/, $if_none_match)) {
+ print $cgi->header(-status => '304 Not Modified', -ETag => $weak_etag);
+}
+else {
+ my $template = Bugzilla->template;
+ $cgi->content_security_policy(script_src => ['self']);
-# Return the appropriate HTTP response headers.
-print $cgi->header();
+ # Return the appropriate HTTP response headers.
+ print $cgi->header(
+ -Cache_Control => join(', ', @cache_control),
+ $can_cache ? (-ETag => $weak_etag) : (),
+ );
-if ($user->in_group('admin')) {
- # If 'urlbase' is not set, display the Welcome page.
- unless (Bugzilla->params->{'urlbase'}) {
- $template->process('welcome-admin.html.tmpl')
- || ThrowTemplateError($template->error());
- exit;
+ if ($user_id && $user->in_group('admin')) {
+ # If 'urlbase' is not set, display the Welcome page.
+ unless (Bugzilla->params->{'urlbase'}) {
+ $template->process('welcome-admin.html.tmpl')
+ or ThrowTemplateError($template->error());
+ exit;
+ }
+ # Inform the administrator about new releases, if any.
+ $vars->{'release'} = Bugzilla::Update::get_notifications();
}
- # Inform the administrator about new releases, if any.
- $vars->{'release'} = Bugzilla::Update::get_notifications();
-}
-# Generate and return the UI (HTML page) from the appropriate template.
-$template->process("index.html.tmpl", $vars)
- || ThrowTemplateError($template->error());
+ $vars->{use_login_page} = 1;
+
+ # Generate and return the UI (HTML page) from the appropriate template.
+ $template->process("index.html.tmpl", $vars)
+ or ThrowTemplateError( $template->error() );
+} \ No newline at end of file