【发布时间】:2014-05-13 11:12:26
【问题描述】:
我正在开发一个使用 libcurl 的应用程序。
我在我的 c 代码中添加了以下 curl 选项:
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
为了遵循http重定向。
当我的应用程序发送一个 http 消息(第一个 http 消息)时,它从服务器接收到一个 http 302 重定向,libcurl 成功检测到重定向信息,然后发送另一个 http 消息(第二条http消息)到新的url,但新的http消息与第一条http消息不同。
如何让 libcurl 发送相同的 HTTP 消息?
第一条 http 消息:我的应用程序和第一台服务器之间的通信,直到应用程序收到 http 重定向消息
应用程序---->服务器1
POST / HTTP/1.1
Host: 192.168.1.15
Accept: */*
User-Agent: cwmp
Content-Type: text/xml
Content-Length: 341
Expect: 100-continue
server1 ----> 应用程序
HTTP/1.1 100 Continue
应用程序---->服务器1
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soap_env:Envelope
xmlns:soap_env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soap_enc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap_env:Header>
<cwmp:ID soap_env:mustUnderstand="1" />
</soap_env:Header>
<soap_env:Body>
<any:command>any_command_value</any:command>
</soap_env:Body>
</soap_env:Envelope>
server1 ----> 应用程序(重定向消息)
HTTP/1.1 302 Found
Date: Tue, 13 May 2014 11:00:48 GMT
Server: Apache/2.4.7 (Win32) PHP/5.5.8
X-Powered-By: PHP/5.5.8
Location: http://192.168.1.133:8080/openserv/serv
Content-Length: 0
Content-Type: text/html
第二条http消息:我的应用收到http重定向后发送给第二台服务器的http消息
应用程序---> server2
GET /openserv/serv HTTP/1.1
Host: 192.168.1.133:8080
Accept: */*
User-Agent: cwmp
Content-Type: text/xml
【问题讨论】:
-
根据标准,是的,需要在重定向时发送相同的消息。然而,几乎没有工具实现标准。 Curl 在重定向时将请求方法从
POST更改为GET,是的,这违反了标准,但我认为除了禁用FOLLOW_LOCATION、识别302 和301 响应代码并发送请求之外,你不能在这里做任何事情再次调用 libcurl。 -
根据 HTTP RFC,服务器应该以 307 响应,而不是 302。
-
CURLOPT_VERBOSE 设置为 1 会帮助您检测到这一点...
-
@n.m.我认为你错了。在 RFC2616 章节 10.3.3 302 Found 中:
If the 302 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. -
相同的 MUST NOT 子句对 302 和 307 都有效。那么为什么选择 307?在这种情况下应该避免 302,因为许多客户端错误地实现它(像 303 而不是像 307)。如果服务器希望客户端重复 POST,它应该以 307 响应。如果服务器希望客户端通过 GET 得到答案,它应该以 303 响应。302 实际上是模棱两可的(尽管根据标准它不是)。
标签: c++ c curl libcurl http-redirect