Files
bun.sh/test/js/node/http2/node-echo-server.fixture.js
Ciro Spaciari 4bbe32fff8 fix(net/http2) fix socket internal timeout and owner_symbol check, fix padding support in http2 (#21263)
### What does this PR do?

<!-- **Please explain what your changes do**, example: -->

<!--

This adds a new flag --bail to bun test. When set, it will stop running
tests after the first failure. This is useful for CI environments where
you want to fail fast.

-->

- [ ] Documentation or TypeScript types (it's okay to leave the rest
blank in this case)
- [x] Code changes

### How did you verify your code works?
Tests added for padding support
Timeout of socket is being fired earlier due to backpressure or lack of
precision in usockets timers (now matchs node.js behavior).
Added check for owner_symbol so the error showed in
https://github.com/oven-sh/bun/issues/21055 is handled

<!-- **For code changes, please include automated tests**. Feel free to
uncomment the line below -->

<!-- I wrote automated tests -->

<!-- If JavaScript/TypeScript modules or builtins changed:

- [ ] I included a test for the new code, or existing tests cover it
- [ ] I ran my tests locally and they pass (`bun-debug test
test-file-name.test`)

-->

<!-- If Zig files changed:

- [ ] I checked the lifetime of memory allocated to verify it's (1)
freed and (2) only freed when it should be
- [ ] I included a test for the new code, or an existing test covers it
- [ ] JSValue used outside of the stack is either wrapped in a
JSC.Strong or is JSValueProtect'ed
- [ ] I wrote TypeScript/JavaScript tests and they pass locally
(`bun-debug test test-file-name.test`)
-->

<!-- If new methods, getters, or setters were added to a publicly
exposed class:

- [ ] I added TypeScript types for the new methods, getters, or setters
-->

<!-- If dependencies in tests changed:

- [ ] I made sure that specific versions of dependencies are used
instead of ranged or tagged versions
-->

<!-- If a new builtin ESM/CJS module was added:

- [ ] I updated Aliases in `module_loader.zig` to include the new module
- [ ] I added a test that imports the module
- [ ] I added a test that require() the module
-->

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-07-29 17:20:16 -07:00

81 lines
2.5 KiB
JavaScript

const http2 = require("http2");
const fs = require("fs");
const paddingStrategy = process.argv[3];
const server = http2.createSecureServer({
...JSON.parse(process.argv[2]),
rejectUnauthorized: false,
paddingStrategy: paddingStrategy ?? http2.constants.PADDING_STRATEGY_NONE,
});
const setCookie = ["a=b", "c=d; Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly", "e=f"];
server.on("stream", (stream, headers, flags) => {
// errors here are not useful the test should handle on the client side
stream.on("error", err => console.error(err));
if (headers["x-wait-trailer"]) {
const response = { headers, flags };
stream.respond({
"content-type": "text/html",
":status": 200,
"set-cookie": setCookie,
});
stream.on("trailers", (headers, flags) => {
stream.end(JSON.stringify({ ...response, trailers: headers }));
});
} else if (headers["x-no-echo"]) {
let byteLength = 0;
stream.on("data", chunk => {
byteLength += chunk.length;
});
stream.respond({
"content-type": "application/json",
":status": 200,
});
stream.on("end", () => {
stream.end(JSON.stringify(byteLength));
});
} else {
// Store the request information, excluding pseudo-headers in the header echo
const requestData = {
method: headers[":method"],
path: headers[":path"],
headers: Object.fromEntries(Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value])),
body: [],
url: `${baseurl}${headers[":path"]}`,
};
// Collect data from the stream
stream.on("data", chunk => {
requestData.body.push(chunk);
});
// Once all data is received, echo it back
stream.on("end", () => {
if (requestData.body.length > 0) {
requestData.data = Buffer.concat(requestData.body).toString();
try {
requestData.json = JSON.parse(requestData.data); // Convert buffer array to string
} catch (e) {}
}
stream.respond({
"content-type": "application/json",
":status": 200,
// Set security and cache-control headers
"cache-control": "no-store",
"x-content-type-options": "nosniff",
"set-cookie": setCookie,
});
stream.end(JSON.stringify(requestData));
});
}
});
let baseurl = "https://localhost:";
server.listen(0, "localhost");
server.on("listening", () => {
const { port, address, family } = server.address();
baseurl = `https://localhost:${port}`;
process.stdout.write(JSON.stringify({ port, address: "localhost", family: "IPv4" }));
});