5
votes

I'm having trouble writing a IPhone/IOS Obj-C SOAP client that talks to an application with a SOAP WS interface. The application uses a NuSOAP php webserver and encodes any payload above a certain size using gzip/deflate, whichever is enabled by the client.

I understand that NSURLConnection transparently decompresses any gzip encoded response and presents the decompressed response, but the raw response that is received in this case seems to be corrupt. I dumped the SOAP payload into a file and decompressed it using gunzip, it complains of an "unexpected end of file". I did check the webserver and dumped the gzip response that it is sending to a file, this is decompressed without any error using gunzip. Seems like the response is getting corrupted on receipt.

I tried using both NSURLConnection and ASIHTTPRequest. With NSURLConnection, there is a difference of exactly 15 bytes every time, between the response Data length and the length mentioned in the response's HTTP header. With ASIHTTPRequest the number of bytes received and the length of the response in the HTTP Header match but alas the response is still corrupt and doesn't respond to gzip decompression kindly.

    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"Headers :%@",[(NSHTTPURLResponse*)response allHeaderFields]);
        [self.receivedData setLength:0];
    self.receivedData = [[NSMutableData dataWithCapacity:1024*1024] retain];
   }

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)value {
    NSString *dataRec = [[NSString alloc] initWithData:value encoding:NSUTF8StringEncoding];
    NSLog(@"didReceiveData :%@",dataRec);
    [self.receivedData appendData:value];
}

2010-10-04 13:37:15.310 SugarSoap[848:207] Headers :{ "Cache-Control" = "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"; Connection = "Keep-Alive"; "Content-Encoding" = gzip; "Content-Length" = 1683; "Content-Type" = "text/xml; charset=UTF-8"; Date = "Mon, 04 Oct 2010 08:07:14 GMT"; Expires = "Thu, 19 Nov 1981 08:52:00 GMT"; "Keep-Alive" = "timeout=15, max=100"; Pragma = "no-cache"; Server = "Apache/2.0.59 (Unix) mod_ssl/2.0.59 OpenSSL/0.9.8g DAV/2 PHP/5.2.5"; "Set-Cookie" = "PHPSESSID=udsgtttvts90ijuhsvuqop6ja6; path=/"; Vary = "Accept-Encoding"; "X-Powered-By" = "PHP/5.2.5"; "X-Soap-Server" = "NuSOAP/0.7.2 ()"; } 2010-10-04 13:37:15.311 SugarSoap[848:207]

didReceiveData :(null) 2010-10-04 13:37:15.311 SugarSoap[848:207] connectionFinsihed! Length :1668

-(void)requestFinished:(ASIHTTPRequest *)request {
    if([request isResponseCompressed]){
        NSLog(@"Response Compressed.");
    }
    NSData *compressedResponse = [request rawResponseData];
    NSData *responseData = [request responseData];
    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding];
    NSLog(@"Length before decompression:%d Length after decompression:%d", compressedResponse length],[responseData length]);
    NSLog(@"Response :%@",responseString);
}

2010-10-04 14:11:20.687 Hello_SOAP[1033:207] Response Compressed.

2010-10-04 14:11:20.687 Hello_SOAP[1033:207] Length before decompression:2165 Length after decompression:0

2010-10-04 14:11:20.687 Hello_SOAP[1033:207] Response :

3

3 Answers

0
votes

I once had a problem when a slightly corrupted file would unzip without any problems on my Mac, but on iPhone it wouldn't. I guess zlib on iPhone has less tolerance for errors.

0
votes

Are you sure that -connection:didReceiveData: isn’t being called at least once before -connection:didReceiveResponse:? It looks like you might be truncating some of the data that comes in the first packet with the headers.

0
votes

Are you sure that your data is UTF8? Try other encodings and see if you error goes away.