Код состояния HTTP 411 - Требуемая длина

Я пытаюсь получить данные с сервера. Я использую NSURLConnectionDelegate, NSURLConnectionDataDelegate. Существует код (Objective-C).

-(void)sendRequest
{
NSURL* url = [[NSURL alloc] initWithString:@"http://SomeServer"];

NSMutableURLRequest* request = [[NSMutableURLRequest alloc] init];


NSString* reqBody = [NSString stringWithFormat:@"<tag>Content</tag>"];

NSData* reqData = [reqBody dataUsingEncoding:NSUTF8StringEncoding];

NSInputStream* stream = [NSInputStream inputStreamWithData:reqData];



[request setURL:url];
[request setHTTPBodyStream:stream];
[request setHTTPMethod:@"POST"];

self.wpData = [[NSMutableData alloc] init];
NSURLConnection* conection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

[conection start];

}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

    [self.wpData setLength:0];    

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)d {
NSString* str = [[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding];

NSLog(@"RESPONSE DATA: %@",str);
[self.wpData appendData:d];
}

Но я получаю "411 - Length Required", когда я использую

[request setHTTPBodyStream:stream];

и "HASH (someAddress)", когда я использую

[request setHTTPBody:reqData];

Я пробовал

[request setHTTPBodyStream:stream];
NSString *postLength = [NSString stringWithFormat:@"%d", [reqData length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];

но снова "HASH (someAdddress)"

Чем я ошибся? Извините за мой английский. Спасибо:)

Ответ 1

Чем я ошибся?

Ничего.

Код состояния HTTP 411 (требуемая длина) отправляется сервером в качестве ответа, когда он отказывается принимать сообщение без заголовка длины содержимого по любой причине.

Сервер просто может принимать или не принимать контент без заголовка Content-Length.

Когда вы устанавливаете объект NSInputStream в качестве тела запроса через свойство HTTPBodyStream для запроса, NSURLConnection больше не может оценивать длину самого тела. (для потока нет свойства length). Следовательно, NSURLConnection использует определенный "режим передачи", а именно "закодированное кодирование передачи". Этот режим передачи должен преуспеть для передачи любого тела, и ему не нужен заголовок Content-Legth (на самом деле он не должен содержать один). Увы, сервер просто не принимает этот тип передачи.

Смотрите также: Chunked transfer encoding (wiki).

Чтобы решить проблему на стороне клиента:

  • Определите длину тела самостоятельно (если возможно) и установите поле заголовка Content-Length для запроса. Если этот входной поток был создан из файла или из объекта NSData, длина может быть легко определена. Но не забудьте установить ту же длину, что и фактическое содержимое потока в байтах.

  • Не используйте NSInputStream, но используйте объект NSData как тело и установите его через свойство HTTPBody. Когда вы устанавливаете тело как объект NSData, NSURLConnection может самостоятельно определить длину содержимого, и он автоматически добавит заголовок Content-Length с правильной длиной, если вы не установите его самостоятельно в запросе.