mirror of
https://github.com/oven-sh/bun
synced 2026-02-05 16:38:55 +00:00
Compare commits
1 Commits
dylan/byte
...
nektro-pat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7cadcb55d2 |
@@ -205,8 +205,8 @@ const FullSettingsPayload = packed struct(u288) {
|
||||
result.put(globalObject, jsc.ZigString.static("maxHeaderListSize"), jsc.JSValue.jsNumber(this.maxHeaderListSize));
|
||||
result.put(globalObject, jsc.ZigString.static("maxHeaderSize"), jsc.JSValue.jsNumber(this.maxHeaderListSize));
|
||||
// TODO: we dont support this setting yet see https://nodejs.org/api/http2.html#settings-object
|
||||
// we should also support customSettings
|
||||
result.put(globalObject, jsc.ZigString.static("enableConnectProtocol"), .false);
|
||||
// TODO: we should also support customSettings
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -331,7 +331,7 @@ pub fn jsAssertSettings(globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallF
|
||||
|
||||
if (try options.get(globalObject, "headerTableSize")) |headerTableSize| {
|
||||
if (headerTableSize.isNumber()) {
|
||||
const headerTableSizeValue = headerTableSize.toInt32();
|
||||
const headerTableSizeValue = headerTableSize.toInt64();
|
||||
if (headerTableSizeValue > MAX_HEADER_TABLE_SIZE or headerTableSizeValue < 0) {
|
||||
return globalObject.throw("Expected headerTableSize to be a number between 0 and 2^32-1", .{});
|
||||
}
|
||||
@@ -348,7 +348,7 @@ pub fn jsAssertSettings(globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallF
|
||||
|
||||
if (try options.get(globalObject, "initialWindowSize")) |initialWindowSize| {
|
||||
if (initialWindowSize.isNumber()) {
|
||||
const initialWindowSizeValue = initialWindowSize.toInt32();
|
||||
const initialWindowSizeValue = initialWindowSize.toInt64();
|
||||
if (initialWindowSizeValue > MAX_HEADER_TABLE_SIZE or initialWindowSizeValue < 0) {
|
||||
return globalObject.throw("Expected initialWindowSize to be a number between 0 and 2^32-1", .{});
|
||||
}
|
||||
@@ -359,7 +359,7 @@ pub fn jsAssertSettings(globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallF
|
||||
|
||||
if (try options.get(globalObject, "maxFrameSize")) |maxFrameSize| {
|
||||
if (maxFrameSize.isNumber()) {
|
||||
const maxFrameSizeValue = maxFrameSize.toInt32();
|
||||
const maxFrameSizeValue = maxFrameSize.toInt64();
|
||||
if (maxFrameSizeValue > MAX_FRAME_SIZE or maxFrameSizeValue < 16384) {
|
||||
return globalObject.throw("Expected maxFrameSize to be a number between 16,384 and 2^24-1", .{});
|
||||
}
|
||||
@@ -370,7 +370,7 @@ pub fn jsAssertSettings(globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallF
|
||||
|
||||
if (try options.get(globalObject, "maxConcurrentStreams")) |maxConcurrentStreams| {
|
||||
if (maxConcurrentStreams.isNumber()) {
|
||||
const maxConcurrentStreamsValue = maxConcurrentStreams.toInt32();
|
||||
const maxConcurrentStreamsValue = maxConcurrentStreams.toInt64();
|
||||
if (maxConcurrentStreamsValue > MAX_HEADER_TABLE_SIZE or maxConcurrentStreamsValue < 0) {
|
||||
return globalObject.throw("Expected maxConcurrentStreams to be a number between 0 and 2^32-1", .{});
|
||||
}
|
||||
@@ -381,7 +381,7 @@ pub fn jsAssertSettings(globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallF
|
||||
|
||||
if (try options.get(globalObject, "maxHeaderListSize")) |maxHeaderListSize| {
|
||||
if (maxHeaderListSize.isNumber()) {
|
||||
const maxHeaderListSizeValue = maxHeaderListSize.toInt32();
|
||||
const maxHeaderListSizeValue = maxHeaderListSize.toInt64();
|
||||
if (maxHeaderListSizeValue > MAX_HEADER_TABLE_SIZE or maxHeaderListSizeValue < 0) {
|
||||
return globalObject.throw("Expected maxHeaderListSize to be a number between 0 and 2^32-1", .{});
|
||||
}
|
||||
@@ -392,7 +392,7 @@ pub fn jsAssertSettings(globalObject: *jsc.JSGlobalObject, callframe: *jsc.CallF
|
||||
|
||||
if (try options.get(globalObject, "maxHeaderSize")) |maxHeaderSize| {
|
||||
if (maxHeaderSize.isNumber()) {
|
||||
const maxHeaderSizeValue = maxHeaderSize.toInt32();
|
||||
const maxHeaderSizeValue = maxHeaderSize.toInt64();
|
||||
if (maxHeaderSizeValue > MAX_HEADER_TABLE_SIZE or maxHeaderSizeValue < 0) {
|
||||
return globalObject.throw("Expected maxHeaderSize to be a number between 0 and 2^32-1", .{});
|
||||
}
|
||||
@@ -2586,14 +2586,30 @@ pub const H2FrameParser = struct {
|
||||
return globalObject.throw("Expected settings to be a object", .{});
|
||||
}
|
||||
|
||||
if (try options.get(globalObject, "customSettings")) |customSettings| {
|
||||
if (customSettings.isObject()) {
|
||||
var piter = try bun.jsc.JSPropertyIterator(.{ .skip_empty_name = true, .include_value = true }).init(globalObject, customSettings.getObject().?);
|
||||
var i: usize = 0;
|
||||
while (try piter.next()) |_| : (i += 1) {
|
||||
if (i >= 10) return globalObject.ERR(.HTTP2_TOO_MANY_CUSTOM_SETTINGS, "Number of custom settings exceeds MAX_ADDITIONAL_SETTINGS", .{}).throw();
|
||||
const keyI = try piter.key.coerceToInt64(globalObject);
|
||||
if (keyI < 0 or keyI > 0xffff)
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE_RangeError, "Invalid value for setting \"customSettings:id\": {d}", .{keyI}).throw();
|
||||
const valueI = try piter.value.coerceToInt64(globalObject);
|
||||
if (valueI < 0 or valueI > std.math.maxInt(u32))
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE_RangeError, "Invalid value for setting \"customSettings:value\": {d}", .{valueI}).throw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (try options.get(globalObject, "headerTableSize")) |headerTableSize| {
|
||||
if (headerTableSize.isNumber()) {
|
||||
const headerTableSizeValue = headerTableSize.toInt32();
|
||||
const headerTableSizeValue = headerTableSize.toInt64();
|
||||
if (headerTableSizeValue > MAX_HEADER_TABLE_SIZE or headerTableSizeValue < 0) {
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE, "Expected headerTableSize to be a number between 0 and 2^32-1", .{}).throw();
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE_RangeError, "Expected headerTableSize to be a number between 0 and 2^32-1", .{}).throw();
|
||||
}
|
||||
this.localSettings.headerTableSize = @intCast(headerTableSizeValue);
|
||||
} else if (!headerTableSize.isEmptyOrUndefinedOrNull()) {
|
||||
} else if (!headerTableSize.isEmptyOrUndefined()) {
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE, "Expected headerTableSize to be a number", .{}).throw();
|
||||
}
|
||||
}
|
||||
@@ -2601,68 +2617,68 @@ pub const H2FrameParser = struct {
|
||||
if (try options.get(globalObject, "enablePush")) |enablePush| {
|
||||
if (enablePush.isBoolean()) {
|
||||
this.localSettings.enablePush = if (enablePush.asBoolean()) 1 else 0;
|
||||
} else if (!enablePush.isEmptyOrUndefinedOrNull()) {
|
||||
} else if (!enablePush.isEmptyOrUndefined()) {
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE, "Expected enablePush to be a boolean", .{}).throw();
|
||||
}
|
||||
}
|
||||
|
||||
if (try options.get(globalObject, "initialWindowSize")) |initialWindowSize| {
|
||||
if (initialWindowSize.isNumber()) {
|
||||
const initialWindowSizeValue = initialWindowSize.toInt32();
|
||||
const initialWindowSizeValue = initialWindowSize.toInt64();
|
||||
if (initialWindowSizeValue > MAX_WINDOW_SIZE or initialWindowSizeValue < 0) {
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE, "Expected initialWindowSize to be a number between 0 and 2^32-1", .{}).throw();
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE_RangeError, "Expected initialWindowSize to be a number between 0 and 2^32-1", .{}).throw();
|
||||
}
|
||||
log("initialWindowSize: {d}", .{initialWindowSizeValue});
|
||||
this.localSettings.initialWindowSize = @intCast(initialWindowSizeValue);
|
||||
} else if (!initialWindowSize.isEmptyOrUndefinedOrNull()) {
|
||||
} else if (!initialWindowSize.isEmptyOrUndefined()) {
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE, "Expected initialWindowSize to be a number", .{}).throw();
|
||||
}
|
||||
}
|
||||
|
||||
if (try options.get(globalObject, "maxFrameSize")) |maxFrameSize| {
|
||||
if (maxFrameSize.isNumber()) {
|
||||
const maxFrameSizeValue = maxFrameSize.toInt32();
|
||||
const maxFrameSizeValue = maxFrameSize.toInt64();
|
||||
if (maxFrameSizeValue > MAX_FRAME_SIZE or maxFrameSizeValue < 16384) {
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE, "Expected maxFrameSize to be a number between 16,384 and 2^24-1", .{}).throw();
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE_RangeError, "Expected maxFrameSize to be a number between 16,384 and 2^24-1", .{}).throw();
|
||||
}
|
||||
this.localSettings.maxFrameSize = @intCast(maxFrameSizeValue);
|
||||
} else if (!maxFrameSize.isEmptyOrUndefinedOrNull()) {
|
||||
} else if (!maxFrameSize.isEmptyOrUndefined()) {
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE, "Expected maxFrameSize to be a number", .{}).throw();
|
||||
}
|
||||
}
|
||||
|
||||
if (try options.get(globalObject, "maxConcurrentStreams")) |maxConcurrentStreams| {
|
||||
if (maxConcurrentStreams.isNumber()) {
|
||||
const maxConcurrentStreamsValue = maxConcurrentStreams.toInt32();
|
||||
const maxConcurrentStreamsValue = maxConcurrentStreams.toInt64();
|
||||
if (maxConcurrentStreamsValue > MAX_HEADER_TABLE_SIZE or maxConcurrentStreamsValue < 0) {
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE, "Expected maxConcurrentStreams to be a number between 0 and 2^32-1", .{}).throw();
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE_RangeError, "Expected maxConcurrentStreams to be a number between 0 and 2^32-1", .{}).throw();
|
||||
}
|
||||
this.localSettings.maxConcurrentStreams = @intCast(maxConcurrentStreamsValue);
|
||||
} else if (!maxConcurrentStreams.isEmptyOrUndefinedOrNull()) {
|
||||
} else if (!maxConcurrentStreams.isEmptyOrUndefined()) {
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE, "Expected maxConcurrentStreams to be a number", .{}).throw();
|
||||
}
|
||||
}
|
||||
|
||||
if (try options.get(globalObject, "maxHeaderListSize")) |maxHeaderListSize| {
|
||||
if (maxHeaderListSize.isNumber()) {
|
||||
const maxHeaderListSizeValue = maxHeaderListSize.toInt32();
|
||||
const maxHeaderListSizeValue = maxHeaderListSize.toInt64();
|
||||
if (maxHeaderListSizeValue > MAX_HEADER_TABLE_SIZE or maxHeaderListSizeValue < 0) {
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE, "Expected maxHeaderListSize to be a number between 0 and 2^32-1", .{}).throw();
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE_RangeError, "Expected maxHeaderListSize to be a number between 0 and 2^32-1", .{}).throw();
|
||||
}
|
||||
this.localSettings.maxHeaderListSize = @intCast(maxHeaderListSizeValue);
|
||||
} else if (!maxHeaderListSize.isEmptyOrUndefinedOrNull()) {
|
||||
} else if (!maxHeaderListSize.isEmptyOrUndefined()) {
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE, "Expected maxHeaderListSize to be a number", .{}).throw();
|
||||
}
|
||||
}
|
||||
|
||||
if (try options.get(globalObject, "maxHeaderSize")) |maxHeaderSize| {
|
||||
if (maxHeaderSize.isNumber()) {
|
||||
const maxHeaderSizeValue = maxHeaderSize.toInt32();
|
||||
const maxHeaderSizeValue = maxHeaderSize.toInt64();
|
||||
if (maxHeaderSizeValue > MAX_HEADER_TABLE_SIZE or maxHeaderSizeValue < 0) {
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE, "Expected maxHeaderSize to be a number between 0 and 2^32-1", .{}).throw();
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE_RangeError, "Expected maxHeaderSize to be a number between 0 and 2^32-1", .{}).throw();
|
||||
}
|
||||
this.localSettings.maxHeaderListSize = @intCast(maxHeaderSizeValue);
|
||||
} else if (!maxHeaderSize.isEmptyOrUndefinedOrNull()) {
|
||||
} else if (!maxHeaderSize.isEmptyOrUndefined()) {
|
||||
return globalObject.ERR(.HTTP2_INVALID_SETTING_VALUE, "Expected maxHeaderSize to be a number", .{}).throw();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ static EncodedJSValue getOwnProxyObject(JSPropertyIterator* iter, JSObject* obje
|
||||
return JSValue::encode(result);
|
||||
}
|
||||
|
||||
extern "C" EncodedJSValue Bun__JSPropertyIterator__getNameAndValue(JSPropertyIterator* iter, JSC::JSGlobalObject* globalObject, JSC::JSObject* object, BunString* propertyName, size_t i)
|
||||
extern "C" EncodedJSValue Bun__JSPropertyIterator__getNameAndValue(JSPropertyIterator* iter, JSC::JSGlobalObject* globalObject, JSC::JSObject* object, JSValue* key, BunString* propertyName, size_t i)
|
||||
{
|
||||
auto& vm = iter->vm;
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
@@ -149,11 +149,12 @@ extern "C" EncodedJSValue Bun__JSPropertyIterator__getNameAndValue(JSPropertyIte
|
||||
JSValue result = slot.getValue(globalObject, prop);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
*key = jsString(vm, String(prop.impl()));
|
||||
*propertyName = Bun::toString(prop.impl());
|
||||
return JSValue::encode(result);
|
||||
}
|
||||
|
||||
extern "C" EncodedJSValue Bun__JSPropertyIterator__getNameAndValueNonObservable(JSPropertyIterator* iter, JSC::JSGlobalObject* globalObject, JSC::JSObject* object, BunString* propertyName, size_t i)
|
||||
extern "C" EncodedJSValue Bun__JSPropertyIterator__getNameAndValueNonObservable(JSPropertyIterator* iter, JSC::JSGlobalObject* globalObject, JSC::JSObject* object, JSValue* key, BunString* propertyName, size_t i)
|
||||
{
|
||||
auto& vm = iter->vm;
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
@@ -176,13 +177,16 @@ extern "C" EncodedJSValue Bun__JSPropertyIterator__getNameAndValueNonObservable(
|
||||
JSValue result = slot.getPureResult();
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
*key = jsString(vm, String(prop.impl()));
|
||||
*propertyName = Bun::toString(prop.impl());
|
||||
return JSValue::encode(result);
|
||||
}
|
||||
|
||||
extern "C" void Bun__JSPropertyIterator__getName(JSPropertyIterator* iter, BunString* propertyName, size_t i)
|
||||
extern "C" void Bun__JSPropertyIterator__getName(JSPropertyIterator* iter, JSValue* key, BunString* propertyName, size_t i)
|
||||
{
|
||||
auto& vm = iter->vm;
|
||||
const auto& prop = iter->properties->propertyNameVector()[i];
|
||||
*key = jsString(vm, String(prop.impl()));
|
||||
*propertyName = Bun::toString(prop.impl());
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ pub fn JSPropertyIterator(comptime options: JSPropertyIteratorOptions) type {
|
||||
globalObject: *jsc.JSGlobalObject,
|
||||
object: *jsc.JSObject,
|
||||
// current property being yielded
|
||||
key: jsc.JSValue = .zero,
|
||||
value: jsc.JSValue = .zero,
|
||||
|
||||
pub fn getLongestPropertyName(this: *@This()) usize {
|
||||
@@ -78,13 +79,13 @@ pub fn JSPropertyIterator(comptime options: JSPropertyIteratorOptions) type {
|
||||
var name = bun.String.dead;
|
||||
if (comptime options.include_value) {
|
||||
const FnToUse = if (options.observable) JSPropertyIteratorImpl.getNameAndValue else JSPropertyIteratorImpl.getNameAndValueNonObservable;
|
||||
const current: jsc.JSValue = try FnToUse(this.impl.?, this.globalObject, this.object, &name, i);
|
||||
const current: jsc.JSValue = try FnToUse(this.impl.?, this.globalObject, this.object, &this.key, &name, i);
|
||||
if (current == .zero) continue;
|
||||
current.ensureStillAlive();
|
||||
this.value = current;
|
||||
} else {
|
||||
// Exception check is unnecessary here because it won't throw.
|
||||
this.impl.?.getName(&name, i);
|
||||
this.impl.?.getName(&this.key, &name, i);
|
||||
}
|
||||
|
||||
if (name.tag == .Dead) {
|
||||
@@ -118,20 +119,20 @@ const JSPropertyIteratorImpl = opaque {
|
||||
|
||||
pub const deinit = Bun__JSPropertyIterator__deinit;
|
||||
|
||||
pub fn getNameAndValue(iter: *JSPropertyIteratorImpl, globalObject: *jsc.JSGlobalObject, object: *jsc.JSObject, propertyName: *bun.String, i: usize) bun.JSError!jsc.JSValue {
|
||||
pub fn getNameAndValue(iter: *JSPropertyIteratorImpl, globalObject: *jsc.JSGlobalObject, object: *jsc.JSObject, key: *jsc.JSValue, propertyName: *bun.String, i: usize) bun.JSError!jsc.JSValue {
|
||||
var scope: bun.jsc.CatchScope = undefined;
|
||||
scope.init(globalObject, @src());
|
||||
defer scope.deinit();
|
||||
const value = Bun__JSPropertyIterator__getNameAndValue(iter, globalObject, object, propertyName, i);
|
||||
const value = Bun__JSPropertyIterator__getNameAndValue(iter, globalObject, object, key, propertyName, i);
|
||||
try scope.returnIfException();
|
||||
return value;
|
||||
}
|
||||
|
||||
pub fn getNameAndValueNonObservable(iter: *JSPropertyIteratorImpl, globalObject: *jsc.JSGlobalObject, object: *jsc.JSObject, propertyName: *bun.String, i: usize) bun.JSError!jsc.JSValue {
|
||||
pub fn getNameAndValueNonObservable(iter: *JSPropertyIteratorImpl, globalObject: *jsc.JSGlobalObject, object: *jsc.JSObject, key: *jsc.JSValue, propertyName: *bun.String, i: usize) bun.JSError!jsc.JSValue {
|
||||
var scope: bun.jsc.CatchScope = undefined;
|
||||
scope.init(globalObject, @src());
|
||||
defer scope.deinit();
|
||||
const value = Bun__JSPropertyIterator__getNameAndValueNonObservable(iter, globalObject, object, propertyName, i);
|
||||
const value = Bun__JSPropertyIterator__getNameAndValueNonObservable(iter, globalObject, object, key, propertyName, i);
|
||||
try scope.returnIfException();
|
||||
return value;
|
||||
}
|
||||
@@ -142,9 +143,9 @@ const JSPropertyIteratorImpl = opaque {
|
||||
|
||||
/// may return null without an exception
|
||||
extern "c" fn Bun__JSPropertyIterator__create(globalObject: *jsc.JSGlobalObject, encodedValue: jsc.JSValue, count: *usize, own_properties_only: bool, only_non_index_properties: bool) ?*JSPropertyIteratorImpl;
|
||||
extern "c" fn Bun__JSPropertyIterator__getNameAndValue(iter: *JSPropertyIteratorImpl, globalObject: *jsc.JSGlobalObject, object: *jsc.JSObject, propertyName: *bun.String, i: usize) jsc.JSValue;
|
||||
extern "c" fn Bun__JSPropertyIterator__getNameAndValueNonObservable(iter: *JSPropertyIteratorImpl, globalObject: *jsc.JSGlobalObject, object: *jsc.JSObject, propertyName: *bun.String, i: usize) jsc.JSValue;
|
||||
extern "c" fn Bun__JSPropertyIterator__getName(iter: *JSPropertyIteratorImpl, propertyName: *bun.String, i: usize) void;
|
||||
extern "c" fn Bun__JSPropertyIterator__getNameAndValue(iter: *JSPropertyIteratorImpl, globalObject: *jsc.JSGlobalObject, object: *jsc.JSObject, key: *jsc.JSValue, propertyName: *bun.String, i: usize) jsc.JSValue;
|
||||
extern "c" fn Bun__JSPropertyIterator__getNameAndValueNonObservable(iter: *JSPropertyIteratorImpl, globalObject: *jsc.JSGlobalObject, object: *jsc.JSObject, key: *jsc.JSValue, propertyName: *bun.String, i: usize) jsc.JSValue;
|
||||
extern "c" fn Bun__JSPropertyIterator__getName(iter: *JSPropertyIteratorImpl, key: *jsc.JSValue, propertyName: *bun.String, i: usize) void;
|
||||
extern "c" fn Bun__JSPropertyIterator__deinit(iter: *JSPropertyIteratorImpl) void;
|
||||
extern "c" fn Bun__JSPropertyIterator__getLongestPropertyName(iter: *JSPropertyIteratorImpl, globalObject: *jsc.JSGlobalObject, object: *jsc.JSObject) usize;
|
||||
};
|
||||
|
||||
@@ -859,6 +859,12 @@ pub const JSValue = enum(i64) {
|
||||
pub inline fn isNull(this: JSValue) bool {
|
||||
return this == .null;
|
||||
}
|
||||
pub inline fn isEmptyOrUndefined(this: JSValue) bool {
|
||||
return switch (this) {
|
||||
.zero, .js_undefined => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
pub inline fn isEmptyOrUndefinedOrNull(this: JSValue) bool {
|
||||
return switch (@intFromEnum(this)) {
|
||||
0, 0xa, 0x2 => true,
|
||||
|
||||
@@ -2974,8 +2974,11 @@ class ServerHttp2Session extends Http2Session {
|
||||
|
||||
settings(settings: Settings, callback) {
|
||||
this.#pendingSettingsAck = true;
|
||||
if (callback) {
|
||||
validateFunction(callback, "callback");
|
||||
}
|
||||
this.#parser?.settings(settings);
|
||||
if (typeof callback === "function") {
|
||||
if (callback) {
|
||||
const start = Date.now();
|
||||
this.once("localSettings", () => {
|
||||
callback(null, this.#localSettings, Date.now() - start);
|
||||
@@ -3412,8 +3415,11 @@ class ClientHttp2Session extends Http2Session {
|
||||
|
||||
settings(settings: Settings, callback) {
|
||||
this.#pendingSettingsAck = true;
|
||||
if (callback) {
|
||||
validateFunction(callback, "callback");
|
||||
}
|
||||
this.#parser?.settings(settings);
|
||||
if (typeof callback === "function") {
|
||||
if (callback) {
|
||||
const start = Date.now();
|
||||
this.once("localSettings", () => {
|
||||
callback(null, this.#localSettings, Date.now() - start);
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
if (!common.hasCrypto)
|
||||
common.skip('missing crypto');
|
||||
const assert = require('assert');
|
||||
const h2 = require('http2');
|
||||
|
||||
const server = h2.createServer();
|
||||
|
||||
// We use the lower-level API here
|
||||
server.on('stream', common.mustCall((stream, headers, flags) => {
|
||||
stream.respond();
|
||||
stream.end('ok');
|
||||
}));
|
||||
server.on('session', common.mustCall((session) => {
|
||||
session.on('remoteSettings', common.mustCall(2));
|
||||
}));
|
||||
|
||||
server.listen(0, common.mustCall(() => {
|
||||
const client = h2.connect(`http://localhost:${server.address().port}`);
|
||||
|
||||
[
|
||||
['headerTableSize', -1, RangeError],
|
||||
['headerTableSize', 2 ** 32, RangeError],
|
||||
['initialWindowSize', -1, RangeError],
|
||||
['initialWindowSize', 2 ** 32, RangeError],
|
||||
['maxFrameSize', 1, RangeError],
|
||||
['maxFrameSize', 2 ** 24, RangeError],
|
||||
['maxConcurrentStreams', -1, RangeError],
|
||||
['maxConcurrentStreams', 2 ** 32, RangeError],
|
||||
['maxHeaderListSize', -1, RangeError],
|
||||
['maxHeaderListSize', 2 ** 32, RangeError],
|
||||
['maxHeaderSize', -1, RangeError],
|
||||
['maxHeaderSize', 2 ** 32, RangeError],
|
||||
['enablePush', 'a', TypeError],
|
||||
['enablePush', 1, TypeError],
|
||||
['enablePush', 0, TypeError],
|
||||
['enablePush', null, TypeError],
|
||||
['enablePush', {}, TypeError],
|
||||
].forEach(([name, value, errorType]) => {
|
||||
assert.throws(
|
||||
() => client.settings({ [name]: value }),
|
||||
{
|
||||
code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
|
||||
name: errorType.name
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() => client.settings({ customSettings: {
|
||||
0x11: 5,
|
||||
0x12: 5,
|
||||
0x13: 5,
|
||||
0x14: 5,
|
||||
0x15: 5,
|
||||
0x16: 5,
|
||||
0x17: 5,
|
||||
0x18: 5,
|
||||
0x19: 5,
|
||||
0x1A: 5, // more than 10
|
||||
0x1B: 5
|
||||
} }),
|
||||
{
|
||||
code: 'ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS',
|
||||
name: 'Error'
|
||||
}
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
() => client.settings({ customSettings: {
|
||||
0x10000: 5,
|
||||
} }),
|
||||
{
|
||||
code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
|
||||
name: 'RangeError'
|
||||
}
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
() => client.settings({ customSettings: {
|
||||
0x55: 0x100000000,
|
||||
} }),
|
||||
{
|
||||
code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
|
||||
name: 'RangeError'
|
||||
}
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
() => client.settings({ customSettings: {
|
||||
0x55: -1,
|
||||
} }),
|
||||
{
|
||||
code: 'ERR_HTTP2_INVALID_SETTING_VALUE',
|
||||
name: 'RangeError'
|
||||
}
|
||||
);
|
||||
|
||||
[1, true, {}, []].forEach((invalidCallback) => {
|
||||
assert.throws(
|
||||
() => client.settings({}, invalidCallback),
|
||||
{
|
||||
name: 'TypeError',
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
client.settings({ maxFrameSize: 1234567, customSettings: { 0xbf: 12 } });
|
||||
|
||||
const req = client.request();
|
||||
req.on('response', common.mustCall());
|
||||
req.resume();
|
||||
req.on('close', common.mustCall(() => {
|
||||
server.close();
|
||||
client.close();
|
||||
}));
|
||||
}));
|
||||
Reference in New Issue
Block a user