NSURLSessionDataTask changes POST request to GET request

Hi


I'm experiencing very odd behavior with NSURLSessionDataTask. It seems that if I POST to an endpoint that has params in the URL, it will always get sent as GET request, even though I am explicitely setting the HTTPMethod of the NSMutableURLRequest to POST. When POSTing to an endpoint that is straight-foward and has no params in its URL (eg. no ?param=value), then NSURLSession will send it off as a POST request.


Has anyone else experienced this behavior?

I tried this and couldn't replicate it. Here's the code I used to create my request:

NSMutableURLRequest *   request;

request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://biff.local.:12345/foo?param=value"]];
request.HTTPMethod = @"POST";
self.task = [self.session dataTaskWithRequest:request];
assert(self.task != nil);

[self.task resume];

The server at

biff.local.
got a POST request as expected.
POST /foo?param=value HTTP/1.1
Host: biff.local.:12345
Connection: keep-alive
Accept: */*
User-Agent: QTestbed/1.0 CFNetwork/711.4.6 Darwin/14.4.0
Accept-Language: en-us
Content-Length: 0
Accept-Encoding: gzip, deflate

I'm building in Xcode 6.4 and running on the iPhone 6 / iOS 8.4 simulator (in my experience the simulator reliably replicates issues like this, so I don't expect this to be a simulator / real device discrepancy).

Please try a simple test with the code shown and let me know what you get.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks, Quinn.

Turns out the server I was POSTing to was sending a 301 redirect back, and so all subsequent queries were GET afterwards!

I just ran into the same problem.


When NSURLSession receives a redirect on a 'POST' request, it replaces the HTTPMethod by 'GET'.


Is this the intended behaviour? I think it is at least not the expected behaviour.


I know I can override the method in `willPerformHTTPRedirection`, but still it feels odd


```

- (void)URLSession:(NSURLSession *)session

task:(NSURLSessionTask *)task

willPerformHTTPRedirection:(NSHTTPURLResponse *)redirectResponse

newRequest:(NSURLRequest *)request

completionHandler:(void (^)(NSURLRequest *))completionHandler {

NSMutableURLRequest *newRequest = request.mutableCopy;

if (redirectResponse) {

newRequest.HTTPMethod = @"POST";

}

completionHandler(newRequest);

}



```

I think it is at least not the expected behaviour.

Clearly it wasn’t expected by you (-:

The behaviour you’re looking for (retrying the

POST
) isn’t possible because of the HTTP idempotency rules. As to why it does what it does, I don’t have a definitive answer for you but my best guess is that this is grandfathered in from some legacy web browser behaviour.

Regardless, the correct solution is to catch the redirect and use app-level logic to determine if the retry is safe.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
NSURLSessionDataTask changes POST request to GET request
 
 
Q