diff --git a/ext/node/polyfills/http2.ts b/ext/node/polyfills/http2.ts index c47e54d1bb2b3a..efd71ff932686c 100644 --- a/ext/node/polyfills/http2.ts +++ b/ext/node/polyfills/http2.ts @@ -933,25 +933,23 @@ export class ClientHttp2Stream extends Duplex { // TODO(bartlomieju): clean up _write(chunk, encoding, callback?: () => void) { - debugHttp2(">>> _write", callback); + debugHttp2(">>> _write", encoding, callback); if (typeof encoding === "function") { callback = encoding; - encoding = "utf8"; + encoding = this.#encoding; } let data; - if (typeof encoding === "string") { + if (encoding === "utf8") { data = ENCODER.encode(chunk); - } else { + } else if (encoding === "buffer") { + this.#encoding = encoding; data = chunk.buffer; } this.#requestPromise .then(() => { debugHttp2(">>> _write", this.#rid, data, encoding, callback); - return op_http2_client_send_data( - this.#rid, - data, - ); + return op_http2_client_send_data(this.#rid, new Uint8Array(data)); }) .then(() => { callback?.(); diff --git a/tests/unit_node/http2_test.ts b/tests/unit_node/http2_test.ts index 872e6641e29ca4..f2604b344c5742 100644 --- a/tests/unit_node/http2_test.ts +++ b/tests/unit_node/http2_test.ts @@ -1,6 +1,9 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. import * as http2 from "node:http2"; +import { Buffer } from "node:buffer"; +import { readFile } from "node:fs/promises"; +import { join } from "node:path"; import * as net from "node:net"; import { assert, assertEquals } from "@std/assert/mod.ts"; import { curlRequest } from "../unit/test_util.ts"; @@ -164,3 +167,39 @@ Deno.test("[node/http2.createServer()]", { // Issue: https://github.com/denoland/deno/issues/22764 await new Promise((resolve) => server.on("close", resolve)); }); + +Deno.test("[node/http2 client] write image buffer on request stream works", async () => { + const url = "https://localhost:5545"; + const client = http2.connect(url); + client.on("error", (err) => console.error(err)); + + const imagePath = join(import.meta.dirname!, "testdata", "green.jpg"); + const buffer = await readFile(imagePath); + const req = client.request({ ":method": "POST", ":path": "/echo_server" }); + req.write(buffer, (err) => { + if (err) throw err; + }); + + let receivedData: Buffer; + req.on("data", (chunk) => { + if (!receivedData) { + receivedData = chunk; + } else { + receivedData = Buffer.concat([receivedData, chunk]); + } + }); + req.end(); + + const endPromise = Promise.withResolvers(); + setTimeout(() => { + try { + client.close(); + } catch (_) { + // pass + } + endPromise.resolve(); + }, 2000); + + await endPromise.promise; + assertEquals(receivedData!, buffer); +}); diff --git a/tests/unit_node/testdata/green.jpg b/tests/unit_node/testdata/green.jpg new file mode 100644 index 00000000000000..72b51899e4883c Binary files /dev/null and b/tests/unit_node/testdata/green.jpg differ