3
  def call(env)
    status, headers, response = @app.call(env)

    if response.is_a? Array
      puts response.inspect
    else
      puts response.class.to_s
    end

    [status, headers, response]
  end

From development.log:

First request:

Completed 200 OK in 95ms (Views: 35.9ms | ActiveRecord: 1.5ms)
ActionDispatch::Response

Second and other requests:

Completed 200 OK in 77ms (Views: 76.3ms | ActiveRecord: 0.0ms)
[]

response is a: ActionDispatch::Response the first time a route gets called, for any other requests for that exact url, it is an empty Array

Page renders successfully in both cases, but I can't use response.body when response is an empty array.

Is this normal Rails behavior? Is there some caching here even in dev environment?

Josh Darnell
  • 11,304
  • 9
  • 38
  • 66
Mirko
  • 5,207
  • 2
  • 37
  • 33

1 Answers1

1

I'm seeing the same thing.

I found that the console would only show the last HTTP status code (200 OK), but with the debugger console I see a different code (304, "Not Modified". More on that here)

The nature of the 304 code is that the response will be empty, because the server is telling your browser to just use cache. Your browser is sending a conditional GET (which should be normal browser behavior?) and that's what's causing your server to behave this way. Your browser is unaware that you're in development mode, so it's going to behave as it normally would.

Note that I was able to sidestep this error by doing CTRL-F5 for a refresh (in Firefox), which is a command for "refresh and ignore cache". So the browser does a plain GET instead of a conditional one.

Here's the code I used to help me figure out what was going on (requires the ruby-debug gem).

def call(env)
  status, headers, response = @app.call(env)
  debugger
  if headers["Content-Type"].include?("text/html")
    [status, headers, "<!--hello world! -->" + response.body]
  else
    [status, headers, response]
  end
end

After doing this, load the page and in the rail server terminal:

(rdb:1) irb
irb(#<PostRedirect:0x7f9c6292a530>):001:0> status
=> 304

My fix was to add a status code check:

  if (status != 304) && headers["Content-Type"].include?("text/html")
Community
  • 1
  • 1
Eric Hu
  • 18,048
  • 9
  • 51
  • 67
  • You are right, and I think "eTag" headers are causing 304 status. – Mirko May 25 '11 at 23:09
  • 1
    Yep, that sounds right.I think most sites now should support eTag headers as it saves bandwidth and allows faster page loads if the site is unchanged from an earlier visit. With that said, it doesn't really make a difference for small websites, and probably isn't noticeable in development mode (since you have near zero latency for your page request) – Eric Hu May 26 '11 at 00:40