mirror of
https://github.com/oven-sh/bun
synced 2026-02-16 22:01:47 +00:00
opsie
This commit is contained in:
@@ -3466,6 +3466,22 @@ pub const H2FrameParser = struct {
|
||||
const stream_id_arg = args_list.ptr[0];
|
||||
bun.debugAssert(stream_id_arg.isNumber());
|
||||
this.lastStreamID = stream_id_arg.to(u32);
|
||||
// to set the next stream id we need to decrement because we only keep the last stream id
|
||||
if (this.isServer) {
|
||||
if (this.lastStreamID % 2 == 0) {
|
||||
this.lastStreamID -= 2;
|
||||
} else {
|
||||
this.lastStreamID -= 1;
|
||||
}
|
||||
} else {
|
||||
if (this.lastStreamID % 2 == 0) {
|
||||
this.lastStreamID -= 1;
|
||||
} else if (this.lastStreamID == 1) {
|
||||
this.lastStreamID = 0;
|
||||
} else {
|
||||
this.lastStreamID -= 2;
|
||||
}
|
||||
}
|
||||
return .undefined;
|
||||
}
|
||||
|
||||
@@ -3477,6 +3493,9 @@ pub const H2FrameParser = struct {
|
||||
JSC.markBinding(@src());
|
||||
|
||||
const id = this.getNextStreamID();
|
||||
if (id > MAX_STREAM_ID) {
|
||||
return JSC.JSValue.jsNumber(-1);
|
||||
}
|
||||
_ = this.handleReceivedStreamID(id) orelse {
|
||||
return JSC.JSValue.jsNumber(-1);
|
||||
};
|
||||
|
||||
@@ -130,6 +130,10 @@ function emitErrorNT(self: any, error: any, destroy: boolean) {
|
||||
self.emit("error", error);
|
||||
}
|
||||
}
|
||||
|
||||
function emitOutofStreamErrorNT(self: any) {
|
||||
self.destroy($ERR_HTTP2_OUT_OF_STREAMS());
|
||||
}
|
||||
function cache() {
|
||||
const d = new Date();
|
||||
utcCache = d.toUTCString();
|
||||
@@ -1843,7 +1847,7 @@ class Http2Stream extends Duplex {
|
||||
// will destroy if it has been closed and there are no other open or
|
||||
// pending streams. Delay with setImmediate so we don't do it on the
|
||||
// nghttp2 stack.
|
||||
if (session) {
|
||||
if (session && typeof this.#id === "number") {
|
||||
setImmediate(rstNextTick.bind(session, this.#id, rstCode));
|
||||
}
|
||||
callback(err);
|
||||
@@ -3512,13 +3516,13 @@ class ClientHttp2Session extends Http2Session {
|
||||
}
|
||||
}
|
||||
let stream_id: number = this.#parser.getNextStream();
|
||||
if (stream_id < 0) {
|
||||
const req = new ClientHttp2Stream(undefined, this, headers);
|
||||
process.nextTick(emitOutofStreamErrorNT, req);
|
||||
return req;
|
||||
}
|
||||
const req = new ClientHttp2Stream(stream_id, this, headers);
|
||||
req.authority = authority;
|
||||
if (stream_id < 0) {
|
||||
const error = $ERR_HTTP2_OUT_OF_STREAMS();
|
||||
this.emit("error", error);
|
||||
return null;
|
||||
}
|
||||
req[kHeadRequest] = method === HTTP2_METHOD_HEAD;
|
||||
if (typeof options === "undefined") {
|
||||
this.#parser.request(stream_id, req, headers, sensitiveNames);
|
||||
|
||||
52
test/js/node/test/parallel/test-http2-no-more-streams.js
Normal file
52
test/js/node/test/parallel/test-http2-no-more-streams.js
Normal file
@@ -0,0 +1,52 @@
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
if (!common.hasCrypto)
|
||||
common.skip('missing crypto');
|
||||
|
||||
const assert = require('assert');
|
||||
const http2 = require('http2');
|
||||
const Countdown = require('../common/countdown');
|
||||
|
||||
const server = http2.createServer();
|
||||
server.on('stream', (stream) => {
|
||||
stream.respond();
|
||||
stream.end('ok');
|
||||
});
|
||||
|
||||
server.listen(0, common.mustCall(() => {
|
||||
const client = http2.connect(`http://127.0.0.1:${server.address().port}`);
|
||||
const nextID = 2 ** 31 - 1;
|
||||
|
||||
client.on('connect', () => {
|
||||
client.setNextStreamID(nextID);
|
||||
assert.strictEqual(client.state.nextStreamID, nextID);
|
||||
|
||||
const countdown = new Countdown(2, () => {
|
||||
server.close();
|
||||
client.close();
|
||||
});
|
||||
|
||||
{
|
||||
// This one will be ok
|
||||
const req = client.request();
|
||||
assert.strictEqual(req.id, nextID);
|
||||
|
||||
req.on('error', common.mustNotCall());
|
||||
req.resume();
|
||||
req.on('end', () => countdown.dec());
|
||||
}
|
||||
|
||||
{
|
||||
// This one will error because there are no more stream IDs available
|
||||
const req = client.request();
|
||||
req.on('error', common.expectsError({
|
||||
code: 'ERR_HTTP2_OUT_OF_STREAMS',
|
||||
name: 'Error',
|
||||
message:
|
||||
'No stream ID is available because maximum stream ID has been reached'
|
||||
}));
|
||||
req.on('error', () => countdown.dec());
|
||||
}
|
||||
});
|
||||
}));
|
||||
Reference in New Issue
Block a user