Сетевая ошибка при отправке файла через http сообщение с NSMutableURLRequest - PullRequest
1 голос
/ 16 ноября 2011

У меня проблема с использованием setHTTPBodyStream вместо setHTTPBody с NSMutableURLRequest.

Я работаю над кодом для отправки большого файла на сервер через HTTP-пост. Со следующей порцией кода все работает отлично:

NSData * mydata = [NSData dataWithContentsOfFile:self.tmpFileLocationToUpload];
[request setHTTPBody:mydata];

Если я изменю его на:

NSData * mydata = [NSData dataWithContentsOfFile:self.tmpFileLocationToUpload];
self.tmpInputStream = [NSInputStream inputStreamWithData:mydata];
[request setHTTPBodyStream: self.tmpInputStream];

Тогда я всегда заканчиваю с ошибкой в ​​сети: Ошибка - Операция не может быть завершена. (kCFErrorDomainCFNetwork ошибка 303.)

Цель состоит в том, чтобы в конце создать inputStrem непосредственно из файла, чтобы иметь возможность отправлять большие файлы без загрузки их в память.

Я что-то пропустил с использованием setHTTPBodyStream?

Спасибо за вашу помощь.

С уважением. Себастьен.

Ответы [ 2 ]

1 голос
/ 09 января 2014

Когда вы используете setHTTPBody, он автоматически устанавливает заголовок Content-length запроса, но когда вы используете setHTTPBodyStream, он не устанавливает, а скорее устанавливает Transfer-encoding из chunked. chunked кодирование передачи используется, когда длина потока не может быть определена заранее. (См. Кодировка передачи по частям .)

При использовании NSURLConnection в сочетании с setHTTPBodyStream вы можете вручную установить Content-length, и это предотвратит Transfer-encoding из chunked (при условии, что вы заранее знаете длину):

NSString *contentLength = [NSString stringWithFormat:@"%d", [mydata length]];
[request setValue:contentLength forHTTPHeaderField:@"Content-length"];

При использовании NSURLSession попытки вручную установить Content-length в сочетании с фрагментарным запросом могут не помешать ему быть chunked запросом.

1 голос
/ 10 апреля 2012

Попробуйте установить метод HTTP (если вы еще этого не сделали).Мне удалось исправить ошибку «kCFErrorDomainCFNetwork error 303», добавив:

[request setHTTPMethod:@"POST"];
...