rack-devel archive mirror (unofficial) https://groups.google.com/group/rack-devel
 help / color / mirror / Atom feed
From: Simon Smith <amazingdancingbear@gmail.com>
To: Rack Development <rack-devel@googlegroups.com>
Subject: Patch - For caching with 304 Not Modified
Date: Wed, 21 Jul 2010 08:23:45 -0700 (PDT)	[thread overview]
Message-ID: <39c82ee3-5030-4721-9be8-0b1927dce3f1@x21g2000yqa.googlegroups.com> (raw)

Hi,

I am currently using Rails 2.3.2 with Rack 1.0.0 (I looked at the
source for 1.2.0 and the issue is the same). When a browser requests a
page it is downloading all images and JavaScripts each time, where
what should be happening is a '304 Not Modified' response should be
returned if the browser already has the asset in cache. The caching is
working fine for html pages themselves served by Rails.

I looked through the source code and found that JavaScript and images
are being handled with Rack::File. I made a patch to the Rack::File
class to handle the If-Modified-Since directive so a 304 is sent in
the case the supplied modified time matches that of the file itself.

Below is that patch to Rack::File; it adds the 'notmodified' function
and modifies the '_call' function.

    def _call(env)
      @path_info = Utils.unescape(env["PATH_INFO"])
      return forbidden  if @path_info.include? ".."

      @path = F.join(@root, @path_info)

      begin
        if F.file?(@path) && F.readable?(@path)

          #check the If-Modified-Since header and send 304 if the
client has the most up to date version already

          if env['HTTP_IF_MODIFIED_SINCE']
          	http_time =
Time.httpdate(env['HTTP_IF_MODIFIED_SINCE'])
          	mtime = Time.httpdate(F.mtime(@path).httpdate)

          	if http_time &&  http_time <= Time.now && mtime = http_time
          	    return notmodified
      		end
      	  end

          serving
        else
          raise Errno::EPERM
        end
      rescue SystemCallError
        not_found
      end
    end

    def notmodified
      body = "Not Modified\n"
      [304, {"Content-Type" => "text/plain",
             "Content-Length" => body.size.to_s},
       [body]]
    end

This patch seems to work but it seems strange that it is missing in
the first place as there are so many users of Rack and Rails and I
cannot find any information pertaining to other users with this
problem. I am wondering if there is an alternate way to handle this
caching without modifying the rack code itself and I am just missing a
configuration option in Rails, do you know of one?

Please feel free to use/modify this patch in your next release of
Rack.

Regards,

Simon

             reply	other threads:[~2010-07-21 17:07 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-21 15:23 Simon Smith [this message]
2010-07-21 18:16 ` Patch - For caching with 304 Not Modified Eric Wong
2010-07-21 18:59   ` Simon Smith

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://groups.google.com/group/rack-devel

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=39c82ee3-5030-4721-9be8-0b1927dce3f1@x21g2000yqa.googlegroups.com \
    --to=rack-devel@googlegroups.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).