Domanda

we have an iOS app that uploads images to a server using a multipart post. Everything is ok while using wifi, but on 3G for large images we are getting network errors.

On the client (iPhone):

I got a

Domain=NSURLErrorDomain Code=-1021 “request body stream exhausted”

based on this post I tried to use the AFNetwork library with that method but still got the same exact result.

On the server:

I have setup a proxy to see the request and I am getting

"Socket broken pipe"

usually after 740Kb have been transmitted

So, what am I doing wrong? Like I said over wifi everything works fine, and on 3G with small images is fine too.

The AFNetwork version code (stops transferring after 600 - 800 kb for large images):

AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:self.baseURL];

        request = [client multipartFormRequestWithMethod:@"POST"
                                                                         path:nil
                                                                   parameters:nil
                                                    constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
                                        {

                                            for (NSString* partType in self.parts) {
                                                if ([partType isEqualToString:@"jsonpart"]) {
                                                    [formData appendPartWithFormData:[self.parts objectForKey:partType] name:@"@json"];
                                                }
                                                else{ //is an image for sure
                                                    [formData appendPartWithFileData:[self.parts objectForKey:partType]
                                                                                name:partType
                                                                            fileName:[NSString stringWithFormat:@"%@-%d.jpg", partType, [partType hash]]
                                                                            mimeType:@"image/jpeg"];
                                                }

                                            }

                                            [formData throttleBandwidthWithPacketSize:kAFUploadStream3GSuggestedPacketSize delay:kAFUploadStream3GSuggestedDelay];
                                        }];

        AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

        [client enqueueHTTPRequestOperation:operation];
È stato utile?

Soluzione 2

Ok, after a lot of hours spent on this I finally got it. Nothing to do with the code, for some reason the company firewall is playing a role here. With the firewall turned off everything works fine. Strange, but that solves it, and is out of the iOS or code scope.

Altri suggerimenti

A clarification what the error means, and where it may come from:

You get this error when the request has been setup with an HTTPBodyStream and a Content-Length header explicitly set, and the input stream does not provide as much bytes as specified in the Content-Length header. That is, the underlaying connection got a EOF from the input stream before the stated number of bytes could have been read from the stream.

So, the cause could be an incorrectly calculated length of the content of the multipart body. This is quite likely, since calculating the length of the multipart is pretty error prone.

The error also occurs, if you got a redirect-response and the input stream has already been opened and possibly some data has been read. A redirect response requires that the input stream will be "rewind" so that it can be read from the start when the correct response will be received. This happens not automatically, and it must be explicitly implemented in the delegate. (Take a look at AFNetworking whether it "rewinds" the input stream somehow in case of a redirect - that is whether connection:needNewBodyStream: is implemented).

Possibly, I suspect, the error may also occur when there is some subtle dead lock, on the run loops which prevents the connection to read the stream - or the stream to read from its sources.

It may also happen, that this error is a side effect of another error - and that this error masks a the original one.

It may also be the case, that the internal subclass of a NSInputStream which is used to accomplish a multipart form request in AFNetworking has a bug. IMHO the implementation is a bit dubious, and elsewhere there is definitely a potential bug regarding streams.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top