使用netcat进行squid代理丢弃请求,但不是curl

时间:2014-08-04 22:49:24

标签: squid netcat

我需要在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表现不同?

1 个答案:

答案 0 :(得分:1)

事实证明,当STDIN上的管道数据时,netcat的行为方式很奇怪。

在使用wireshark跟踪数据包之后,我发现netcat在将数据发送到STDIN后立即向服务器发送FIN,ACK数据包。当然,squid服务器在收到FIN,ACK数据包并关闭连接时中止处理请求。

使用netcat的-i选项可以避免此行为,该选项指定事务之间的间隔时间。例如,使用-i 1在发送FIN之后等待一秒,在发送数据之后发送ACK。这足以让squid代理返回一个答案。

另一个解决方案是在写出HTTP POST信息后让生成STDIN输入的脚本暂停。脚本末尾的简单sleep 1似乎足以让代理完成请求。