mirror of
https://github.com/denoland/deno.git
synced 2025-07-07 21:35:07 +00:00
fix(ext/http2): fix oob buffer reads in http2 requests (#29969)
This commit is contained in:
parent
7a1e949c47
commit
3a94adf956
3 changed files with 66 additions and 1 deletions
|
@ -1041,7 +1041,7 @@ export class ClientHttp2Stream extends Duplex {
|
|||
data = ENCODER.encode(chunk);
|
||||
} else if (encoding === "buffer") {
|
||||
this.#encoding = encoding;
|
||||
data = chunk.buffer;
|
||||
data = new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
||||
}
|
||||
|
||||
this.#requestPromise
|
||||
|
|
|
@ -71,6 +71,7 @@ for (const url of ["http://localhost:4246", "https://localhost:4247"]) {
|
|||
"abc": "def",
|
||||
"opr": "stv",
|
||||
"foo": "bar",
|
||||
"req_body_len": "5",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -121,6 +122,64 @@ Deno.test(`[node/http2 client createConnection]`, {
|
|||
assertEquals(receivedData, "hello world\n");
|
||||
});
|
||||
|
||||
// https://github.com/denoland/deno/issues/29956
|
||||
Deno.test(`[node/http2 client body overflow]`, {
|
||||
ignore: Deno.build.os === "windows",
|
||||
}, async () => {
|
||||
const url = "http://127.0.0.1:4246";
|
||||
const createConnDeferred = Promise.withResolvers<void>();
|
||||
// Create a server to respond to the HTTP2 requests
|
||||
const client = http2.connect(url, {
|
||||
createConnection() {
|
||||
const socket = net.connect({ host: "127.0.0.1", port: 4246 });
|
||||
|
||||
socket.on("connect", () => {
|
||||
createConnDeferred.resolve();
|
||||
});
|
||||
|
||||
return socket;
|
||||
},
|
||||
});
|
||||
client.on("error", (err) => console.error(err));
|
||||
|
||||
const req = client.request({ ":method": "POST", ":path": "/" });
|
||||
|
||||
let receivedData = "";
|
||||
let receivedTrailers;
|
||||
|
||||
const ab = new ArrayBuffer(100);
|
||||
const view = new Uint8Array(ab, 0, 5);
|
||||
|
||||
req.write(view);
|
||||
req.setEncoding("utf8");
|
||||
|
||||
req.on("data", (chunk) => {
|
||||
receivedData += chunk;
|
||||
});
|
||||
|
||||
req.on("trailers", (trailers, _flags) => {
|
||||
receivedTrailers = trailers;
|
||||
});
|
||||
|
||||
req.end();
|
||||
|
||||
const endPromise = Promise.withResolvers<void>();
|
||||
setTimeout(() => {
|
||||
try {
|
||||
client.close();
|
||||
} catch (_) {
|
||||
// pass
|
||||
}
|
||||
endPromise.resolve();
|
||||
}, 2000);
|
||||
|
||||
await createConnDeferred.promise;
|
||||
await endPromise.promise;
|
||||
assertEquals(receivedData, "hello world\n");
|
||||
|
||||
assertEquals(receivedTrailers?.["req_body_len"], "5");
|
||||
});
|
||||
|
||||
Deno.test("[node/http2 client GET https://www.example.com]", async () => {
|
||||
const clientSession = http2.connect("https://www.example.com");
|
||||
const req = clientSession.request({
|
||||
|
|
|
@ -52,9 +52,11 @@ pub async fn h2_grpc_server(h2_grpc_port: u16, h2s_grpc_port: u16) {
|
|||
mut respond: h2::server::SendResponse<bytes::Bytes>,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let body = request.body_mut();
|
||||
let mut len = 0;
|
||||
while let Some(data) = body.data().await {
|
||||
let data = data?;
|
||||
let _ = body.flow_control().release_capacity(data.len());
|
||||
len += data.len();
|
||||
}
|
||||
|
||||
let maybe_recv_trailers = body.trailers().await?;
|
||||
|
@ -72,6 +74,10 @@ pub async fn h2_grpc_server(h2_grpc_port: u16, h2s_grpc_port: u16) {
|
|||
HeaderName::from_static("opr"),
|
||||
HeaderValue::from_static("stv"),
|
||||
);
|
||||
trailers.insert(
|
||||
HeaderName::from_static("req_body_len"),
|
||||
HeaderValue::from(len),
|
||||
);
|
||||
if let Some(recv_trailers) = maybe_recv_trailers {
|
||||
for (key, value) in recv_trailers {
|
||||
trailers.insert(key.unwrap(), value);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue