【问题标题】:How to get the length of a file without downloading the file in a cURL binary get request如何在不下载 cURL 二进制获取请求中的文件的情况下获取文件的长度
【发布时间】:2011-12-02 09:36:01
【问题描述】:

我想在一些 C++ 代码中创建一个 cURL 请求,它可以让我在不下载文件的情况下获得服务器中文件的长度。为此,我使用一些 cURL 选项告诉我只需要请求响应中的标头,然后我检查响应以获取文件长度。

我正在设置以下请求选项:

curl_easy_setopt(_curl_handle, CURLOPT_HEADER, 1);
curl_easy_setopt(_curl_handle, CURLOPT_NOBODY, 1);

然后处理请求,等待响应,显示OK=200,最后查询文件长度:

curl_easy_getinfo(_curl_handle, CURLINFO_CONTENT_LENGTH_UPLOAD, &dResult);

但我得到的文件长度为-1。根据 cURL 文档,这意味着大小是未知的。 cURL怎么会没有从服务器获取文件长度信息呢?

【问题讨论】:

  • 该信息不可用的情况并不少见。尝试从命令行在同一 URL 上运行 curl --head,看看它是否显示文件大小。
  • 如果我执行curl --head "https://...",它会告诉我curl: (1) Protocol https not supported or disabled in libcurl。如果我尝试使用"http://" 或不使用"http://",它会显示curl: (7) couldn't connect to host
  • 使用 curl --version 查看 curl.exe 编译时使用的功能。如果支持列表中未提及HTTPSSSL,则无法请求HTTPS URL。

标签: c++ curl


【解决方案1】:

CURLINFO_CONTENT_LENGTH_UPLOAD 是上传的字节数。您需要改用CURLINFO_CONTENT_LENGTH_DOWNLOAD

请注意,如果服务器动态生成数据,则实际下载文件与仅下载文件头时长度可能会有所不同。

还请注意,如果服务器在下载时以压缩格式发送数据,则标头中可能没有任何可用大小(如果使用 Transfer-Encoding 标头而不是 Content-Length 标头),因此 CURLINFO_CONTENT_LENGTH_DOWNLOAD 仍将返回-1。在这种情况下知道大小的唯一方法是完整下载。

【讨论】:

  • 我使用 UPLOAD 而不是 DOWNLOAD 是因为我在几个网页中发现该术语具有误导性,如果您想要下载文件的大小,您应该使用 UPLOAD(它可能有意义,因为您查询的是已上传到服务器的文件)。
  • 无论如何,使用 DOWNLOAD 我得到了与 -1 相同的结果。
  • 顺便说一句,调试代码,我到达了 libcurl 中的一个点,函数 Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...) 本身,它检查 data->progress.flags,因为它们为空,所以它返回 -1 .可能是我错过了使用curl_easy_setopt 设置选项吗?
  • 服务器是发送成功还是失败响应码?我建议使用数据包嗅探器,例如 Wireshark,以确保 libcurl 正在发送有效请求并查看它收到的响应类型。
  • 我不能使用wireshark,因为我正在发送https请求。但是,我的工具会抓取服务器输出。我看到的是:HTTP/1.1 200 OK Content-length: 213 Content-Type: text/xml;charset=ISO-8859-1 Date: Mon, 10 Oct 2011 10:52:31 GMT Vary: Accept-Encoding X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1 Connection: keep-alive 对于我请求的任何二进制文件,我总是得到 213 的内容长度。
【解决方案2】:

您是否尝试过使用 CURLINFO_CONTENT_LENGTH_DOWNLOAD 代替?

【讨论】:

  • 看起来这已被弃用,现在更喜欢 CURLINFO_CONTENT_LENGTH_DOWNLOAD_T。
【解决方案3】:

需要致电perform()

curl_easy_setopt(_curl_handle, CURLOPT_HEADER, 1); curl_easy_setopt(_curl_handle, CURLOPT_NOBODY, 1);

curl_easy_perform(_curl_handle);

curl_easy_getinfo(_curl_handle, CURLINFO_CONTENT_LENGTH_UPLOAD, &d结果);

【讨论】:

  • 如果您需要同时获取标题和正文,这在 curl_easy_perform 中会成为一个挑战 - 因为您需要获取/缓冲正文(适当设置 CURLOPT_NOBODY),然后获取大小,然后做适当的事情......
猜你喜欢
  • 1970-01-01
  • 2022-06-10
  • 2018-11-24
  • 2014-05-18
  • 1970-01-01
  • 2016-12-03
  • 2013-12-01
  • 2011-01-27
相关资源
最近更新 更多