Почему основанный на PHP HTTP-запрос не может разрешить частичное кодирование?

У меня есть сервис XML-over-HTTP, который довольно долго работал достаточно хорошо, и меня попросили предоставить пример PHP-кода для подключения к нему. Я написал код, и он подключается и т. Д. Просто отлично, за исключением того, что
он ожидает истечения времени ожидания активности (5 с) до завершения.

Когда я подключаюсь с помощью клиента на основе Java, я вижу, что Tomcat (через httpd) использует chunked-кодировку:

DEBUG: Request properties:
DEBUG: Accept-Charset: UTF-8, ISO-8859-1, *
DEBUG: Cache-Control: private, no-cache, no-store, no-transform
DEBUG: Accept: application/xml, text/xml, text/plain
DEBUG: User-Agent: My Awesome Java Client
DEBUG: Pragma: no-cache
DEBUG: Accept-Encoding: gzip, deflate
DEBUG: Content-Type: application/xml
DEBUG: Received first response packet after 219ms
DEBUG: Dumping HTTP response headers
DEBUG: Transfer-Encoding: chunked
DEBUG: Keep-Alive: timeout=5, max=100
DEBUG: null: HTTP/1.1 200 OK
DEBUG: Server: Apache/2.2.22 (Debian)
DEBUG: Connection: Keep-Alive
DEBUG: Date: Fri, 03 Feb 2017 15:33:13 GMT
DEBUG: Content-Type: application/xml;charset=UTF-8
DEBUG: Read response in 7ms

Когда я использую клиент PHP, вот что я получаю в заголовках ответов:

array(6) {
[0]=>
string(15) "HTTP/1.1 200 OK"[1]=>
string(35) "Date: Fri, 03 Feb 2017 15:37:01 GMT"[2]=>
string(30) "Server: Apache/2.2.22 (Debian)"[3]=>
string(30) "Keep-Alive: timeout=5, max=100"[4]=>
string(22) "Connection: Keep-Alive"[5]=>
string(43) "Content-Type: application/xml;charset=UTF-8"}

Обратите внимание, что нет никаких Transfer-Encoding: chunked заголовок ответа.

Я могу подтвердить, что клиент PHP делает запрос HTTP / 1.1 (и
ответ использует HTTP / 1.1, как вы можете видеть), но кодирование по частям
кажется, не используется здесь.

Я полагаю, что отправляю те же заголовки запроса от клиента PHP.
Вот что видит сервер:

2017-02-03 10:44:59,287 [catalina-exec-2] TRACE MyServlet- [1d] ========== Request from x.y.113.203
2017-02-03 10:44:59,287 [catalina-exec-2] TRACE MyServlet- [1d] host: example.com
2017-02-03 10:44:59,287 [catalina-exec-2] TRACE MyServlet- [1d] content-length: 135
2017-02-03 10:44:59,287 [catalina-exec-2] TRACE MyServlet- [1d] content-type: application/xml
2017-02-03 10:44:59,287 [catalina-exec-2] TRACE MyServlet- [1d] user-agent: My Awesome PHP Client
2017-02-03 10:44:59,287 [catalina-exec-2] TRACE MyServlet- [1d] accept: application/xml, text/xml, text/plain
2017-02-03 10:44:59,287 [catalina-exec-2] TRACE MyServlet- [1d] Accept-Charset: UTF-8, ISO-8859-1, *
2017-02-03 10:44:59,288 [catalina-exec-2] TRACE MyServlet- [1d] Accept-Encoding: gzip, deflate
2017-02-03 10:44:59,288 [catalina-exec-2] TRACE MyServlet- [1d] Cache-Control: private, no-cache, no-store, no-transform
2017-02-03 10:44:59,288 [catalina-exec-2] TRACE MyServlet- [1d] pragma: no-cache
2017-02-03 10:44:59,288 [catalina-exec-2] TRACE MyServlet- [1d] connection: keep-alive

И то же самое с клиентом Java:

2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] ========== Request from x.y.113.203
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] user-agent: My Awesome Java Client
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] content-type: application/xml
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] accept: application/xml, text/xml, text/plain
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] Accept-Encoding: gzip, deflate
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] Accept-Charset: UTF-8, ISO-8859-1, *
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] Cache-Control: private, no-cache, no-store, no-transform
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] pragma: no-cache
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] host:
example.com
2017-02-03 10:46:33,684 [catalina-exec-3] TRACE MyServlet- [1e] connection: keep-alive
2017-02-03 10:46:33,685 [catalina-exec-3] TRACE MyServlet- [1e] content-length: 135

Я использую ту же полезную нагрузку «call», и ответ должен быть идентичным
для двух клиентов.

Если я добавлю Connection: close к заголовкам из PHP-клиента, то
вызов завершается немедленно без 5-секундной задержки.

PHP задокументирован для поддержки чанкованного кодирования, но сервер не поддерживает
похоже, что он даже пытается использовать кусочную кодировку, так как ответ
Заголовки ничего не говорят об этом. Код PHP выглядит следующим образом:

$options = array(
'http' => array(
'header' => array('Content-Type: application/xml',
'User-Agent: My Awesome PHP Client',
'Accept: application/xml, text/xml, text/plain',
'Accept-Charset: UTF-8, ISO-8859-1, *',
'Accept-Encoding: gzip, deflate',
'Cache-Control: private, no-cache, no-store, no-transform',
'Pragma: no-cache',

// NOTE: Connection: close makes multiple calls less efficient, but file_get_contents seems to stall otherwise
//                              'Connection: close'
'Connection: keep-alive',
),
'follow_location' => 0, // Don't follow redirects
'protocol_version' => '1.1',
'ignore_errors' => TRUE, // Does not dump ugly errors to stderr
'timeout' => 0.01, // TODO: adjustable
'method'  => 'POST',
'content' => $message,
),
'ssl' => array(
'disable_compression' => TRUE,
'ciphers' => '!aNULL:!eNULL:!EXPORT:!DSS:!DES:!3DES:!SSLv2:!RC4:!MD5:ECDHE:ECDH',
)
);

$context = stream_context_create($options);

$result = file_get_contents($url, false, $context);

var_dump($http_response_header);

Любые идеи относительно того, что может происходить? Я полагаю, что если используется chunked-кодировка, клиент не остановится в ожидании дополнительной информации, когда ответ фактически завершен.

Обратите внимание, что ответ должен быть либо разделенным на части, либо по тайм-ауту, поскольку динамический и потоковый характер ответа не может иметь content-length предварительно вычисляется и отправляется в заголовке ответа HTTP.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …