จะส่งการตอบสนองไฮเปอร์ที่เข้ารหัสการถ่ายโอนเป็นกลุ่มได้อย่างไร

Aug 18 2020

ฉันกำลังพยายามส่งการตอบสนองแบบไฮเปอร์ที่มีจำนวนไบต์และชิ้นที่ระบุ ฉันหลงทางในการสร้างการตอบสนองแบบกลุ่มทั่วไปหรือตั้งค่าส่วนหัวการเข้ารหัสการถ่ายโอน ดูเหมือนจะมี httpWriter / chunkedWriter สำหรับไฮเปอร์ซึ่งตอนนี้คิดค่าเสื่อมราคาแล้ว

นี่เป็นความพยายามของฉัน แต่ยังไม่ได้ตั้งค่าส่วนหัวของการเข้ารหัสการถ่ายโอนและฉันไม่เชื่อว่านี่เป็นวิธีที่ถูกต้องในการตอบสนองเป็นก้อน

let chunked_body = "5\r\nhello\r\n5\r\n worl\r\n1\r\nd\r\n0\r\n\r\n";
let mut resp: hyper::Response<Body> = Response::new(Body::from(chunked_body));
resp.headers_mut().insert(TRANSFER_ENCODING, HeaderValue::from_static("Chunked"));
Ok(resp)

คำตอบ

2 PeterHall Aug 18 2020 at 16:13

การเข้ารหัสขนส่งเป็นชิ้นส่วนเป็นส่วนหนึ่งของ HTTP / 1.1 และไม่ได้เป็นส่วนหนึ่งของ HTTP / 2 เมื่อตัวจัดการตอบสนองด้วยสตรีมที่เป็นกลุ่ม Hyper จะทำ "สิ่งที่ถูกต้อง" ขึ้นอยู่กับเวอร์ชัน HTTP ที่ไคลเอ็นต์รองรับ

ตัวอย่างเช่นสิ่งต่อไปนี้จะส่งการตอบสนองแบบเป็นกลุ่มใน HTTP / 1.1 แต่ใช้เฟรมข้อมูลหากไคลเอ็นต์รองรับ HTTP / 2:

async fn handle(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
    let chunked_body = vec!["Hello", ", ", "worl", "d", "!"];
    let stream = stream::iter(chunked_body.into_iter().map(Result::<_, Infallible>::Ok));
    let body = Body::wrap_stream(stream);
    Ok(Response::new(body))
}

ส่วนหัวของการตอบกลับนี้ (เมื่อบังคับ HTTP / 1.1 บนไคลเอนต์) คือ:

HTTP/1.1 200 OK
transfer-encoding: chunked

หากคุณต้องการรองรับเฉพาะ HTTP / 1.1 คุณสามารถระบุสิ่งนั้นบนตัวServerสร้างด้วยBuilder::http1_only(true).