[Rt-commit] rt branch, 4.2/cache-control-regression, created. rt-4.2.3-60-g915eb4b

Wallace Reis wreis at bestpractical.com
Wed Mar 26 15:35:05 EDT 2014


The branch, 4.2/cache-control-regression has been created
        at  915eb4b7d0cd113e223007e69ea5913564031e3f (commit)

- Log -----------------------------------------------------------------
commit 915eb4b7d0cd113e223007e69ea5913564031e3f
Author: Wallace Reis <wreis at bestpractical.com>
Date:   Wed Mar 26 13:54:24 2014 -0300

    I#28640: Set headers for static content
    
    This is a regression fix since at some point the static content served
    from /static/ path had the 'Expires' and 'Cache-Control' headers removed
    (probably when started serving it with Static middleware). Additionally,
    add support for static content served from custom StaticRoots.

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index af017ba..b9595cc 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -71,6 +71,7 @@ use Digest::MD5 ();
 use Encode qw();
 use List::MoreUtils qw();
 use JSON qw();
+use Plack::Util;
 
 =head2 SquishedCSS $style
 
@@ -966,13 +967,13 @@ sub Redirect {
     $HTML::Mason::Commands::m->abort;
 }
 
-=head2 CacheControlExpiresHeaders
+=head2 GetStaticHeaders
 
-set both Cache-Control and Expires http headers
+return an arrayref of Headers (currently, Cache-Control and Expires).
 
 =cut
 
-sub CacheControlExpiresHeaders {
+sub GetStaticHeaders {
     my %args = @_;
 
     my $Visibility = 'private';
@@ -989,13 +990,28 @@ sub CacheControlExpiresHeaders {
         ? sprintf "max-age=%d, %s", $args{Time}, $Visibility
         : 'no-cache'
     ;
-    $HTML::Mason::Commands::r->headers_out->{'Cache-Control'} = $CacheControl;
 
     my $expires = RT::Date->new(RT->SystemUser);
     $expires->SetToNow;
     $expires->AddSeconds( $args{Time} ) if $args{Time};
 
-    $HTML::Mason::Commands::r->headers_out->{'Expires'} = $expires->RFC2616;
+    return [
+        Expires => $expires->RFC2616,
+        'Cache-Control' => $CacheControl,
+    ];
+}
+
+=head2 CacheControlExpiresHeaders
+
+set both Cache-Control and Expires http headers
+
+=cut
+
+sub CacheControlExpiresHeaders {
+    Plack::Util::header_iter( GetStaticHeaders(@_), sub {
+        my ( $key, $val ) = @_;
+        $HTML::Mason::Commands::r->headers_out->{$key} = $val;
+    } );
 }
 
 =head2 StaticFileHeaders 
@@ -1008,20 +1024,12 @@ This routine could really use _accurate_ heuristics. (XXX TODO)
 =cut
 
 sub StaticFileHeaders {
-    my $date = RT::Date->new(RT->SystemUser);
-
     # remove any cookie headers -- if it is cached publicly, it
     # shouldn't include anyone's cookie!
     delete $HTML::Mason::Commands::r->err_headers_out->{'Set-Cookie'};
 
     # Expire things in a month.
     CacheControlExpiresHeaders( Time => 'forever' );
-
-    # if we set 'Last-Modified' then browser request a comp using 'If-Modified-Since'
-    # request, but we don't handle it and generate full reply again
-    # Last modified at server start time
-    # $date->Set( Value => $^T );
-    # $HTML::Mason::Commands::r->headers_out->{'Last-Modified'} = $date->RFC2616;
 }
 
 =head2 ComponentPathIsSafe PATH
diff --git a/lib/RT/Interface/Web/Handler.pm b/lib/RT/Interface/Web/Handler.pm
index 078091f..0625b16 100644
--- a/lib/RT/Interface/Web/Handler.pm
+++ b/lib/RT/Interface/Web/Handler.pm
@@ -328,9 +328,16 @@ sub StaticWrap {
     my $app     = shift;
     my $builder = Plack::Builder->new;
 
+    my $headers = RT::Interface::Web::GetStaticHeaders(Time => 'forever');
+
     for my $static ( RT->Config->Get('StaticRoots') ) {
         if ( ref $static && ref $static eq 'HASH' ) {
             $builder->add_middleware(
+                '+RT::Interface::Web::Middleware::StaticHeaders',
+                path => $static->{'path'},
+                headers => $headers,
+            );
+            $builder->add_middleware(
                 'Plack::Middleware::Static',
                 pass_through => 1,
                 %$static
@@ -342,10 +349,16 @@ sub StaticWrap {
         }
     }
 
+    my $path = sub { s!^/static/!! };
+    $builder->add_middleware(
+        '+RT::Interface::Web::Middleware::StaticHeaders',
+        path => $path,
+        headers => $headers,
+    );
     for my $root (RT::Interface::Web->StaticRoots) {
         $builder->add_middleware(
             'Plack::Middleware::Static',
-            path         => sub { s!^/static/!! },
+            path         => $path,
             root         => $root,
             pass_through => 1,
         );
diff --git a/lib/RT/Interface/Web/Middleware/StaticHeaders.pm b/lib/RT/Interface/Web/Middleware/StaticHeaders.pm
new file mode 100644
index 0000000..8bbd14f
--- /dev/null
+++ b/lib/RT/Interface/Web/Middleware/StaticHeaders.pm
@@ -0,0 +1,80 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+#                                          <sales at bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+#
+# This work is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
+package RT::Interface::Web::Middleware::StaticHeaders;
+
+use strict;
+use warnings;
+use base 'Plack::Middleware';
+use Plack::Util;
+
+use Plack::Util::Accessor qw(path headers);
+
+sub call {
+    my ( $self, $env ) = @_;
+    my $res = $self->app->($env);
+    my $path_match = $self->path;
+    my $path = $env->{'PATH_INFO'};
+    for ($path) {
+        my $matched = 'CODE' eq ref $path_match ?
+            $path_match->($_, $env)
+            : $_ =~ $path_match;
+        return $res unless $matched;
+        return $self->response_cb( $res,
+            sub {
+                my $res = shift;
+                my $headers = $res->[1];
+                Plack::Util::header_iter( $self->headers, sub {
+                    Plack::Util::header_set($headers, @_);
+                } );
+            }
+        );
+    }
+}
+
+1;
diff --git a/t/web/helpers-http-cache-headers.t b/t/web/helpers-http-cache-headers.t
index 74008ec..c32782c 100644
--- a/t/web/helpers-http-cache-headers.t
+++ b/t/web/helpers-http-cache-headers.t
@@ -24,7 +24,10 @@ ok $m->login, 'logged in';
 my $docroot = join '/', qw(share html);
 
 # find endpoints to loop over
-my @endpoints = ("/NoAuth/css/aileron/squished-".("0"x32).".css");
+my @endpoints = (
+    "/NoAuth/css/aileron/squished-".("0"x32).".css",
+    '/static/images/bpslogo.png',
+);
 find({
   wanted => sub {
     if ( -f $_ && $_ !~ m|autohandler$| ) {
@@ -77,7 +80,7 @@ foreach my $endpoint ( @endpoints ) {
   my $header_key = 'default';
   if ( $endpoint =~ m|Autocomplete| ) {
     $header_key =  'Autocomplete';
-  } elsif ( $endpoint =~ m|NoAuth| ) {
+  } elsif ( $endpoint =~ m/NoAuth|static/ ) {
     $header_key =  'NoAuth';
   }
   my $headers = $expected->{$header_key};

-----------------------------------------------------------------------


More information about the rt-commit mailing list