10

我正在尝试编写一个 BASH 命令,该命令使用 CURL 向两个不同的网页发送 GET 请求,但使用相同的连接。对我来说,这就像向登录页面发送一个 GET 请求以对服务器进行身份验证,然后第二个请求模仿在 Web 浏览器中发生的自动重定向到主页(通过刷新标签)。我需要链接请求,因为来宾用户的主页内容(由服务器生成)与经过身份验证的用户不同。

我首先根据SOF 帖子的建议尝试了这个命令(假设变量已经$IP$PORT有效值定义):

curl -u user:pass ${IP}:${PORT}/login.php && curl ${IP}:${PORT}/index.php

但是,我总是在第一个 GET 结束和第二个 GET 开始之间发生这样的事情:

* Connection #0 to host 10.0.3.153 left intact
* Closing connection #0

那么 SOF 的帖子错了吗?无论如何,执行此命令将成功保持两个请求之间的连接打开:

curl -u user:pass ${IP}:${PORT}/login.php ${IP}:${PORT}/index.php

但是,我真的更喜欢更接近前一个命令的解决方案而不是后一个命令。主要原因是将第一页与第二页的输出分开到两个不同的输出文件中。所以我想做类似的事情:

curl page1.html > output1 && curl page2.html > output2

当然,我需要重用相同的连接,因为 page2.html 的内容取决于我也在同一个 HTTP 会话中对 page1.html 发出请求。

我也对使用 netcat 或 wget 的解决方案持开放态度,但不是 PHP!

4

4 回答 4

6

执行 curl a.html && curl b.html 将必然使用两个 TCP (http) 连接来获取数据。每个 curl 操作都是自己的进程,并且会打开自己的连接。

但是,网站不使用 TCP/HTTP 连接来跟踪登录信息。相反,某种令牌被放置在会话中(通常使用 cookie),该令牌在后续请求中传递给站点。该站点在后续请求中验证该令牌。

Curl 有一个选项 -c 来指示应该在连接之间存储 cookie 的位置

curl -c cookiejar -u user:pass login.php && curl -c cookierjar index.php

会更近。我说得更近了,因为许多站点不使用 -u 选项支持的基于 http 的身份验证,而是使用自定义表单,其次,调用假定使用了 cookie(而不是在 javascript 或 url 路径中嵌入某些内容)。后者很可能,但我不会指望第一位。

于 2013-03-10T07:13:55.340 回答
6

根据curl 手册,概要如下:

curl [options] [URL...]

这意味着您可以在同一命令中一个接一个地指定多个 url。Curl 将重用每个后续 url 的句柄:

curl 将尝试为多个文件传输重用连接,因此从同一服务器获取许多文件不会进行多次连接/握手。这提高了速度。当然,这仅适用于在单个命令行上指定的文件,并且不能在单独的 curl 调用之间使用。

于 2015-09-14T19:07:48.907 回答
1

主要这就是我制作Xidel的目的,您可以在一个命令调用中编写所有请求和操作,它的行为类似于保持 cookie 的浏览器,并且连接处于活动状态:

xidel http://${IP}/login.php --download page1.html -f '"index.php"' --download page2.html 

或者如果有从第一页到第二页的链接,它可以直接跟随该链接:

xidel http://${IP}/login.php --download page1.html -f //a --download page2.html 

但是,它不支持 http 身份验证或 80,8080 和 443 以外的其他端口(后端会支持它,但在这之间有一个 url 验证将其拒绝为无效 url)

于 2013-03-10T13:54:07.070 回答
0

我只是想补充一点,虽然 cookie-jar 选项对于该用例可能是最重要的,但如果您确实需要使用相同的 TCP 连接,您可以使用:

curl --http1.1 \
 -u user:pass -c cookiejar --url ${IP}:${PORT}/login.php \
 --next \
 -c cookiejar --url ${IP}:${PORT}/index.php

该参数--http1.1强制连接为 http1.1 支持keepalivehttp2当然也可以工作。--keepalive也可以工作,而不是将事情限制在 HTTP1.1

该参数--next允许您为第一个调用独立设置标头,以便 user:pass 不会发送到第二个 url。

于 2021-05-14T08:39:03.243 回答