NSURLRequest cannot handle HTTP body when method is not POST?
Asked Answered
L

3

12

Whenever I set a body on a mutable request with the method set to anything other than POST, the body is not included in the request and I get a kCFErrorDomainCFNetwork error 303 (kCFErrorHTTPParseFailure) when the server replies. Changing the method to POST is all it takes for the request to go through with no error. Is there any way to attach a body to other methods, or are we stuck with POST for everything?

This is the submission code:

NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:assembleURL]];// cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:45.0];

#if (SERVER_TARGET_ARGS_ALLOWED==1)
[req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[req setValue:@"application/json" forHTTPHeaderField:@"Accept"];

[req setHTTPMethod:ServerMessageMethods[operation]];    //value is @"POST" or other method name

#endif  

//run the payload into a JSON
SBJsonWriter *json = [[SBJsonWriter alloc] init];
NSString *encodedPayload = [json stringWithObject:payload];
encodedPayload = [NSString stringWithFormat:@"%@", [encodedPayload stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSData *dataPayload = [encodedPayload dataUsingEncoding:NSUTF8StringEncoding];
[req setHTTPBody:dataPayload];

NSURLConnection *conn = [NSURLConnection connectionWithRequest:req delegate:self];
Lycurgus answered 12/8, 2010 at 14:58 Comment(1)
Yep, I had an issue with Content-Length, regarding PDFs, but thought I'd share. ssbits.wordpress.com/tag/kcferrordomaincfnetworkZombie
T
14

I tried finding more recent information about it, but there was an old post about the exact issue you were talking about: http://lists.apple.com/archives/cocoa-dev/2004/May/msg01847.html

Basically, they mention it is a bug in the code. Sadly, I wished I could find something more recent that confirms it.

The code I've been using is ASIHTTPRequest and it can definitely do PUT requests, since they use a lower level set of code to create the HTTP messages and don't rely on the NSMutableUrlRequest.

Also, I found another blog post talking about the issue and what you need to put for a PUT request. http://iphonedevelopment.blogspot.com/2008/06/http-put-and-nsmutableurlrequest.html

blog post:

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.

Thyrse answered 12/8, 2010 at 15:36 Comment(1)
Still exists in 2016Toneytong
E
0

Are you remembering to set the Content-Length/Transfer-Encoding and Content-Type headers? I don't think that Content-Length is put in automatically for you, which means the server is going to assume it's 0.

More info: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

Esophagitis answered 12/8, 2010 at 15:23 Comment(3)
Just wondering how that would explain it working for POST but not for other operations? You thinking maybe it gets set for one operation and not the other?Thyrse
@Thyrse it might be set automatically, but i don't know; however, an undefined Content-Length might explain why the server never reads the body of the request.Esophagitis
Content-Length is not necessary if you use HTTP/1.1's chunked encoding. NSURLConnection should handle all of that transparently for you.Rawhide
A
-1

here it is

+(NSString*)simpleCurl:(NSString*)urlStr withBody:(NSString*)post{

//    NSLog(urlStr);
NSURL *url = [NSURL URLWithString:[urlStr stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
//    NSLog([url description]);
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req setHTTPMethod:@"POST"];
[req setValue:@"close" forHTTPHeaderField:@"Connection"];
[req setValue:@"utf-8;q=0.7,*;q=0.7" forHTTPHeaderField:@"Accept-Charset"];
[req setValue:@"gzip,deflate" forHTTPHeaderField:@"Accept-Encoding"];
[req setValue:@"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)" forHTTPHeaderField:@"User-Agent"];
[req setValue:@"Application/Json, text/html, application/xhtml+xml, */*" forHTTPHeaderField:@"Accept"];
[req setHTTPMethod:@"POST"];//  or PUT
NSString *postString = post;
[req setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];

NSData *res = [NSURLConnection  sendSynchronousRequest:req returningResponse:NULL error:NULL];
NSString* html=[[NSString alloc] initWithData:res encoding:NSUTF8StringEncoding];
return html;

}

Amusement answered 17/5, 2013 at 21:23 Comment(1)
I don't get it, how is this supposed to solve the issue?Demagogic

© 2022 - 2024 — McMap. All rights reserved.