Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HEAD HTTP requests in Rails 3

Rails 3 currently routes a HEAD request to the matching GET route. There is a head? method on the request, but in returns false and the request acts like a get request. Can I detect if the request is a HEAD request?

Reasoning: I get that a HEAD request should return the EXACT same headers as the get, so Rails wants to perform the full GET and then shave off the body. However, I can conform to this request without issuing the same DB calls, etc that the GET would. Does this make sense?

like image 862
Glenn Goodrich Avatar asked May 03 '12 20:05

Glenn Goodrich


3 Answers

I had this exact issue. It turns out that enabling caching causes this. Turn caching off in your environment and #head? will work as expected.

The issue is that Rack::Cache turns HEAD requests into GET requests so they can be cached. This is arguably the correct behavior, but it interfered with my application.

like image 66
Jacob Lukas Avatar answered Oct 12 '22 16:10

Jacob Lukas


You can use the request.head? method to find out if it's a HEAD request:

http://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-head-3F

Once you've determined that it is, you can also use the controller's head() method instead of the typical render:

http://guides.rubyonrails.org/layouts_and_rendering.html#using-head-to-build-header-only-responses

So I'd simply check request.head? before bothering with the database activities. Then use

head :ok, :custom_header => 'value'
like image 39
Benjamin Cox Avatar answered Oct 12 '22 16:10

Benjamin Cox


def index
  if request.head?
    head :created
  else
    Rails.logger.info "Derp #{request.method}"
  end
end

Hmm. The above controller method works like I'd expect on Ruby v1.9.3-p194 and Rails v3.2.3; 201's w/o response body for the HEAD requests and 200's w/ for the GET's.

like image 1
ezkl Avatar answered Oct 12 '22 14:10

ezkl