'Content-Type' after 302 redirect is invalid #1238

Closed
cvasilak opened this Issue Aug 21, 2013 · 5 comments

Comments

Projects
None yet
6 participants
Contributor

cvasilak commented Aug 21, 2013

Hi there,

I am facing an issue and it would be really helpful if I get your insight on this. I have implemented logic that performs a redirect (using 'setRedirectResponseBlock') and works perfectly fine, in the sense that redirection happens and I get back results from the server.

*Note that the redirection happens from an 'http' to an 'https' scheme and uses Basic Authentication

My issue is that the returned 'Content-Type' is set to 'text/plain' which causes 'AFJSONRequestOperation' to fail since it expects a valid json type.

I suspected the server initially, but as I have seen from curl, the server does return a valid 'application/json' Content-Type. You can see the output of the curl command here

As you see from the log, the first request has the 'Content-Type' to 'text/plain' and the '302 Moved Temporarily' but after the redirection the next request has the correct Content-Type set to 'application/json'. Not sure why this is not seen?

Any insight on where to look?

Thank you for your time

I had the same problem. My understanding is that the redirect doesn't copy the original request's headers, so your server isn't getting the 'ACCEPT' header when the second request is made. The following works for me (note where the original request is copied at the end):

- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest success:(void (^)(AFHTTPRequestOperation *, id))success failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure {
    AFHTTPRequestOperation *op = [super HTTPRequestOperationWithRequest:urlRequest success:success failure:failure];
    __weak AFHTTPRequestOperation *weakOp = op;
    [op setRedirectResponseBlock:^NSURLRequest *(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse) {
        if (nil == redirectResponse) {
            return request;
        }
        if ([@"http" isEqualToString:weakOp.request.URL.scheme] && [@"https" isEqualToString:request.URL.scheme]) {
            self.shouldUseSSL = YES;
        }
        NSMutableURLRequest *r = [weakOp.request mutableCopy];
        [r setURL:request.URL];
        return r;
    }];
    return op;
}
Contributor

matzew commented Aug 23, 2013

My understanding is that the redirect doesn't copy the original request's headers

I wonder if that should be fixed inside of the library; or if it was done for a reason.

Adding these 'work arounds' are an option, but IMO it would be nice to see a fix for that in the library;

Contributor

kcharwood commented Aug 23, 2013

Hey guys,

The redirect block provides the exact behavior you would get if you were the delegate for the NSURLConnection, so there are no surprises.

You are correct in seeing that the original request is not copied. This is standard NSURLConnection behavior. You'll need to copy the original request and set the new URL if you want to send the entire request to the new endpoint.

The point of those blocks is to provide NSURLConnectionDelegate behavior, and this is one of the 'joys' of that behavior.

Hope that clears everything up.

Contributor

mattt commented Aug 23, 2013

Thanks for the clarification, @kcharwood. I'll do my best to document this peculiarity in either the FAQ or the book.

@mattt mattt closed this Aug 23, 2013

Contributor

tewha commented Aug 23, 2013

User agents dropping payloads on 302 status codes is pretty common. See Wikipedia's HTTP 302.

I'm not sure if NSURLConnection respects 307; I did the same hack you did. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment