Есть ли способ настроить php так, чтобы он всегда устанавливал $ _SERVER ['CONTENT_LENGTH']? - PullRequest
1 голос
/ 01 октября 2011

Я работаю на клиенте carddav.В качестве сервера я использую davical v. 0.9.9.6.Я не понимаю, почему я получаю недопустимую ошибку типа содержимого, когда заголовки http содержат правильное значение.Я смотрю в исходный код и нашел это условие:

if ( isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > 7) {...

После небольшого исследования я нашел php set $_SERVER['CONTENT_LENGTH'] только с методом POST и загрузкой файла.Есть ли способ настроить php, чтобы всегда устанавливать $_SERVER['CONTENT_LENGTH']?Я спрашиваю в целом, не только для этого случая ...

// РЕДАКТИРОВАТЬ Я делаю HTTP PUT-запрос к davical серверу (используя php curl).сторона - это условие тестирования CONTENT_LENGTH, которое не установлено.Значит, это давняя ошибка?

// РЕДАКТИРОВАТЬ 2

Наконец-то я это понял!PUT-запрос с функцией обратного вызова readfunc требует установки INFILE_SIZE с помощью curl_setopt (...). Отсутствует автоматическое значение, поэтому вводить поле Content-Length вручную в заголовок также неправильно.Пример (неверный):

// PUT REQUEST
curl_setopt($ch,CURLOPT_HTTPHEADER,"Content-Length: $length");  //mistake
curl_setopt($ch,CURLOPT_PUT,true);
curl_setopt($ch,CURLOPT_READFUNCTION,array($this,'readfunc'));
....
--------------------------------------------------------------
// WIRESHARK TCP STREAM DUMP
PUT /caldav.php/testuser/contacts/novy.vcf HTTP/1.1
Authorization: Basic xxxxxxxxxxxxxxx
Host: davical
Accept: */*
Content-Type: text/vcard
Content-Length: xxx
Expect: 100-continue

HTTP/1.1 100 Continue

155
BEGIN:VCARD
VERSION:3.0
...
END:VCARD

0

HTTP/1.1 200 OK
----------------------------------------------------------------
// On server side
isset($_SERVER['CONTENT_LENGTH'])==false

Второй (правильный) пример

// PUT REQUEST
curl_setopt($ch,CURLOPT_INFILESIZE,$length);
curl_setopt($ch,CURLOPT_PUT,true);
curl_setopt($ch,CURLOPT_READFUNCTION,array($this,'readfunc'));
....
--------------------------------------------------------------
// WIRESHARK TCP STREAM DUMP
PUT /caldav.php/testuser/contacts/novy.vcf HTTP/1.1
Authorization: Basic xxxxxxxxxxxxxxx
Host: davical
Accept: */*
Content-Type: text/vcard
Content-Length: xxx
Expect: 100-continue

HTTP/1.1 100 Continue

BEGIN:VCARD
VERSION:3.0
...
END:VCARD
HTTP/1.1 200 OK
----------------------------------------------------------------
// On server side
isset($_SERVER['CONTENT_LENGTH'])==true

Ответы [ 3 ]

1 голос
/ 01 октября 2011

Хотя я никогда не использовал CONTENT_LENGHT, я могу сказать вам, почему это, вероятно, происходит:

В запросе вам не нужно устанавливать заголовок Content-Lenght ... ЭТО НЕ ОБЯЗАТЕЛЬНО. За исключением особых ситуаций. Если ваш POST-контент имеет тип «multipart / form-data», становится необходимым использовать контент-длину для каждой части, потому что каждая часть отделена границей и каждая часть будет иметь свои собственные заголовки ...

Например:

Content-Type: MultiPart/Form-Data
Boundary: @FGJ4823024562DGGRT3455

MyData=1&Username=Blabla&Password=Blue


@FGJ4823024562DGGRT3455==
Content-Type: image/jpef:base64
Content-Lenght: 256

HNSIFRTGNOHVDFNSIAH$5346twSADVni56hntgsIGHFNR$Iasdf==

Итак, это грубый пример того, как работает многочастный запрос, вы видите, что вторая часть имеет длину контента. Вот почему иногда устанавливается длина содержимого, а иногда нет, потому что вам нужно прочитать байты Х, прежде чем найти другую границу и извлечь правильные данные.

Это не значит, что ваш сервер никогда не отправит его в других случаях, но мои 2 цента - это именно тот случай, который есть сейчас. Это потому, что вы находитесь не в режиме POST, а в некоторых других режимах.

1 голос
/ 01 октября 2011

Только запросы, которые имеют тело запроса , имеют заголовок запроса длины контента (или, по крайней мере, только тогда, когда это имеет смысл), и поэтому устанавливается переменная $_SERVER.вам нужно, чтобы он был всегда установлен (что я считаю фиктивным), вы можете сделать это самостоятельно в самом начале вашего сценария:

isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] = 0;

Предполагая, что если он не установлен, он имеет нулевую длину.См. Также Улучшена обработка HTTP-запросов в PHP .

0 голосов
/ 01 октября 2011

Возможно, вы могли бы установить их самостоятельно.Зачем вам нужно, чтобы эти значения были установлены?И что они должны установить?

Возможно, вам не хватает информации о $ _SERVER ['CONTENT_TYPE'] или $ _SERVER ['CONTENT_LENGTH'], как я это сделал.По POST-запросам они доступны в дополнение к перечисленным выше.

-> http://www.php.net/manual/en/reserved.variables.server.php#86495

...