Ответ от PHP без HTTP заголовков

vikingmrboo

Новичок
Очень часто встречаюсь с проблемой, когда для реализации простого ответа, приходится использовать другой язык.
Суть проблемы: при закрытии основного буфера, php отправляет все заготовленные заголовки ( HTTP/1.1 200 OK\r\nContnet-Type:...\r\n\r\n), а требуется в ответе вывести некую строчку, на пример "OK".
Но есть еще одна задача. Раз в 20 сек отправлять HTTP/1.1 102 Processing. А после первого же flush(), пыха отправляет \r\n\r\n
Пару дней спрашивал гугл, умеет ли php как perl не выводить http заголовки. Все что приводилось в примерах, не работает для php-fcgid.
Придется вкомпиливать что-то свое, реализовать на другом языке, или все таки PHP умеет не отправлять заголовки?
 

Redjik

Джедай-мастер
тоже задумался изначально, зачем использовать протокол http, если нужен невалидный ответ?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
при закрытии основного буфера, php отправляет все заготовленные заголовки ( HTTP/1.1 200 OK\r\nContnet-Type:...\r\n\r\n)
откуда информация, что статусную строку ответа (HTTP/1.1 200 OK) возвращает именно php, а не nginx?
в спецификации fcgi такого нет
http://fastcgi.com/devkit/doc/fcgi-spec.html#SB
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
А что невалидного в 10x кодах, специалисты? Другое дело, что на php-cgi/fpm это нереализуемо, надо брать какой-нибудь phpdaemon.
 

fixxxer

К.О.
Партнер клуба
102 Processing (WebDAV; RFC 2518)
As a WebDAV request may contain many sub-requests involving file operations, it may take a long time to complete the request. This code indicates that the server has received and is processing the request, but no response is available yet.[3] This prevents the client from timing out and assuming the request was lost
что не так?
 

fixxxer

К.О.
Партнер клуба
И чем не устраивают 20 секунд? Ну можно 15. Или 25.
 

fixxxer

К.О.
Партнер клуба
По RFC, кстати, таки 20:

10.1 102 Processing

The 102 (Processing) status code is an interim response used to
inform the client that the server has accepted the complete request,
but has not yet completed it. This status code SHOULD only be sent
when the server has a reasonable expectation that the request will
take significant time to complete. As guidance, if a method is taking
longer than 20 seconds (a reasonable, but arbitrary value) to process
the server SHOULD return a 102 (Processing) response. The server MUST
send a final response after the request has been completed.

Methods can potentially take a long period of time to process,
especially methods that support the Depth header. In such cases the
client may time-out the connection while waiting for a response. To
prevent this the server may return a 102 (Processing) status code to
indicate to the client that the server is still processing the
method.
 

WMix

герр M:)ller
Партнер клуба
PHP:
 /* бред */
 
Последнее редактирование:

WMix

герр M:)ller
Партнер клуба
я не понимаю как это должно работать, я привык к законченому запросу ответу.
 

fixxxer

К.О.
Партнер клуба
А ответ 102 только в вебдаве и есть. То есть, либо ТС делает webdav-сервер, либо какую-то неведомую хрень =)
 

WMix

герр M:)ller
Партнер клуба
я идею понял (там где слово бред), подумал о зокетах, обратил внимание на демона, но чет перепробывав, не разобрался как сложить.
 

fixxxer

К.О.
Партнер клуба
Да элементарно это работает. Пишу псевдокодом специально

PHP:
function DavServer::processRequest($Request, $Response) {
    $ProcessingThread = new ProcessingThread($Request);
    $TimerThread = new TimerThread(20);
    $TimerThread->onTick(function() {
        $Response->write("HTTP/1.1 102 Processing" . CRLF . CRLF);
    });
    $ProcessingThread->onDone(function($result) {
        $TimerThread->stop();
        $Response->write("HTTP/1.1 200 OK" . CRLF . CRLF . $result);
    });
    $TimerThread->run();
    $ProcessingThread->run();
}
C точки зрения протокола тоже все банально:

Код:
> GET /LongDavRequest HTTP/1.1
> Host: dav.server
>
[...20 sec...]
< HTTP/1.1 102 Processing
<
[...20 sec...]
< HTTP/1.1 102 Processing
<
[...]
< HTTP/1.1 200 OK
<
< result..
 
Последнее редактирование:

vikingmrboo

Новичок
Огромное спасибо, за интерес к теме. Попробую разобрать все по порядку:
  • точно понимаешь как работает http? или http://php.net/manual/en/function.header.php это ищешь?
    : понимаю, раз в 20 секунд отправлять заголовок HTTP/1.1 102 Processing, не закрывая блок заголовков (вторым \r\n), так как nginx все следующее считает контентом и проксирует клиенту, а тот, считает что это контент. Нужен именно header но который не будет выдавать результат в буфер а сразу в ответ, в реалтайме, без вывода системных заголовков
  • тоже задумался изначально, зачем использовать протокол http, если нужен невалидный ответ?
    : это скорее для интереса, "можно ли?". А система такая, один модуль приложения хорошо знает HTTP, но он делает авторизацию и потом передает управление другому модулю, который HTTP не знает, самым правильным выходом, это научить его общаться на хттп, не спорю.

    откуда информация, что статусную строку ответа (HTTP/1.1 200 OK) возвращает именно php, а не nginx?
    в спецификации fcgi такого нет
    http://fastcgi.com/devkit/doc/fcgi-spec.html#SB
    : именно php, это легко определить, подключившись к cgi
    Код:
    curl -i "http://127.0.0.1:10080/index.php" -H "Host: my.local"
    Да элементарно это работает. Пишу псевдокодом специально

    PHP:
    function DavServer::processRequest($Request, $Response) {
        $ProcessingThread = new ProcessingThread($Request);
        $TimerThread = new TimerThread(20);
        $TimerThread->onTick(function() {
            $Response->write("HTTP/1.1 102 Processing" . CRLF . CRLF);
        });
        $ProcessingThread->onDone(function($result) {
            $TimerThread->stop();
            $Response->write("HTTP/1.1 200 OK" . CRLF . CRLF . $result);
        });
        $TimerThread->run();
        $ProcessingThread->run();
    }
    C точки зрения протокола тоже все банально:

    Код:
    > GET /LongDavRequest HTTP/1.1
    > Host: dav.server
    >
    [...20 sec...]
    < HTTP/1.1 102 Processing
    <
    [...20 sec...]
    < HTTP/1.1 102 Processing
    <
    [...]
    < HTTP/1.1 200 OK
    <
    < result..
    Спасибо за поддержку, да именно это и нужно, с небольшим отличаем
    Код:
    > GET /LongDavRequest HTTP/1.1
    > Host: dav.server
    >
    [...20 sec...]
    < HTTP/1.1 102 Processing
    [...20 sec...]
    < HTTP/1.1 102 Processing
    [...]
    < HTTP/1.1 200 OK
    <
    < result..
    так как после передачи второго \r\n клиент (браузер) считает что это должно быть контентом
 

fixxxer

К.О.
Партнер клуба
Браузер все правильно считает, он не умеет заголовок 102. Его понимают только вебдав-клиенты.

В случае с браузером надо делать поллинг.
 
Сверху