使用 NSURLConnection 从 iPhone 发出的 HTTPS POST 在特定文件大小范围内挂起

发布于 2024-10-06 13:23:00 字数 2013 浏览 1 评论 0原文

我正在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

余生共白头 2024-10-13 13:23:01

啊,我已经找到问题所在了。连接:保持活动状态正在设置,即使我设置了连接:关闭。我该如何覆盖这个?看来不能啊!?

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!?

南冥有猫 2024-10-13 13:23:01

我有以下代码,针对 30-40 MB 的文件进行了测试,并且它永远不会挂起。它看起来几乎与您的代码相似,但是您确定它不是您的服务器端脚本可能正在等待某些东西吗?

url = [NSURL URLWithString:u];

NSData* d = [self data];

request = [NSMutableURLRequest requestWithURL:url];
[request setTimeoutInterval: 2000 ];
[request setHTTPMethod:@"POST"];
[request setValue:
 [NSString stringWithFormat:@"multipart/form-data; boundary=%@", BOUNDRY]
forHTTPHeaderField:@"Content-Type"];

NSMutableData *postData =
[NSMutableData dataWithCapacity:[d length] + 512];
[postData appendData:
 [[NSString stringWithFormat:@"--%@\r\n", BOUNDRY] dataUsingEncoding:NSUTF8StringEncoding]];
[postData appendData:
 [[NSString stringWithFormat:
   @"Content-Disposition: form-data; name=\"%@\"; filename=\"file.bin\"\r\n\r\n", FORM_FLE_INPUT]
  dataUsingEncoding:NSUTF8StringEncoding]];
[postData appendData:d];
[postData appendData:
 [[NSString stringWithFormat:@"\r\n--%@--\r\n", BOUNDRY] dataUsingEncoding:NSUTF8StringEncoding]];

[request setHTTPBody:postData];

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?

url = [NSURL URLWithString:u];

NSData* d = [self data];

request = [NSMutableURLRequest requestWithURL:url];
[request setTimeoutInterval: 2000 ];
[request setHTTPMethod:@"POST"];
[request setValue:
 [NSString stringWithFormat:@"multipart/form-data; boundary=%@", BOUNDRY]
forHTTPHeaderField:@"Content-Type"];

NSMutableData *postData =
[NSMutableData dataWithCapacity:[d length] + 512];
[postData appendData:
 [[NSString stringWithFormat:@"--%@\r\n", BOUNDRY] dataUsingEncoding:NSUTF8StringEncoding]];
[postData appendData:
 [[NSString stringWithFormat:
   @"Content-Disposition: form-data; name=\"%@\"; filename=\"file.bin\"\r\n\r\n", FORM_FLE_INPUT]
  dataUsingEncoding:NSUTF8StringEncoding]];
[postData appendData:d];
[postData appendData:
 [[NSString stringWithFormat:@"\r\n--%@--\r\n", BOUNDRY] dataUsingEncoding:NSUTF8StringEncoding]];

[request setHTTPBody:postData];
一杯敬自由 2024-10-13 13:23:01

我想你可以尝试删除这行代码。

[request addValue:@"close" forHTTPHeaderField: @"Connection"];

它会告诉http服务器关闭这个连接。根据 RFC 2616 (HTTP/1.1),服务器和客户端应保持持久连接。

I think you can try to remove this line of codes.

[request addValue:@"close" forHTTPHeaderField: @"Connection"];

It will tell the http server to close this connection. By the RFC 2616 (HTTP/1.1), servers and clients should maintain persistent connection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文