チャンク転送でエンコードされたハイパー応答を送信する方法は?

Aug 18 2020

特定のバイト数とチャンクでハイパーレスポンスを送信しようとしています。一般的なチャンク応答を生成する方法や、転送エンコーディングヘッダーを設定する方法に迷いました。現在減価償却されているハイパー用のhttpWriter / chunkedWriterがあるようです。

これは私の試みですが、transfer-encodingヘッダーが設定されておらず、これがチャンク化された応答を得る正しい方法であるとは思いません。

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)。を使用して指定できます。