F5 Sites
  • F5.com
  • LearnF5
  • NGINX
  • MyF5
  • Partner Central
Contact
  • Under Attack?
  • F5 Support
  • DevCentral Support
  • F5 Sales
  • NGINX Sales
  • F5 Professional Services
Skip to contentBrand Logo
Forums
CrowdSRC
Articles
Groups
EventsSuggestionsHow Do I...?
RegisterSign In
  1. DevCentral
  2. CrowdSRC
  3. CodeShare

Cache Expire

Problem this snippet solves: This iRule sets caching headers Expires and Cache-Control on the response. Mostly the use case will be to set client-side caching of static resources as images, styleshee...
Published Jan 30, 2015
Version 1.0
application delivery
cache
devops
http
iRules
Opher_Shachar_6's avatar
Opher_Shachar_6
Icon for Nimbostratus rankNimbostratus
Joined January 12, 2012
View Profile
Opher_Shachar_6's avatar
Opher_Shachar_6
Icon for Nimbostratus rankNimbostratus
Joined January 12, 2012
View Profile
Amine_Kadimi's avatar
Amine_Kadimi
Icon for MVP rankMVP
Mar 21, 2017

Thanks for the code.

 

I agree with Vova regarding the second problem and below is the updated iRule to solve it. Regarding the first problem, I don't agree and I think that this is a good design choice to consider only the last extension when there is more than one. I have many .min.js and .min.css and they are all matching my .js and .css data group entries.

 

     Expires iRule, Version 0.9.1
 August, 2012

 Created by Opher Shachar (contact me through devcentral.f5.com)
 (please see end of iRule for additional credits)

 Purpose:
 This iRule sets caching headers on the response. Mostly the use case will be
 to set client-side caching of static resources as images, stylesheets, 
 javascripts etc.

 Configuration Requirements:
 Uses a datagroup named Expires of type string containing lines that
 specify mime-types or extention for the name and, the number of seconds the
 client should cache the resource for the value. ex.:
    "image/" := "604800"
    ".js"    := "604800"
 The Content-Type, if specified, takes precedence over the file extention.

when RULE_INIT {
    Enable to debug Expires via log messages in /var/log/ltm
    (2 = verbose, 1 = essential, 0 = none)
   set static::ExpiresDebug 0

    Overwrite cache headers in response
    (1 = yes, 0 = no)
   set static::ExpiresOverwrite 0
}

when CLIENT_ACCEPTED {
    The name of the Data Group (aka class) we are going to use
   set vname [URI::basename [virtual name]]
   set vpath [URI::path [virtual name]]
   set Expires_clname "${vpath}Expires$vname"

   if {! [class exists $Expires_clname]} {
      log local0.notice "Data Group $Expires_clname not found."
   }
}

when HTTP_REQUEST {
    The log prefix so you can find yourself in the log
   set Expires_lp "VS=[virtual name], URI=[HTTP::uri]"

   if {[class exists $Expires_clname]} {
      set period [string last . [HTTP::path]]
      if { $period >= 0 } {
          Set the timeout based on the class entry if it exists for this request.
         set expire_content_timeout [class match -value [string tolower [getfield [string range [HTTP::path] $period end] ";" 1]] ends_with $Expires_clname]
         if { ($static::ExpiresDebug > 1) and ($expire_content_timeout ne "") } {
           log local0. "$Expires_lp: found file suffix based expiration: $expire_content_timeout."
         }
      }
      else {
         set expire_content_timeout ""
      }
   }
}

when HTTP_RESPONSE {
   if { [info exists expire_content_timeout] } {  if expire_content_timeout not set then no class was found   
      if { [HTTP::header exists "Content-Type"] } {
        if {[class match [string tolower [HTTP::header "Content-Type"]] starts_with $Expires_clname]} {
              Set the tiemout based on the class entry if it exists for this mime type.
              TODO: Allow globbing in matching mime-types
             set expire_content_timeout [class match -value [string tolower [HTTP::header "Content-Type"]] starts_with $Expires_clname]
             if { ($static::ExpiresDebug > 1) and ($expire_content_timeout ne "") } {
                log local0. "$Expires_lp: found mime type based expiration: $expire_content_timeout."
            }
        }
      }

      if { $expire_content_timeout ne "" } {  either matched Content-Type or file extention  
         if { $static::ExpiresOverwrite or not [HTTP::header exists "Expires"] } {
            HTTP::header replace "Expires" "[clock format [expr ([clock seconds]+$expire_content_timeout)] -format "%a, %d %h %Y %T GMT" -gmt true]"
            if { ($static::ExpiresDebug > 0) } {
               log local0. "$Expires_lp: Set 'Expires' to '[clock format [expr ([clock seconds]+$expire_content_timeout)] -format "%a, %d %h %Y %T GMT" -gmt true]'."
            }
         }
         elseif { [HTTP::header exists "Expires"] } {
            set expire_content_timeout [expr [clock scan "[HTTP::header Expires]" -gmt true] - [clock seconds]]
            if { $expire_content_timeout < 0 } {
               if { ($static::ExpiresDebug > 0) } {
                  log local0. "$Expires_lp: Found 'Expires' header either invalid or in the past."
               }
               return
            }
            if { ($static::ExpiresDebug > 0) } {
               log local0. "$Expires_lp: Found 'Expires' header and calculated $expire_content_timeout seconds timeout."
            }
         }
         if { $static::ExpiresOverwrite or not [HTTP::header exists "Cache-Control"] } {
            HTTP::header replace "Cache-Control" "max-age=$expire_content_timeout, public"
            if { ($static::ExpiresDebug > 0) } {
               log local0. "$Expires_lp: Set 'Cache-Control' to 'max-age=$expire_content_timeout, public'."
            }
         }
      }
   }
}

ABOUT DEVCENTRAL

DevCentral NewsTechnical ForumTechnical ArticlesTechnical CrowdSRCCommunity GuidelinesDevCentral EULAGet a Developer Lab LicenseBecome a DevCentral MVP

RESOURCES

Product DocumentationWhite PapersGlossaryCustomer StoriesWebinarsFree Online CoursesF5 CertificationLearnF5 Training

SUPPORT

Manage SubscriptionsProfessional ServicesProfessional ServicesCreate a Service RequestSoftware DownloadsSupport Portal

PARTNERS

Find a Reseller PartnerTechnology AlliancesBecome an F5 PartnerLogin to Partner Central

F5 logo©2024 F5, Inc. All rights reserved.
TrademarksPoliciesPrivacyCalifornia PrivacyDo Not Sell My Personal Information