使用 NSURLConnection 从 iPhone 发出的 HTTPS POST 在特定文件大小范围内挂起
我正在使用 NSURLConnection 向我们的网络服务发送异步 HTTPS POST 来上传 jpg。大多数时候它工作得很好。
但是,当帖子正文在 196609 到 196868 字节(含)之间时,连接在文件上传 100% 后挂起(didSendBodyData 告诉我它已 100% 发送)。 5 分钟后,连接超时并显示消息“网络连接丢失”。更大和更小的文件大小都可以工作。我通过限制添加到帖子正文的文件的文件大小对此进行了测试。
内容长度设置正确。请参阅下面的代码。
当我通过 HTTP 上传到 netcat 时,上传看起来很好。消息的整个正文都通过了。但我怀疑由于 SSL 加密而出现问题,就像它正在缓冲 SSL 加密的块帧一样。
iPhone 的 SSL 代码中是否存在错误,导致它无法上传整个帖子正文,即使它报告已上传,还是其他原因?
这是我设置内容长度并将文件附加到多部分 POST 正文的部分。您可以看到我正在手动限制文件大小以进行测试。
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:nsurl];
[request setHTTPMethod:@"POST"];
[request setTimeoutInterval:1];
[request addValue:@"close" forHTTPHeaderField: @"Connection"];
// Add headers and POST information
NSLog( @"Posting file." );
NSString *stringBoundary = [NSString stringWithString:@"0xKhTmLbOuNdArY"];
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
NSMutableData *postBody = [NSMutableData data];
...
[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"uploadFile\"; filename=\"upload.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithString:@"Content-Type: image/jpg\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
NSLog( @"file size...%d", [uploadFile length] );
//[postBody appendData:uploadFile];
[postBody appendData:[NSData dataWithBytes: [uploadFile bytes] length: 196099]];
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postBody];
[request setValue:[NSString stringWithFormat:@"%d", [postBody length]] forHTTPHeaderField:@"Content-Length"];
NSLog(@"Uploaded POST size: %d", [postBody length] );
I'm using NSURLConnection to make an async HTTPS POST to our webservice to upload a jpg. It works fine most of the time.
But when the post body is between 196609 and 196868 bytes (inclusive), the connection hangs after the file has been uploaded 100% (didSendBodyData tells me that it's 100% sent). Then after 5 minutes, the connection times out with the message "The network connection was lost." Larger and smaller filesizes work. I've tested this by capping the filesize of the file that I add to the post body.
The content length is getting set correctly. See the code below.
The upload looks fine when I upload to netcat via HTTP. The entire body of the message gets through. But I suspect something's going wrong because of the SSL encryption, like it's buffering an SSL encrypted block frame.
Is there a bug in the iPhone's SSL code that makes it not upload the entire post body even though it's reporting that it is, or something else?
Here's the section where I set the content length and append the file to the multi-part POST body. You can see i'm capping the filesize manually, to test.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:nsurl];
[request setHTTPMethod:@"POST"];
[request setTimeoutInterval:1];
[request addValue:@"close" forHTTPHeaderField: @"Connection"];
// Add headers and POST information
NSLog( @"Posting file." );
NSString *stringBoundary = [NSString stringWithString:@"0xKhTmLbOuNdArY"];
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
NSMutableData *postBody = [NSMutableData data];
...
[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"uploadFile\"; filename=\"upload.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithString:@"Content-Type: image/jpg\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
NSLog( @"file size...%d", [uploadFile length] );
//[postBody appendData:uploadFile];
[postBody appendData:[NSData dataWithBytes: [uploadFile bytes] length: 196099]];
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postBody];
[request setValue:[NSString stringWithFormat:@"%d", [postBody length]] forHTTPHeaderField:@"Content-Length"];
NSLog(@"Uploaded POST size: %d", [postBody length] );
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
啊,我已经找到问题所在了。连接:保持活动状态正在设置,即使我设置了连接:关闭。我该如何覆盖这个?看来不能啊!?
Ah, I've found what the issue is. Connection: Keep-alive is being set, even though I set connection: close. How do I override this?? It looks like you can't!?
我有以下代码,针对 30-40 MB 的文件进行了测试,并且它永远不会挂起。它看起来几乎与您的代码相似,但是您确定它不是您的服务器端脚本可能正在等待某些东西吗?
I have following code that is tested for 30-40 MB of files, and it never hangs. It looks almost similar to your code, however are you sure that its not your server side scrip that may be waiting for something?
我想你可以尝试删除这行代码。
它会告诉http服务器关闭这个连接。根据 RFC 2616 (HTTP/1.1),服务器和客户端应保持持久连接。
I think you can try to remove this line of codes.
It will tell the http server to close this connection. By the RFC 2616 (HTTP/1.1), servers and clients should maintain persistent connection.