Возвращаемые заголовки в ответ на запрос методом HEAD на Windows и Unix

Shadow_1512

Новичок
Возвращаемые заголовки в ответ на запрос методом HEAD на Windows и Unix

Суть проблемы:
есть некий софт, из которого человек может, нажав на кнопку обновить свою базу данных, для этого программа шлет сначала запрос методом HEAD на сервер, определяя имя файла, его длину, поддерживается ли докачка и пр., после чего уже шлет запрос методом GET.
На сервере эти 2 запроса обрабатываются по-разному, в ответ на первый шлются следующие заголовки:
PHP:
function getAnswerToHead($file)
  {
    $fsize = filesize($file);
    $range = 0;
    if(file_exists($file))
      {
        $handle = @fopen($file, "rb");
        if(getenv("HTTP_RANGE"))
          {
            $range = getenv("HTTP_RANGE");
            $range = str_replace("bytes=", "", $range);
            $range = str_replace("-", "", $range);
            fseek($handle, $range);
            header("HTTP/1.0 206 Partial Content\r\n");
          }
        else
          {
            header("HTTP/1.0 200 OK\r\n");
          }
        header("Pragma: no-cache\r\n");
        header("Expires: 0\r\n");
        header("Content-Type: application/force-download\r\n");
        header("Cache-Control: private\r\n");
        header("Content-Disposition: attachment; filename=" . basename($file) . "\r\n");
        header("Content-Transfer-Encoding: binary\r\n");
        header("Content-Length: ". ($fsize-$range) . "\r\n");
        header("Accept-Ranges: bytes\r\n");
        header("Content-Range: bytes $range-" . ($fsize-1) . "/" . $fsize . "\r\n");
        fclose($handle);
      }
    else
      {
//Файла нет.
        $this->text_answer = 'Empty File Request!';
        return false;
      }  
  }
Эта одна из функций класса, поэтому не удивляйтесь на $this. Параметром туда передается полный путь до файла.

В общем тут можно и остановиться - на Unix-машине на запрос методом HEAD сервер отвечает ровно то, что я его прошу. На Windows он отвечает в общем то же, но Content-Length заголовка просто нет. Проверял Снифферами - этот заголовок действительно сервером не посылается.
В чем соль?
 

Shadow_1512

Новичок
Автор оригинала: Кром
Content-Length это не обязательный заголовок.
Я понимаю, вопрос в другом - почему, когда я его задаю и хочу, чтобы сервер его передал, в случае, когда веб-сервер стоит на unix-машине все работает, а когда на windows - это единственный заголовок, который не передается?
 

Кром

Новичок
Т.е. ты хочешь сказать, что отсылешь его принудительно, а он не шлется?
 

Shadow_1512

Новичок
Автор оригинала: Кром
Т.е. ты хочешь сказать, что отсылешь его принудительно, а он не шлется?
PHP:
header("Pragma: no-cache\r\n");
        header("Expires: 0\r\n");
        header("Content-Type: application/force-download\r\n");
        header("Cache-Control: private\r\n");
        header("Content-Disposition: attachment; filename=" . basename($file) . "\r\n");
        header("Content-Transfer-Encoding: binary\r\n");
        header("Content-Length: ". ($fsize-$range) . "\r\n");
        header("Accept-Ranges: bytes\r\n");
        header("Content-Range: bytes $range-" . ($fsize-1) . "/" . $fsize . "\r\n");
У меня есть ощущение, что здесь я его принудительно шлю, а он не шлется:)
 

RigVan

Постоянный член клуба
Shadow_1512
Надо настройки сервера смотреть видимо, я тут тоже сейчас с похожим вопросом парюсь.. Некотрые заголовки можно, только в настройках менять...

или с помощью mod_security см. http://www.nextaz.com/showarticle.php?id=1114626882
 

Кром

Новичок
Shadow_1512
Попробуй убрать все заголовки кроме :
header("Content-Type: application/force-download\r\n");
header("Content-Length: ". ($fsize-$range) . "\r\n");

Ты уверен, что в $fsize-$range действительно что-то есть?

Как ты проверяешь, что заголовок не отослан?
 

Shadow_1512

Новичок
Автор оригинала: Кром
Shadow_1512
Попробуй убрать все заголовки кроме :
header("Content-Type: application/force-download\r\n");
header("Content-Length: ". ($fsize-$range) . "\r\n");

Ты уверен, что в $fsize-$range действительно что-то есть?

Как ты проверяешь, что заголовок не отослан?
Убрал, протестировал, не помогло.
Для того, чтобы быть уверенным, что дело не в том, что $fsize-$range может дать глюк (тогда бы кстати было бы отослан по идее заголовок Content-Length: 0) взял и поставил туда обыкновенное число, не помогло.

То, что заголовок не отослан я проверяю сниффером, т.е. смотрю, какие пакеты ушли с веб-сервера и смотрю их содержимое. Так вот в том пакете, в котором идут заголовки мои, заголовка Content-Length нет..

Еще один момент - если делать запрос методом GET, то заголовок Content-Length появляется. Не работает он именно в ответе на запрос методом HEAD...
 

Кром

Новичок
А какая версия сервера и используется ли прокси?
Ты можешь просто создать тестовую html страницу и проверить шлется ли Content-Length на этой странице?
Попробуй сменить протокол на http1.1 и посмотри как с ним будет работать.
 

Shadow_1512

Новичок
Автор оригинала: Кром
А какая версия сервера и используется ли прокси?
Ты можешь просто создать тестовую html страницу и проверить шлется ли Content-Length на этой странице?
Попробуй сменить протокол на http1.1 и посмотри как с ним будет работать.
Версия сервера 2.x (сильно не пинать за винду:)), прокси не используется, протокол уже 1.1, тестовый html создавал, результат тот же. Как только метод HEAD так никакого Content-Length заголовка, как только другой метод - все ок. Я в общем уже давно придумал, как обойти эту проблему, но она подразумевает изменения в базовом ПО (из которого шлются запросы), а это дело ныне невозможное....:(
 

Кром

Новичок
Может быть такой вариант, что Apache использует какой-либо фильтр. При этом фильт изменяет размер данных, и чтобы не возникало ошибки удаляет Content-Length заголовок.
 

Shadow_1512

Новичок
As the result:

Ради праздного любопытства переставил версию Апача на 1.3. И все сразу заработало. Параллельно еще парочка глюков ушла.
Так что вот такие предсказуемые чудеса.
 
Сверху