|
2 | 2 | #![cfg(not(feature = "rustls-tls-manual-roots-no-provider"))] |
3 | 3 | mod support; |
4 | 4 |
|
| 5 | +use bytes::Bytes; |
| 6 | +use http_body_util::{BodyExt, Full}; |
5 | 7 | use support::server; |
6 | 8 |
|
7 | | -use http::header::{CONTENT_LENGTH, CONTENT_TYPE, TRANSFER_ENCODING}; |
| 9 | +use http::{ |
| 10 | + header::{self, CONTENT_LENGTH, CONTENT_TYPE, TRANSFER_ENCODING}, |
| 11 | + StatusCode, |
| 12 | +}; |
8 | 13 | #[cfg(feature = "json")] |
9 | 14 | use std::collections::HashMap; |
10 | 15 |
|
11 | | -use reqwest::Client; |
| 16 | +use reqwest::{Body, Client}; |
12 | 17 | use tokio::io::AsyncWriteExt; |
13 | 18 |
|
14 | 19 | #[tokio::test] |
@@ -528,3 +533,48 @@ async fn error_has_url() { |
528 | 533 | let err = reqwest::get(u).await.unwrap_err(); |
529 | 534 | assert_eq!(err.url().map(AsRef::as_ref), Some(u), "{err:?}"); |
530 | 535 | } |
| 536 | + |
| 537 | +#[tokio::test] |
| 538 | +async fn response_trailers() { |
| 539 | + let server = server::http(move |req| async move { |
| 540 | + assert_eq!(req.uri().path(), "/trailers"); |
| 541 | + |
| 542 | + let body = Full::new(Bytes::from("HelloWorld!")).with_trailers(async move { |
| 543 | + let mut trailers = http::HeaderMap::new(); |
| 544 | + trailers.insert("chunky-trailer", "custom-value".parse().unwrap()); |
| 545 | + Some(Ok(trailers)) |
| 546 | + }); |
| 547 | + let mut resp = http::Response::new(Body::wrap(body)); |
| 548 | + resp.headers_mut().insert( |
| 549 | + header::TRAILER, |
| 550 | + header::HeaderValue::from_static("chunky-trailer"), |
| 551 | + ); |
| 552 | + resp.headers_mut().insert( |
| 553 | + header::TRANSFER_ENCODING, |
| 554 | + header::HeaderValue::from_static("chunked"), |
| 555 | + ); |
| 556 | + |
| 557 | + resp |
| 558 | + }); |
| 559 | + |
| 560 | + let mut res = reqwest::Client::new() |
| 561 | + .get(format!("http://{}/trailers", server.addr())) |
| 562 | + .header(header::TE, "trailers") |
| 563 | + .send() |
| 564 | + .await |
| 565 | + .expect("Failed to get response"); |
| 566 | + |
| 567 | + assert_eq!(res.status(), StatusCode::OK); |
| 568 | + |
| 569 | + // Read the body using chunk() to preserve response ownership |
| 570 | + let mut body_content = Vec::new(); |
| 571 | + while let Some(chunk) = res.chunk().await.expect("Failed to read chunk") { |
| 572 | + body_content.extend_from_slice(&chunk); |
| 573 | + } |
| 574 | + |
| 575 | + let body = String::from_utf8(body_content).expect("Invalid UTF-8"); |
| 576 | + assert_eq!(body, "HelloWorld!"); |
| 577 | + |
| 578 | + let trailers = res.trailers().expect("Expected trailers but got None"); |
| 579 | + assert_eq!(trailers.get("chunky-trailer").unwrap(), "custom-value"); |
| 580 | +} |
0 commit comments