Thursday, June 5, 2008

HTTP PUT and NSMutableURLRequest

I've been struggling with a problem with NSMutableURLRequest for an article I'm writing about writing Cocoa clients for RESTful web services. Whenever I use HTTP PUT requests, the form parameters do not appear to be getting passed to the server in the request body. If I did two requests, exactly the same, using PUT and POST, the parameters came up in the POST request, but not the PUT request.

I wrote up a sample Ruby on Rails server and Xcode project to demonstrate the problem and submitted it as "PUT parameters not being passed in body when using NSMutableURLRequest". After being told by Apple that this wasn't happening, I re-tested, thinking perhaps that 10.5.3 release had fixed it. Nope! 

Well, I spent several years working at a large software company fixing reported defects. so I knew that merely re-submitting the same post was unlikely to yield a different result.  Defects are generally not closed lightly, and certainly not arbitrarily, so I dug out wireshark and did a little digging.

It turns out, the PUT parameters are being passed in the body. My description of the problem was not technically correct, even though the code I submitted clearly showed a problem with PUT requests. I took the captured requests for a  PUT and a POST request and noticed a difference: the PUT requests had no content-type header. This is clearly a bug, but it's not the bug I described. I'm going to submit a new defect today, but since I've found a simple workaround for the problem, I thought I'd post it. Here it is:

When using NSMutableURLRequest to do an HTTP PUT request, add the following line of code (req is the NSMutableURLRequest):
[req setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
That's all there is to it. If you add this line of code, your PUT requests will work just fine.

No comments:

Post a Comment