10
votes

I'm developing iPhone app and manually constructing POST requests. Currently, need to compress JSON data before sending it, so looking how to tell a server the content is compressed. Setting content type header to gzip might be not acceptable because server expects JSON data. I'm looking for transparent solution, something like just to add some header telling JSON data is compressed into gzip.

I know, the standard way is to tell the server that the client accepts encoding, but you need to make GET request with accept encoding header first. In my case, I want to post the data already encoded.

2

2 Answers

20
votes

Include a Obj-C gzip wrapper, for example NSData+GZip, and use it to encode the body of your NSURLRequest. Also remember to set the Content-Encoding accordingly, so the webserver will know how to treat your request.

NSData *requestBodyData = [yourData gzippedData];
NSString *postLength = [NSString stringWithFormat:@"%d", requestBodyData.length];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"];
[request setHTTPBody:requestBodyData];
-2
votes

Implmenting some general Method such as follows and setting appropriate Header might help you.

// constructing connection request for url with no local and remote cache data and timeout seconds
NSMutableURLRequest *request =[NSMutableURLRequest requestWithURL:[NSURL URLWithString:callingWebAddress]];// cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:timoutseconds];
[request setHTTPMethod:@"POST"];

NSMutableDictionary *headerDictionary = [NSMutableDictionary dictionary];
[headerDictionary setObject:@"application/json, text/javascript" forKey:@"Accept"];
[headerDictionary setObject:@"application/json" forKey:@"Content-Type"];

//Edit as @centurion suggested
[headerDictionary setObject:@"Content-Encoding" forKey:@"gzip"];
[headerDictionary setObject:[NSString stringWithFormat:@"POST /Json/%@ HTTP/1.1",method] forKey:@"Request"];
[request setAllHTTPHeaderFields:headerDictionary];

// allocation mem for body data
self.bodyData = [NSMutableData data];

[self appendPostString:[parameter JSONFragment]];

// set post body to request
[request setHTTPBody:bodyData];

NSLog(@"sending data %@",[[[NSString alloc] initWithData:bodyData encoding:NSUTF8StringEncoding]autorelease]);

// create new connection for the request
// schedule this connection to respond to the current run loop with common loop mode.
NSURLConnection *aConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
//[aConnection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
self.requestConnenction = aConnection;
[aConnection release];