Назад | Перейти на главную страницу

Как отключить поддержку активности в curl

Я пытаюсь выяснить, как последовательно отключать поддержку активности на различных клиентских машинах, которые выдают HTTP-запросы через curl.

Это мой целевой сервер:

- Ubuntu 18.04.2 LTS
- 4.15.0-47-generic
- HA-Proxy version 1.8.19-1ppa1~bionic 2019/02/12

Это клиент 1, откуда я выдаю curl (ванильная установка):

- Ubuntu 16.04.3 LTS
- 4.4.0-62-generic
- curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3

Это клиент 2, откуда я выдаю curl (ванильная установка):

- Ubuntu 18.04 LTS
- 4.15.0-20-generic
- curl 7.58.0 (x86_64-pc-linux-gnu) libcurl/7.58.0 OpenSSL/1.1.0g zlib/1.2.11 libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4) nghttp2/1.30.0 librtmp/2.3

Чтобы отключить поддержку активности, я пробовал использовать -H "Connection: close", --no-keepalive и --keepalive-time 1 и кажется, работает только первый вариант, но только от клиента 1.

На клиенте 1 (Ubuntu 16) соединение не остается открытым, но с клиента 2 (Ubuntu 18) соединение остается открытым до истечения времени ожидания. Я подтверждаю, что либо посмотрев на целевой сервер watch -n 0.1 "netstat -na | fgrep CLIENT_IP_ADDRESS" или используя -vvv на обоих клиентах, что на клиенте 1 всегда * Closing connection 0 а на клиенте 2 всегда * Connection #0 to host www.example.com left intact.

Разница между клиентом 1 и 2, очевидно, заключается в версии Ubuntu и версии curl. Что вызывает закрытие соединения на клиенте 1, но не на клиенте 2?

Я также узнал, что если я изменю свой целевой сервер на другую машину, на которой запущен старый дистрибутив со старым apache httpd, отправляю ли я Connection: close или нет, не имеет значения, и keepalive всегда используется одним из моих двух клиентов. Поэтому я полагаю, что конфигурация целевого сервера также играет в этом некоторую роль.

редактировать: Чтобы еще больше усложнить ситуацию, если от клиентов 1 и 2 я отправляю запросы на целевой сервер через ab то соединение разрывается мгновенно. Это ожидается, потому что ab использует HTTP/1.0 и нет HTTP/1.1. Но затем, если я нацелен на старый дистрибутив с помощью apache, в обоих случаях соединение останется открытым. Это означает, что принимающая сторона тоже играет роль.

Редактировать 2: Я все схватил /proc/sys/net/ipv4/ настройки обоих клиентов через:

for file in /proc/sys/net/ipv4/*
do
  echo "$file $(cat $file)"
done

и их можно найти здесь:

Параметр --no-keepalive полезен только для пакетов поддержки активности TCP, как упоминалось в этой заархивированной ветке на веб-сайте curl: https://curl.haxx.se/mail/archive-2013-04/0037.html

Похоже, вам нужно специально отключить HTTP-пакеты поддержки активности, что будет сделано на ваших серверах с помощью keepalive_timeout 0; как упоминалось в этом потоке stackoverflow https://stackoverflow.com/questions/24924237/linux-curlnginx-cant-request-with-no-keepalive.

Извините, если форматирование отключено, это мой первый пост :)

Надеюсь, это поможет!

За https://ec.haxx.se/usingcurl-persist.html

curl всегда будет пытаться поддерживать соединения и повторно использовать существующие соединения, насколько это возможно.

Следовательно, вы не можете использовать его, используя те инструменты, которые есть.

Как отметил @ pl-nowlan в своем ответе, единственный способ сделать это - на стороне сервера.

вы можете использовать опцию --no-keepalive. Смотрите больше на man curl

--no-keepalive Отключает использование сообщений keepalive для TCP-соединения, поскольку по умолчанию curl их включает.

Обратите внимание, что это задокументированное отрицательное имя параметра. Таким образом, вы можете использовать --keepalive для обеспечения активности.