rust - 为什么 reqwest 不在此请求中返回内容长度?

标签 rust reqwest

我很困惑为什么我没有从以下使用 reqwest 的函数中获取任何内容:

  fn try_get() {
      let wc = reqwest::Client::new();
      wc.get("https://httpbin.org/json").send().map(|res| {
          println!("{:?}", res);
          println!("length {:?}", res.content_length());
      });
  }

我期待这个函数显示响应对象,然后给我内容长度。它执行第一个但不执行第二个:

Response { url: "https://httpbin.org/json", status: 200, headers: {"access-control-allow-credentials": "true", "access-control-allow-origin": "*", "connection": "keep-alive", "content-type": "application/json", "date": "Tue, 26 Feb 2019 00:52:47 GMT", "server": "nginx"} }
length None

这很令人困惑,因为如果我使用 cURL 访问同一个端点,它会给我一个预期的主体:

$ curl -i https://httpbin.org/json
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Content-Type: application/json
Date: Tue, 26 Feb 2019 00:54:57 GMT
Server: nginx
Content-Length: 429
Connection: keep-alive

{
  "slideshow": {
    "author": "Yours Truly",
    "date": "date of publication",
    "slides": [
      {
        "title": "Wake up to WonderWidgets!",
        "type": "all"
      },
      {
        "items": [
          "Why <em>WonderWidgets</em> are great",
          "Who <em>buys</em> WonderWidgets"
        ],
        "title": "Overview",
        "type": "all"
      }
    ],
    "title": "Sample Slide Show"
  }
}

我的函数没有提供内容长度有什么问题?

最佳答案

reqwest documentation for content_length()始终是一个很好的起点。它指出

Get the content-length of the response, if it is known.

Reasons it may not be known:

  • The server didn't send a content-length header.
  • The response is gzipped and automatically decoded (thus changing the actual decoded length).

查看您的示例 curl 输出,它包含 Content-Length: 429 因此涵盖了第一种情况。所以现在让我们尝试禁用 gzip:

let client = reqwest::Client::builder()
  .gzip(false)
  .build()
  .unwrap();

client.get("https://httpbin.org/json").send().map(|res| {
  println!("{:?}", res);
  println!("length {:?}", res.content_length());
});

哪些日志

length Some(429)

所以第二种情况就是问题所在。默认情况下,reqwest 似乎会自动处理 gzip 压缩的内容,而 curl 则不会。

Content-Length HTTP header 完全是可选的,因此通常依赖它的存在是错误的。您应该使用其他 reqwest API 从请求中读取数据,然后计算数据本身的长度。例如,您可以使用 .text()

let wc = reqwest::Client::new();
let mut response = wc.get("https://httpbin.org/json").send().unwrap();
let text = response.text().unwrap();

println!("text: {} => {}", text.len(), text);

同样,对于二进制数据,您可以使用 .copy_to() :

let wc = reqwest::Client::new();
let mut response = wc.get("https://httpbin.org/json").send().unwrap();

let mut data = vec![];
response.copy_to(&mut data).unwrap();

println!("data: {}", data.len());

关于rust - 为什么 reqwest 不在此请求中返回内容长度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54876973/

相关文章:

rust - Rust Playground和本地计算机中reqwest示例的错误

error-handling - 如何处理 rust 上的盒装和链式错误?

rust - 用于测试的抽象OS环境变量

rust - 在字符串文字上调用 `chars` 方法产生的类型/特征是什么?

rust - 如何从其他语言访问 Rust

rust - 使用线程和async/await时如何解决 "cannot return value referencing local data"?

string - 为什么 &str 原语存在?

string - 从 io::stdin().read_line() 中修剪 '\n' 的更好方法是什么?

http - 为什么来自 api.color.pizza 的 reqwest 响应会返回意外的字节?

rust - 为什么get方法未在reqwest中返回Response对象?