-
-
Notifications
You must be signed in to change notification settings - Fork 696
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Bug Description
When WrapHandler gets involved to translate from the new handler API calls to the old handler API, it incorrectly translates headers using utf-8 instead of isomorphic encoding, due to calling Buffer.from(x) instead of Buffer.from(x, 'latin1').
This affects all APIs that use WrapHandler such as request().
Reproducible By
const WrapHandler = require("undici/lib/handler/wrap-handler.js");
const oldAPIHandler = {
onHeaders(statusCode, rawHeaders) {
const value = rawHeaders[1].toString("latin1");
console.log("Expected:", JSON.stringify("\xE2\x80\xA6"));
console.log("Got: ", JSON.stringify(value));
}
};
const wrapped = WrapHandler.wrap(oldAPIHandler);
wrapped.onResponseStart({ resume() {} }, 200, { "x-test": "\xE2\x80\xA6" }, "OK");A repro case using request() around a custom dispatcher that uses WrapHandler
const http = require("http");
const { Dispatcher, request } = require("undici");
const WrapHandler = require("undici/lib/handler/wrap-handler.js");
const server = http.createServer((req, res) => {
res.writeHead(200, { "x-test": "\xE2\x80\xA6" });
res.end();
});
// Dispatcher that does its own HTTP and calls onResponseStart with object headers
class MyDispatcher extends Dispatcher {
dispatch(opts, handler) {
const wrapped = WrapHandler.wrap(handler);
http.get(opts.origin + opts.path, res => {
wrapped.onRequestStart?.({ abort() {}, pause() {}, resume() {} }, {});
wrapped.onResponseStart?.({ resume() {}, pause() {} }, res.statusCode, res.headers, res.statusMessage);
res.on("data", chunk => wrapped.onResponseData?.({}, chunk));
res.on("end", () => wrapped.onResponseEnd?.({}, {}));
}).on("error", err => wrapped.onResponseError?.({}, err));
return true;
}
close() { return Promise.resolve(); }
destroy() { return Promise.resolve(); }
}
(async () => {
await new Promise(r => server.listen(0, r));
const url = `http://localhost:${server.address().port}`;
const response = await request(url, { dispatcher: new MyDispatcher() });
await response.body.dump();
console.log("Expected:", JSON.stringify("\xE2\x80\xA6"));
console.log("Got: ", JSON.stringify(response.headers["x-test"]));
server.close();
})();Expected Behavior
Expected: "â¦"
Got: "â¦"
Environment
- Node v25.3.0
- Undici 7.20.0
Additional context
I don't believe #4785 will fix this.
#4786 might fix this.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working