Почему 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"
}
}
В чем проблема с моей функцией, которая не обеспечивает длину контента?
1 ответ
reqwest
документация для content_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
кажется, автоматически обрабатывает сжатый контент, тогда как curl
не является.
Content-Length
Заголовок HTTP не является обязательным, поэтому полагаться на его наличие было бы ошибкой. Вы должны прочитать данные из запроса, используя другой 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());