我正在尝试编写一个BASH命令,该命令使用CURL将GET请求发送到两个不同的网页,但使用相同的连接。对我来说,就像向登录页面发送GET请求以向服务器进行身份验证,然后第二个请求模仿自动重定向到主页,这将发生在Web浏览器中(通过 meta 刷新标签)。我需要链接请求,因为主页的内容(由服务器生成)对于访客用户而言将不同于经过身份验证的用户。
我首先根据SOF post的建议尝试了此命令(假设已使用有效值定义变量$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!
答案 0 :(得分:5)
做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路径中嵌入某些内容)。后者很可能,但我不会指望第一位。
答案 1 :(得分:2)
根据curl manual,概要如下:
curl [options] [URL...]
这意味着您可以在同一命令中一个接一个地指定多个URL。 Curl将重用每个后续URL的句柄:
curl将尝试重新使用多个文件传输的连接,因此从同一服务器获取多个文件将不会进行多个连接/握手。这提高了速度。当然,这只对在单个命令行上指定的文件进行,并且不能在单独的curl调用之间使用。
答案 2 :(得分:0)
这主要是我为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)
答案 3 :(得分: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
强制连接为支持 keepalive
的 http1.1,http2
当然也可以工作。 --keepalive
也可以工作并且不限制 HTTP1.1
参数 --next
允许您独立于第一次调用设置标头,以便 user:pass 不会发送到第二个 url。