HTTPS POST от iPhone с использованием NSURLConnection зависает для определенного диапазона размеров файла - PullRequest
5 голосов
/ 08 декабря 2010

Я использую NSURLConnection для создания асинхронного HTTPS POST в нашем веб-сервисе для загрузки jpg.Большую часть времени он работает нормально.

Но когда размер тела сообщения составляет от 196609 до 196868 байт (включительно), соединение зависает после того, как файл загружен на 100% (didSendBodyData сообщает, что он отправлен на 100%),Затем через 5 минут истекает время соединения с сообщением «Сетевое соединение потеряно».Большие и меньшие размеры файлов работают.Я проверил это, ограничив размер файла файла, который я добавляю в тело сообщения.

Длина содержимого установлена ​​правильно.См. Код ниже.

Загрузка выглядит нормально, когда я загружаю в netcat через HTTP.Все тело сообщения проходит.Но я подозреваю, что что-то идет не так из-за шифрования SSL, например, он буферизует зашифрованный кадр блока SSL.

Есть ли ошибка в коде SSL iPhone, из-за которой он не загружает весь текст сообщения, даже если он сообщает, чтоэто или что-то еще?

Вот раздел, в котором я устанавливаю длину содержимого и добавляю файл в тело 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] );

Ответы [ 3 ]

3 голосов
/ 08 декабря 2010

Ах, я нашел, в чем проблема. Соединение: устанавливается Keep-alive, хотя я установил соединение: закрыть. Как мне переопределить это? Похоже, вы не можете!?

1 голос
/ 08 декабря 2010

Я думаю, вы можете попытаться удалить эту строку кодов.

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

Он скажет http-серверу закрыть это соединение. Согласно RFC 2616 (HTTP / 1.1) серверы и клиенты должны поддерживать постоянное соединение.

1 голос
/ 08 декабря 2010

У меня есть следующий код, который проверен на 30-40 МБ файлов, и он никогда не зависает. Он выглядит почти так же, как и ваш код, однако вы уверены, что это не ваш серверный скрипт, который может чего-то ждать?

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];
...