#27 ✓resolved
Scott Guelich

302 Redirection Issue

Reported by Scott Guelich | November 15th, 2009 @ 08:31 PM

Hi Ben, a few months ago there was a ticket for 303 redirects not performing a GET request (ticket #9). There's a similar issue with 302 redirects.

Technically, the HTTP standard says that the HTTP request method should not be changed for 302 requests -- instead clients should be prompted whether they want to do a GET or POST to the new URL. However, browsers don't do this. Instead they treat a 302 response to a POST requests by performing a new GET request to the redirected location. So when we try to use ASIHTTPRequest to submit form data to a server that responds with a 302 status (say a login form), we can end up with completely different content than what we're seeing in web browsers.

Here are some refs:

  • RFC 2616 - provides the formal spec, but note that it immediately says "most existing user agent implementations treat 302 as if it were a 303 response, performing a GET on the Location field-value regardless of the original request method."
  • curl manpage - curl submits GET redirect for 301, 302, 303 unless you explicitly tell it not to do this for 301 & 302 responses.

My suggestion is that ASIHTTPRequest do the same thing as curl, and by default send a GET request to all 301, 302, 303 responses. Optionally you could add a property to toggle the behavior to send a POST request for 301 & 302 responses as curl also does.

Thanks so much for such a thorough and well coded library!

Comments and changes to this ticket

  • Ben Copsey

    Ben Copsey December 1st, 2009 @ 09:22 AM

    • State changed from “new” to “open”

    Hi Scott

    This behaviour has been mentioned a couple of times on the google group:

    http://groups.google.com/group/asihttprequest/browse_thread/thread/...
    http://groups.google.com/group/asihttprequest/browse_thread/thread/...

    Since a few people have asked about this, perhaps it would make sense to change things to follow the browser convention rather than the spec for cases where ASIHTTPRequest is talking to an interface that is intended for a browser. I'll try to take a look soon.

    I'd rather avoid adding an additional flag, though I have been thinking about moving the redirection code into its own method to make subclassing to change the behaviour easier.

    Thanks

    Ben

  • Ben Copsey

    Ben Copsey December 18th, 2009 @ 05:28 PM

    • State changed from “open” to “resolved”

    Hi Scott

    I've changed the redirect behaviour so 301, 302 and 303 redirects all use GET. I will revisit how the code is structured soon to make customising the behaviour easier.

    Best

    Ben

  • Thien Tran

    Thien Tran November 11th, 2011 @ 02:56 AM

    • Milestone order changed from “0” to “0”

    I know this is an old topic but I've discovered a bug with this approach when it comes to HEAD requests. We use a HEAD request to get a file's size without needing to download the whole (possibly very large) file. In the case of a redirect, this HEAD request gets transformed into a GET request and the whole file starts downloading.

    To fix this, I added a check for "POST" requests only, in method -(BOOL) willRedirect:

    if (responseCode != 307 && (![self shouldUseRFC2616RedirectBehaviour] || responseCode == 303)) {
    
           if ([self.requestMethod isEqualToString:@"POST"]) {     // <-- My change
            [self setRequestMethod:@"GET"];
            [self setPostBody:nil];
            [self setPostLength:0];
        }
    

    But I'm not sure if this has other global ramifications for the rest of the code, do you guys think this is a safe fix?

    Thanks!

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

Easy to use CFNetwork wrapper for HTTP requests, Objective-C, Mac OS X and iPhone

People watching this ticket

Referenced by

Pages