Запрос отбрасывания прокси Squid сделан с netcat, но не curl
Мне нужно сделать REST-вызов в рамках кикстарта RHEL %pre
сценарий, и поэтому я ограничен использованием Netcat (так как wget
упаковано в RHEL %pre
среда не может настроить метод HTTP). Я бы конечно хотел использовать curl
(так как он имеет прекрасный -X
вариант) но увы это не доступно в %pre
среда.
Тем не менее, вот соответствующий curl
команда и, что важно, точный поток байтов, который он отправляет на сервер:
$ curl -X POST http://pkrizak-globalpxe.anonycom.com/univac/api/record/pkrizak-sles10.anonycom.com/_install_log --data-binary '[ ]' --trace /tmp/foo.log
$ cat /tmp/foo.log (truncated)
== Info: About to connect() to pkrizak-globalpxe.anonycom.com port 80 (#0)
== Info: Trying 10.46.174.117... == Info: connected
== Info: Connected to pkrizak-globalpxe.anonycom.com (10.46.174.117) port 80 (#0)
=> Send header, 312 bytes (0x138)
0000: 50 4f 53 54 20 2f 75 6e 69 76 61 63 2f 61 70 69 POST /univac/api
0010: 2f 72 65 63 6f 72 64 2f 70 6b 72 69 7a 61 6b 2d /record/pkrizak-
0020: 73 6c 65 73 31 30 2e 61 63 6f 63 79 63 6f 6d 2e sles10.anonycom.
0030: 63 6f 6d 2f 5f 69 6e 73 74 61 6c 6c 5f 6c 6f 67 com/_install_log
0040: 20 48 54 54 50 2f 31 2e 31 0d 0a 55 73 65 72 2d HTTP/1.1..User-
0050: 41 67 65 6e 74 3a 20 63 75 72 6c 2f 37 2e 31 39 Agent: curl/7.19
0060: 2e 37 20 28 78 38 36 5f 36 34 2d 72 65 64 68 61 .7 (x86_64-redha
0070: 74 2d 6c 69 6e 75 78 2d 67 6e 75 29 20 6c 69 62 t-linux-gnu) lib
0080: 63 75 72 6c 2f 37 2e 31 39 2e 37 20 4e 53 53 2f curl/7.19.7 NSS/
0090: 33 2e 31 34 2e 33 2e 30 20 7a 6c 69 62 2f 31 2e 3.14.3.0 zlib/1.
00a0: 32 2e 33 20 6c 69 62 69 64 6e 2f 31 2e 31 38 20 2.3 libidn/1.18
00b0: 6c 69 62 73 73 68 32 2f 31 2e 34 2e 32 0d 0a 48 libssh2/1.4.2..H
00c0: 6f 73 74 3a 20 70 6b 72 69 7a 61 6b 2d 67 6c 6f ost: pkrizak-glo
00d0: 62 61 6c 70 78 65 2e 61 63 6f 63 79 63 6f 6d 2e balpxe.anonycom.
00e0: 63 6f 6d 0d 0a 41 63 63 65 70 74 3a 20 2a 2f 2a com..Accept: */*
00f0: 0d 0a 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 ..Content-Length
0100: 3a 20 33 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 : 3..Content-Typ
0110: 65 3a 20 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 e: application/x
0120: 2d 77 77 77 2d 66 6f 72 6d 2d 75 72 6c 65 6e 63 -www-form-urlenc
0130: 6f 64 65 64 0d 0a 0d 0a oded....
=> Send data, 3 bytes (0x3)
0000: 5b 20 5d [ ]
== Info: HTTP 1.0, assume close after body
<= Recv header, 24 bytes (0x18)
Остальное я обрезал, но достаточно сказать, что транзакция продолжается без проблем.
Теперь отправим тот же поток байтов с помощью netcat:
$ ./mypost.sh | hexdump -C
00000000 50 4f 53 54 20 2f 75 6e 69 76 61 63 2f 61 70 69 |POST /univac/api|
00000010 2f 72 65 63 6f 72 64 2f 70 6b 72 69 7a 61 6b 2d |/record/pkrizak-|
00000020 73 6c 65 73 31 30 2e 61 63 6f 63 79 63 6f 6d 2e |sles10.anonycom.|
00000030 63 6f 6d 2f 5f 69 6e 73 74 61 6c 6c 5f 6c 6f 67 |com/_install_log|
00000040 20 48 54 54 50 2f 31 2e 31 0d 0a 55 73 65 72 2d | HTTP/1.1..User-|
00000050 41 67 65 6e 74 3a 20 63 75 72 6c 2f 37 2e 31 39 |Agent: curl/7.19|
00000060 2e 37 20 28 78 38 36 5f 36 34 2d 72 65 64 68 61 |.7 (x86_64-redha|
00000070 74 2d 6c 69 6e 75 78 2d 67 6e 75 29 20 6c 69 62 |t-linux-gnu) lib|
00000080 63 75 72 6c 2f 37 2e 31 39 2e 37 20 4e 53 53 2f |curl/7.19.7 NSS/|
00000090 33 2e 31 34 2e 33 2e 30 20 7a 6c 69 62 2f 31 2e |3.14.3.0 zlib/1.|
000000a0 32 2e 33 20 6c 69 62 69 64 6e 2f 31 2e 31 38 20 |2.3 libidn/1.18 |
000000b0 6c 69 62 73 73 68 32 2f 31 2e 34 2e 32 0d 0a 48 |libssh2/1.4.2..H|
000000c0 6f 73 74 3a 20 70 6b 72 69 7a 61 6b 2d 67 6c 6f |ost: pkrizak-glo|
000000d0 62 61 6c 70 78 65 2e 61 63 6f 63 79 63 6f 6d 2e |balpxe.anonycom.|
000000e0 63 6f 6d 0d 0a 41 63 63 65 70 74 3a 20 2a 2f 2a |com..Accept: */*|
000000f0 0d 0a 43 6f 6e 74 65 6e 74 2d 6c 65 6e 67 74 68 |..Content-length|
00000100 3a 20 33 0d 0a 43 6f 6e 74 65 6e 74 2d 74 79 70 |: 3..Content-typ|
00000110 65 3a 20 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 |e: application/x|
00000120 2d 77 77 77 2d 66 6f 72 6d 2d 75 72 6c 65 6e 63 |-www-form-urlenc|
00000130 6f 64 65 64 0d 0a 0d 0a 5b 20 5d |oded....[ ]|
0000013b
... не работает:
$ ./mypost.sh | nc pkrizak-globalpxe.anonycom.com 80
$ # no response
Хитрость здесь в том, что есть прокси-сервер squid (обратный), прослушивающий порт 80 хоста, к которому я подключаюсь. Так что я на самом деле не разговариваю с Apache или Nginx или даже с моим собственным приложением Perl - я пытаюсь поговорить со Squid (который при обращении с curl
фактически перенаправляет запрос в мое приложение). И, видимо, в том, как curl взаимодействует со Squid, что-то другое, чем в том, как nc общается со squid, несмотря на то, что содержимое запроса идентично.
Я пытался изменить запрос на использование HTTP/1.0
и даже пытался оставить HTTP/
расстаться, но это не поможет.
Я действительно сбит с толку в этот момент - что происходит под капотом, что я скучаю? Почему netcat ведет себя по-другому?
1 ответ
Оказывается, это странность в том, как ведет себя netcat, когда данные передаются по каналу STDIN.
После отслеживания пакетов с помощью wireshark я обнаружил, что netcat после отправки данных, передаваемых в STDIN, немедленно отправляет пакет FIN,ACK на сервер. Сервер squid, естественно, прерывает обработку запроса при получении пакета FIN,ACK и закрывает соединение.
Этого поведения можно избежать с помощью -i
опция netcat, которая указывает интервал времени между транзакциями. С помощью -i 1
например, ждет одну секунду перед отправкой FIN,ACK после отправки своих данных. Этого достаточно, чтобы прокси-сервер squid вернулся с ответом.
Другое решение состоит в том, чтобы скрипт генерировал входные данные для паузы STDIN после записи информации HTTP POST. Просто sleep 1
в конце скрипта оказывается достаточным, чтобы прокси завершил запрос.