304 response status codes trigger the on_failure block #14

Closed
wesgurn opened this Issue Nov 2, 2009 · 9 comments

3 participants

@wesgurn

Greetings. I have been implementing an app that uses caching and I am setting the if-modified-since header to test if the response code is 200 or 304.

For some reason when it returns 304 status code response, it never calls the on_success block. Instead it calls both the on_complete and on_failure blocks.

Is this the desired action for 304 responses?

Here is an example of the code I am using.

#!/usr/bin/env ruby

require 'rubygems'
require 'curb'
require 'uri'

# Define URL
url = "http://www.google.com/intl/en_ALL/images/logo.gif"
easy = Curl::Easy.new URI.escape(url) do |curl|
  # Set header for cache
  curl.headers['If-Modified-Since'] = "Wed, 07 Jun 2006 19:38:24 GMT"
  curl.headers['Cache-Control'] = "max-age=0"

  # On successful download (ie a response was returned from the web server)
  curl.on_success do |response|
    print "We have success.  The response code is #{response.response_code}\n"
  end
  curl.on_complete do |response|
    print "We have complete.  The response code is #{response.response_code}\n"
  end

  curl.on_failure do |response, err|
    print "We have failure.  The response code is #{response.response_code}\n"
    print "Error is: #{err.inspect}\n"
  end
end

easy.verbose = true
easy.perform

The output:

* About to connect() to www.google.com port 80 (#0)
*   Trying 74.125.157.104... * Connected to www.google.com (74.125.157.104) port 80 (#0)
> GET /intl/en_ALL/images/logo.gif HTTP/1.1
Host: www.google.com
Accept: */*
If-Modified-Since: Wed, 07 Jun 2006 19:38:24 GMT
Cache-Control: max-age=0

< HTTP/1.1 304 Not Modified
< Last-Modified: Wed, 07 Jun 2006 19:38:24 GMT
< X-Content-Type-Options: nosniff
< Date: Mon, 02 Nov 2009 15:34:55 GMT
< Server: gws
< X-XSS-Protection: 0
< 
* Expire cleared
* Connection #0 to host www.google.com left intact
We have complete.  The response code is 304
We have failure.  The response code is 304
Error is: [Curl::Err::CurlError, "Unknown error result from libcurl"]

I looked in the C code to see where that error gets set and it looks like it is the default code if no other curl error codes match. Why are 304 responses returning an error code from Curl?

Just as an aside, if I don't set caching headers, here is the 200 response

* About to connect() to www.google.com port 80 (#0)
*   Trying 74.125.157.103... * Connected to www.google.com (74.125.157.103) port 80 (#0)
> GET /intl/en_ALL/images/logo.gif HTTP/1.1
Host: www.google.com
Accept: */*

< HTTP/1.1 200 OK
< Content-Type: image/gif
< Last-Modified: Wed, 07 Jun 2006 19:38:24 GMT
< Date: Mon, 02 Nov 2009 15:33:53 GMT
< Expires: Tue, 02 Nov 2010 15:33:53 GMT
< X-Content-Type-Options: nosniff
< Server: gws
< Content-Length: 8558
< Cache-Control: public, max-age=31536000
< Age: 85
< X-XSS-Protection: 0
< 
* Expire cleared
* Connection #0 to host www.google.com left intact
We have complete.  The response code is 200
We have success.  The response code is 200

Any ideas?

Thanks,
Wes

@taf2
Owner

Hi Wes,

Sorry for the long delay... This really comes down to a deficiency in the current callback interface, whether we say 20x is success or 30x is failure just means we really can't easily classify response codes binary as success or failure... I suggest using the on_complete callback...

@wesgurn

No worries. I ended up implementing using the on_complete callback and having it check in the on_failure callback to ignore if it was a 304 response code.

@taf2
Owner

Maybe for future releases the right thing to do here would be to add a on_redirect, and on_missing callback?

@wesgurn

Thats a good idea. Maybe define the set callbacks more specific for the various status response groups:
2xx codes on_success
3xx codes on_redirect
4xx codes on_missing
5xx codes on _failure

One thing that might get somewhat confusing is that network connection, DNS failed lookups, and 5xx reponse codes are getting grouped in on_failure callback. Not sure if you want to break those out in a separate ones or not.

Another possible solution is to add callbacks for each of the response status codes - on_200, on_301, on_404. This way the developer can be very specific as to how they want to handle each of the status codes.

@taf2
Owner

Okay, I'm thinking something such as. easy.on("304") {|c| ... } etc... There is a bit of overhead in this but I think it's not huge. Will update as I make progress

@jeisenlo

Any updates on this? Thanks.

@taf2
Owner

will work on this for the 0.8 series... porting more c code to ruby will make this kind of interface easier to implement.

@jeisenlo

Awesome, Todd! Thank you!

@taf2
Owner

for 0.8 release on_redirect and on_missing will be included in addition to on_success, on_failure and on_complete.

@taf2 taf2 closed this Jan 20, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment