【问题标题】:HTTP redirect with curl does not resend the same http message使用 curl 的 HTTP 重定向不会重新发送相同的 http 消息
【发布时间】: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


【解决方案1】:

根据标准,需要在 HTTP 重定向上发送相同的消息。然而,几乎没有工具实现标准。 libcurl 在重定向时将请求方法从 POST 更改为 GET,是的,这违反了标准,但它就是这样工作的。 可能的解决方案:

  1. 使用CURLOPT_POSTREDIR 选项;它将强制libcurl 在重定向后至少也使用POST 方法,我不知道POST 请求正文如何。
  2. 识别 302 和 301 响应代码并通过另一个呼叫发送请求至 libcurl

【讨论】:

    猜你喜欢
    • 2010-11-01
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-12
    • 1970-01-01
    相关资源
    最近更新 更多