我需要在RHEL kickstart %pre
脚本中进行REST调用,因此我只能使用netcat(因为在RHEL wget
环境中打包的%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
这里棘手的一点就是有一个鱿鱼(反向)代理监听我正在连接的主机的端口80。所以我实际上并没有和Apache或Nginx甚至我的自定义Perl应用程序交谈 - 我正在尝试与Squid交谈(当与curl
联系时,实际上将请求正确地转发给我的应用程序)。尽管请求的内容相同,但与鱿鱼谈论鱿鱼的方式显然有些不同,尤其是nc如何与鱿鱼交谈。
我已尝试更改使用HTTP/1.0
的请求,甚至尝试关闭HTTP/
部分,但这没有帮助。
在这一点上我真的很困惑 - 我失踪的幕后发生了什么?为什么netcat表现不同?
答案 0 :(得分:1)
事实证明,当STDIN上的管道数据时,netcat的行为方式很奇怪。
在使用wireshark跟踪数据包之后,我发现netcat在将数据发送到STDIN后立即向服务器发送FIN,ACK数据包。当然,squid服务器在收到FIN,ACK数据包并关闭连接时中止处理请求。
使用netcat的-i
选项可以避免此行为,该选项指定事务之间的间隔时间。例如,使用-i 1
在发送FIN之后等待一秒,在发送数据之后发送ACK。这足以让squid代理返回一个答案。
另一个解决方案是在写出HTTP POST信息后让生成STDIN输入的脚本暂停。脚本末尾的简单sleep 1
似乎足以让代理完成请求。