From e21cee47ced69277073d3d2395e8a7cb64e71c14 Mon Sep 17 00:00:00 2001 From: Gervase Markham Date: Wed, 27 Nov 2013 18:02:11 +0000 Subject: Bug 938596 - Add hook for modifying HTTP headers. r=LpSolit. --- Bugzilla/CGI.pm | 28 +++++++++++++++++++--------- Bugzilla/Hook.pm | 27 +++++++++++++++++++++++++++ extensions/Example/Extension.pm | 7 +++++++ 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm index 05863bf02..c7997ba18 100644 --- a/Bugzilla/CGI.pm +++ b/Bugzilla/CGI.pm @@ -15,6 +15,7 @@ use parent qw(CGI); use Bugzilla::Constants; use Bugzilla::Error; use Bugzilla::Util; +use Bugzilla::Hook; use Bugzilla::Search::Recent; use File::Basename; @@ -275,19 +276,23 @@ sub multipart_start { sub header { my $self = shift; + my %headers; + # If there's only one parameter, then it's a Content-Type. if (scalar(@_) == 1) { - # Since we're adding parameters below, we have to name it. - unshift(@_, '-type' => shift(@_)); + %headers = ('-type' => shift(@_)); + } + else { + %headers = @_; } if ($self->{'_content_disp'}) { - unshift(@_, '-content_disposition' => $self->{'_content_disp'}); + $headers{'-content_disposition'} = $self->{'_content_disp'}; } # Add the cookies in if we have any if (scalar(@{$self->{Bugzilla_cookie_list}})) { - unshift(@_, '-cookie' => $self->{Bugzilla_cookie_list}); + $headers{'-cookie'} = $self->{Bugzilla_cookie_list}; } # Add Strict-Transport-Security (STS) header if this response @@ -301,24 +306,29 @@ sub header { { $sts_opts .= '; includeSubDomains'; } - unshift(@_, '-strict_transport_security' => $sts_opts); + + $headers{'-strict_transport_security'} = $sts_opts; } # Add X-Frame-Options header to prevent framing and subsequent # possible clickjacking problems. unless ($self->url_is_attachment_base) { - unshift(@_, '-x_frame_options' => 'SAMEORIGIN'); + $headers{'-x_frame_options'} = 'SAMEORIGIN'; } # Add X-XSS-Protection header to prevent simple XSS attacks # and enforce the blocking (rather than the rewriting) mode. - unshift(@_, '-x_xss_protection' => '1; mode=block'); + $headers{'-x_xss_protection'} = '1; mode=block'; # Add X-Content-Type-Options header to prevent browsers sniffing # the MIME type away from the declared Content-Type. - unshift(@_, '-x_content_type_options' => 'nosniff'); + $headers{'-x_content_type_options'} = 'nosniff'; + + Bugzilla::Hook::process('cgi_headers', + { cgi => $self, headers => \%headers } + ); - return $self->SUPER::header(@_) || ""; + return $self->SUPER::header(%headers) || ""; } sub param { diff --git a/Bugzilla/Hook.pm b/Bugzilla/Hook.pm index 4c8933b16..e6a0ba283 100644 --- a/Bugzilla/Hook.pm +++ b/Bugzilla/Hook.pm @@ -641,6 +641,33 @@ spaces. =back +=head2 cgi_headers + +This allows you to modify the HTTP headers sent out on every Bugzilla +response. + +Params: + +=over + +=item C + +A hashref, where the keys are header names and the values are header +values. Keys need to be lower-case, and begin with a "-". If you use +the "_" character it will be converted to "-", and the library will +also fix the casing to Camel-Case. + +You can delete (some) headers that Bugzilla adds by deleting entries +from the hash. + +=item C + +The CGI object, which may tell you useful things about the response on +which to base a decision of whether or not to add a header. + +=back + + =head2 config_add_panels If you want to add new panels to the Parameters administrative interface, diff --git a/extensions/Example/Extension.pm b/extensions/Example/Extension.pm index c0015803e..7e77b03f7 100644 --- a/extensions/Example/Extension.pm +++ b/extensions/Example/Extension.pm @@ -336,6 +336,13 @@ sub bugmail_relationships { $relationships->{+REL_EXAMPLE} = 'Example'; } +sub cgi_headers { + my ($self, $args) = @_; + my $headers = $args->{'headers'}; + + $headers->{'-x_test_header'} = "Test header from Example extension"; +} + sub config_add_panels { my ($self, $args) = @_; -- cgit v1.2.3-24-g4f1b