Как сообщить прокси, что соединение все еще используется с помощью HTTP-связи?

У меня есть приложение с графическим интерфейсом на стороне клиента для использования человеком, которое использует некоторые веб-службы SOAP и использует cURL в качестве базовой библиотеки связи HTTP. В зависимости от ввода обработка запроса может занять некоторое время, даже один час. Ни клиент, ни сервер не отключаются по этой причине сами по себе, и это проверено и работает. В любом случае, большинство запросов обрабатываются за несколько минут, так что это крайний случай.

Один из моих пользователей вынужден использовать прокси-сервер между моим клиентским приложением и моим сервером и по разным причинам не может его контролировать. У этого прокси настроено время ожидания, и он закрывает соединение с моим клиентом через 4 минуты без передачи данных. Таким образом, пользователь может (и делал) загружать данные, например. 30 минут, после чего сервер начинает обрабатывать данные и через 4 минуты прокси закрывает соединение, сервер молча продолжает обрабатывать запрос, но пользователь остается с сообщением об ошибке И не получает результат обработки. Мое приложение уже использует TCP Keep Alive, так что это не должно быть проблемой, но вместо этого тайм-аут, похоже, определен для данных более высокого уровня. Он работает так же, как опция read_timeout для squid, которую я использовал для воспроизведения поведение в нашей внутренней настройке.

Что я хотел бы сделать сейчас, так это запустить фоновый поток в моем веб-сервисе, который просто выводит некоторые данные мусора моему клиенту за все время обработки запроса, который игнорируется клиентом и сообщает прокси-серверу, что соединение все еще активно . Я могу распознать своего клиента с помощью пользовательского агента и могу настроить, выводить ли эти данные или нет на стороне сервера и тому подобное, чтобы у других клиентов, использующих веб-службу, не было проблем.

Я прошу, есть ли какой-либо HTTP-совместимый метод для вывода таких мусорных данных до фактического ответа HTTP? Так, например. будет ли достаточно просто выводить \r\n без какого-либо дополнительного контента снова и снова, чтобы быть совместимым с HTTP со всеми запрашивающими библиотеками? Или, может быть, даже двоичный 0? Или некоторые полноценные заголовки HTTP, в которых говорится что-то вроде «настоящий ответ скоро придет, пожалуйста, наберитесь терпения»? Судя по моему исследованию, это в значительной степени похоже на кодирование HTTP по частям, но я еще не уверен, применимо ли это.

Я хотел бы иметь следующее, где все эти «подождите» просто игнорируются в конце, а реальный ответ HTTP в конце содержит Content-Length и тому подобное.

Wait...\r\n
Wait...\r\n
Wait...\r\n
[...]
HTTP/1.1 200 OK\r\n
Server: Apache/2.4.23 (Win64) mod_jk/1.2.41\r\n
[...]
<?xml version="1.0" encoding="UTF-8"?><soap:Envelope[...]

Возможно ли это каким-то стандартным способом HTTP, и если да, то какой подход мне нужно использовать? Спасибо!

Статус HTTP 102

Разве HTTP-статус 102 — это не то, что мне нужно? Насколько я понимаю спецификацию, я могу просто печатать эту строку ответа снова и снова, пока не будет готов окончательный ответ?


person Thorsten Schöning    schedule 07.10.2016    source источник


Ответы (1)


Статус HTTP 102 был тупиковым, две вещи могли работать, в зависимости от используемого прокси: Скрипт NPH можно использовать для регулярной печати заголовков непосредственно клиенту. Важно то, что сценарии NPH обычно обходят буферы заголовков с веб-сервера и поэтому могут передаваться по сети по мере необходимости. Они «только» должны быть правильными заголовками HTTP, и в зависимости от веб-сервера и прокси-сервера и т. д. может быть хорошей идеей создавать увеличивающиеся уникальные заголовки. Просто добавив счетчик в имя заголовка.

Во-вторых, это фрагментированное кодирование передачи, и в этом случае можно распечатать небольшие фрагменты фиктивных данных. клиенту в теле ответа. Хорошо то, что такой небольшой объем данных может быть передан по сети по мере необходимости с использованием сброса на стороне сервера и тому подобное, плохо то, что клиент получает эти данные и по умолчанию ведет себя так, как если бы они были частью ожидаемого тела ответа. Это, конечно, может сломать приложение, но большинство HTTP-библиотек предоставляют обратные вызовы для обработки полученных данных, и если вы печатаете какой-то уникальный, клиент должен иметь возможность отфильтровывать мусор.

В моем случае веб-служба порождает некоторый фоновый поток и в зависимости от точки входа запрошенной службы либо печатает заголовки, используя NPH, либо фрагменты данных. В обоих случаях данные могут быть одними и теми же, поэтому заголовок NPH можно использовать и для фрагментированного кодирования передачи.

Мое решение NPH не работает со Squid, но решение с фрагментами работает. Проблема со Squid заключается в том, что его настройка read_timeout не является низким уровнем для соединения, чтобы вообще получать данные, а вместо этого является какой-то логической вещью HTTP. Это означает, что Squid получает мои заголовки, но ожидает полный HTTP-заголовок в течение периода времени, определенного с помощью read_timeout. С моим подходом NPH это не так, просто потому, что по замыслу я хочу только отправлять некоторые мусорные заголовки, чтобы игнорировать их, пока не поступят настоящие заголовки.

Кроме того, нужно быть осторожным с NPH в Apache httpd, но в моем случае это работает. Я вижу отдельные заголовки в журнале Squid и без мусора после тела ответа или чего-то подобного. Избегайте директивы Action.

Apache2 отправляет два заголовка HTTP с сопоставленным nph-CGI< /а>

person Thorsten Schöning    schedule 20.10.2016