mirror of
https://github.com/zebrajr/node.git
synced 2025-12-06 00:20:08 +01:00
quic: reduce boilerplate and other minor cleanups
While I get that macros aren't the most loved thing in the world, they do help reduce boilerplate, and there's a lot of boilerplate in the QUIC code. This commit cleans up some of that boilerplate, particularly around the use of v8 APIs. PR-URL: https://github.com/nodejs/node/pull/59342 Reviewed-By: Stephen Belanger <admin@stephenbelanger.com> Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
This commit is contained in:
parent
cd9fd09a27
commit
b4af647920
|
|
@ -1826,16 +1826,6 @@ added: v21.2.0
|
|||
|
||||
Disable exposition of [Navigator API][] on the global scope.
|
||||
|
||||
### `--no-experimental-quic`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
> Stability: 1.1 - Active Development
|
||||
|
||||
Use this flag to disable QUIC.
|
||||
|
||||
### `--no-experimental-repl-await`
|
||||
|
||||
<!-- YAML
|
||||
|
|
@ -3462,6 +3452,7 @@ one is included in the list below.
|
|||
* `--experimental-loader`
|
||||
* `--experimental-modules`
|
||||
* `--experimental-print-required-tla`
|
||||
* `--experimental-quic`
|
||||
* `--experimental-require-module`
|
||||
* `--experimental-shadow-realm`
|
||||
* `--experimental-specifier-resolution`
|
||||
|
|
|
|||
|
|
@ -226,9 +226,6 @@ flag is no longer required as WASI is enabled by default.
|
|||
.It Fl -experimental-quic
|
||||
Enable the experimental QUIC support.
|
||||
.
|
||||
.It Fl -no-experimental-quic
|
||||
Disable the experimental QUIC support.
|
||||
.
|
||||
.It Fl -experimental-inspector-network-resource
|
||||
Enable experimental support for inspector network resources.
|
||||
.
|
||||
|
|
|
|||
|
|
@ -15,11 +15,14 @@ const {
|
|||
Uint8Array,
|
||||
} = primordials;
|
||||
|
||||
// QUIC requires that Node.js be compiled with crypto support.
|
||||
const {
|
||||
assertCrypto,
|
||||
} = require('internal/util');
|
||||
assertCrypto();
|
||||
getOptionValue,
|
||||
} = require('internal/options');
|
||||
|
||||
// QUIC requires that Node.js be compiled with crypto support.
|
||||
if (!process.features.quic || !getOptionValue('--experimental-quic')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { inspect } = require('internal/util/inspect');
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,14 @@ const {
|
|||
JSONStringify,
|
||||
} = primordials;
|
||||
|
||||
const {
|
||||
getOptionValue,
|
||||
} = require('internal/options');
|
||||
|
||||
if (!process.features.quic || !getOptionValue('--experimental-quic')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {
|
||||
codes: {
|
||||
ERR_ILLEGAL_CONSTRUCTOR,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,14 @@ const {
|
|||
JSONStringify,
|
||||
} = primordials;
|
||||
|
||||
const {
|
||||
getOptionValue,
|
||||
} = require('internal/options');
|
||||
|
||||
if (!process.features.quic || !getOptionValue('--experimental-quic')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {
|
||||
isArrayBuffer,
|
||||
} = require('util/types');
|
||||
|
|
|
|||
|
|
@ -4,6 +4,14 @@ const {
|
|||
Symbol,
|
||||
} = primordials;
|
||||
|
||||
const {
|
||||
getOptionValue,
|
||||
} = require('internal/options');
|
||||
|
||||
if (!process.features.quic || !getOptionValue('--experimental-quic')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {
|
||||
customInspectSymbol: kInspect,
|
||||
} = require('internal/util');
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ namespace node {
|
|||
V(simdutf) \
|
||||
V(ada) \
|
||||
V(nbytes) \
|
||||
V(ngtcp2) \
|
||||
V(nghttp3) \
|
||||
NODE_VERSIONS_KEY_AMARO(V) \
|
||||
NODE_VERSIONS_KEY_UNDICI(V) \
|
||||
V(cjs_module_lexer)
|
||||
|
|
@ -80,14 +82,6 @@ namespace node {
|
|||
#define NODE_VERSIONS_KEY_INTL(V)
|
||||
#endif // NODE_HAVE_I18N_SUPPORT
|
||||
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
#define NODE_VERSIONS_KEY_QUIC(V) \
|
||||
V(ngtcp2) \
|
||||
V(nghttp3)
|
||||
#else
|
||||
#define NODE_VERSIONS_KEY_QUIC(V)
|
||||
#endif
|
||||
|
||||
#if HAVE_SQLITE
|
||||
#define NODE_VERSIONS_KEY_SQLITE(V) V(sqlite)
|
||||
#else
|
||||
|
|
@ -98,7 +92,6 @@ namespace node {
|
|||
NODE_VERSIONS_KEYS_BASE(V) \
|
||||
NODE_VERSIONS_KEY_CRYPTO(V) \
|
||||
NODE_VERSIONS_KEY_INTL(V) \
|
||||
NODE_VERSIONS_KEY_QUIC(V) \
|
||||
NODE_VERSIONS_KEY_SQLITE(V)
|
||||
|
||||
#define V(key) +1
|
||||
|
|
|
|||
|
|
@ -551,10 +551,11 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() {
|
|||
kAllowedInEnvvar,
|
||||
true);
|
||||
AddOption("--experimental-quic",
|
||||
"" /* undocumented until its development */,
|
||||
#ifndef OPENSSL_NO_QUIC
|
||||
"experimental QUIC support",
|
||||
&EnvironmentOptions::experimental_quic,
|
||||
#else
|
||||
"" /* undocumented when no-op */,
|
||||
NoOp{},
|
||||
#endif
|
||||
kAllowedInEnvvar);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
namespace node {
|
||||
|
||||
using v8::Function;
|
||||
using v8::FunctionCallbackInfo;
|
||||
using v8::FunctionTemplate;
|
||||
using v8::Local;
|
||||
using v8::Object;
|
||||
|
|
@ -144,7 +143,7 @@ QUIC_JS_CALLBACKS(V)
|
|||
|
||||
#undef V
|
||||
|
||||
void BindingData::SetCallbacks(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD_IMPL(BindingData::SetCallbacks) {
|
||||
auto env = Environment::GetCurrent(args);
|
||||
auto isolate = env->isolate();
|
||||
auto& state = Get(env);
|
||||
|
|
@ -166,7 +165,7 @@ void BindingData::SetCallbacks(const FunctionCallbackInfo<Value>& args) {
|
|||
#undef V
|
||||
}
|
||||
|
||||
void BindingData::FlushPacketFreelist(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD_IMPL(BindingData::FlushPacketFreelist) {
|
||||
auto env = Environment::GetCurrent(args);
|
||||
auto& state = Get(env);
|
||||
state.packet_freelist.clear();
|
||||
|
|
@ -217,7 +216,7 @@ CallbackScopeBase::~CallbackScopeBase() {
|
|||
}
|
||||
}
|
||||
|
||||
void IllegalConstructor(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD_IMPL(IllegalConstructor) {
|
||||
THROW_ERR_ILLEGAL_CONSTRUCTOR(Environment::GetCurrent(args));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -167,16 +167,15 @@ class BindingData final
|
|||
|
||||
// Installs the set of JavaScript callback functions that are used to
|
||||
// bridge out to the JS API.
|
||||
static void SetCallbacks(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
JS_METHOD(SetCallbacks);
|
||||
|
||||
// Purge the packet free list to free up memory.
|
||||
JS_METHOD(FlushPacketFreelist);
|
||||
|
||||
std::vector<BaseObjectPtr<BaseObject>> packet_freelist;
|
||||
|
||||
std::unordered_map<Endpoint*, BaseObjectPtr<BaseObject>> listening_endpoints;
|
||||
|
||||
// Purge the packet free list to free up memory.
|
||||
static void FlushPacketFreelist(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
|
||||
bool in_ngtcp2_callback_scope = false;
|
||||
bool in_nghttp3_callback_scope = false;
|
||||
size_t current_ngtcp2_memory_ = 0;
|
||||
|
|
@ -223,7 +222,7 @@ class BindingData final
|
|||
#undef V
|
||||
};
|
||||
|
||||
void IllegalConstructor(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
JS_METHOD_IMPL(IllegalConstructor);
|
||||
|
||||
// The ngtcp2 and nghttp3 callbacks have certain restrictions
|
||||
// that forbid re-entry. We provide the following scopes for
|
||||
|
|
|
|||
|
|
@ -375,8 +375,6 @@ QuicError QuicError::FromConnectionClose(ngtcp2_conn* session) {
|
|||
return QuicError(ngtcp2_conn_get_ccerr(session));
|
||||
}
|
||||
|
||||
const QuicError QuicError::TRANSPORT_NO_ERROR =
|
||||
ForTransport(TransportError::NO_ERROR_);
|
||||
#define V(name) \
|
||||
const QuicError QuicError::TRANSPORT_##name = \
|
||||
ForTransport(TransportError::name);
|
||||
|
|
|
|||
|
|
@ -156,9 +156,6 @@ class QuicError final : public MemoryRetainer {
|
|||
// it as is.
|
||||
NO_ERROR_ = NGTCP2_NO_ERROR,
|
||||
#define V(name) name = NGTCP2_##name,
|
||||
// The NO_ERROR here has to be treated as a special case since there
|
||||
// is a NO_ERROR macro defined in Windows that conflicts.
|
||||
NO_ERROR_ = NGTCP2_NO_ERROR,
|
||||
QUIC_TRANSPORT_ERRORS(V)
|
||||
#undef V
|
||||
};
|
||||
|
|
|
|||
|
|
@ -161,8 +161,96 @@ uint64_t GetStat(Stats* stats) {
|
|||
name##_STATS(STAT_FIELD) \
|
||||
};
|
||||
|
||||
#define JS_METHOD(name) \
|
||||
static void name(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||||
#define JS_METHOD_IMPL(name) \
|
||||
void name(const v8::FunctionCallbackInfo<v8::Value>& args)
|
||||
|
||||
#define JS_METHOD(name) static JS_METHOD_IMPL(name)
|
||||
|
||||
#define JS_CONSTRUCTOR(name) \
|
||||
inline static bool HasInstance(Environment* env, \
|
||||
v8::Local<v8::Value> value) { \
|
||||
return GetConstructorTemplate(env)->HasInstance(value); \
|
||||
} \
|
||||
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate( \
|
||||
Environment* env)
|
||||
|
||||
#define JS_CONSTRUCTOR_IMPL(name, template, body) \
|
||||
v8::Local<v8::FunctionTemplate> name::GetConstructorTemplate( \
|
||||
Environment* env) { \
|
||||
auto& state = BindingData::Get(env); \
|
||||
auto tmpl = state.template(); \
|
||||
if (tmpl.IsEmpty()) { \
|
||||
body state.set_##template(tmpl); \
|
||||
} \
|
||||
return tmpl; \
|
||||
}
|
||||
|
||||
#define JS_ILLEGAL_CONSTRUCTOR() \
|
||||
tmpl = NewFunctionTemplate(env->isolate(), IllegalConstructor)
|
||||
|
||||
#define JS_NEW_CONSTRUCTOR() tmpl = NewFunctionTemplate(env->isolate(), New)
|
||||
|
||||
#define JS_INHERIT(name) tmpl->Inherit(name::GetConstructorTemplate(env));
|
||||
|
||||
#define JS_CLASS(name) \
|
||||
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount); \
|
||||
tmpl->SetClassName(state.name##_string())
|
||||
|
||||
#define JS_CLASS_FIELDS(name, fields) \
|
||||
tmpl->InstanceTemplate()->SetInternalFieldCount(fields); \
|
||||
tmpl->SetClassName(state.name##_string())
|
||||
|
||||
#define JS_NEW_INSTANCE_OR_RETURN(env, name, ret) \
|
||||
v8::Local<v8::Object> name; \
|
||||
if (!GetConstructorTemplate(env) \
|
||||
->InstanceTemplate() \
|
||||
->NewInstance(env->context()) \
|
||||
.ToLocal(&obj)) { \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define JS_NEW_INSTANCE(env, name) \
|
||||
v8::Local<v8::Object> name; \
|
||||
if (!GetConstructorTemplate(env) \
|
||||
->InstanceTemplate() \
|
||||
->NewInstance(env->context()) \
|
||||
.ToLocal(&obj)) { \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define JS_BINDING_INIT_BOILERPLATE() \
|
||||
static void InitPerIsolate(IsolateData* isolate_data, \
|
||||
v8::Local<v8::ObjectTemplate> target); \
|
||||
static void InitPerContext(Realm* realm, v8::Local<v8::Object> target); \
|
||||
static void RegisterExternalReferences(ExternalReferenceRegistry* registry)
|
||||
|
||||
#define JS_TRY_ALLOCATE_BACKING(env, name, len) \
|
||||
auto name = v8::ArrayBuffer::NewBackingStore( \
|
||||
env->isolate(), \
|
||||
len, \
|
||||
v8::BackingStoreInitializationMode::kUninitialized, \
|
||||
v8::BackingStoreOnFailureMode::kReturnNull); \
|
||||
if (!name) { \
|
||||
THROW_ERR_MEMORY_ALLOCATION_FAILED(env); \
|
||||
return; \
|
||||
}
|
||||
|
||||
#define JS_TRY_ALLOCATE_BACKING_OR_RETURN(env, name, len, ret) \
|
||||
auto name = v8::ArrayBuffer::NewBackingStore( \
|
||||
env->isolate(), \
|
||||
len, \
|
||||
v8::BackingStoreInitializationMode::kUninitialized, \
|
||||
v8::BackingStoreOnFailureMode::kReturnNull); \
|
||||
if (!name) { \
|
||||
THROW_ERR_MEMORY_ALLOCATION_FAILED(env); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define JS_DEFINE_READONLY_PROPERTY(env, target, name, value) \
|
||||
target \
|
||||
->DefineOwnProperty( \
|
||||
env->context(), name, value, v8::PropertyAttribute::ReadOnly) \
|
||||
.Check();
|
||||
|
||||
enum class Side : uint8_t {
|
||||
CLIENT,
|
||||
|
|
@ -222,7 +310,7 @@ CC_ALGOS(V)
|
|||
#undef V
|
||||
|
||||
constexpr size_t kDefaultMaxPacketLength = NGTCP2_MAX_UDP_PAYLOAD_SIZE;
|
||||
constexpr size_t kMaxSizeT = std::numeric_limits<size_t>::max();
|
||||
constexpr uint64_t kMaxSizeT = std::numeric_limits<size_t>::max();
|
||||
constexpr uint64_t kMaxSafeJsInteger = 9007199254740991;
|
||||
constexpr auto kSocketAddressInfoTimeout = 60 * NGTCP2_SECONDS;
|
||||
constexpr size_t kMaxVectorCount = 16;
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ namespace node {
|
|||
|
||||
using v8::ArrayBufferView;
|
||||
using v8::BackingStore;
|
||||
using v8::FunctionCallbackInfo;
|
||||
using v8::FunctionTemplate;
|
||||
using v8::HandleScope;
|
||||
using v8::Integer;
|
||||
using v8::Just;
|
||||
|
|
@ -38,7 +36,6 @@ using v8::Nothing;
|
|||
using v8::Number;
|
||||
using v8::Object;
|
||||
using v8::ObjectTemplate;
|
||||
using v8::PropertyAttribute;
|
||||
using v8::String;
|
||||
using v8::Uint32;
|
||||
using v8::Value;
|
||||
|
|
@ -284,27 +281,10 @@ std::string Endpoint::Options::ToString() const {
|
|||
|
||||
class Endpoint::UDP::Impl final : public HandleWrap {
|
||||
public:
|
||||
static Local<FunctionTemplate> GetConstructorTemplate(Environment* env) {
|
||||
auto& state = BindingData::Get(env);
|
||||
auto tmpl = state.udp_constructor_template();
|
||||
if (tmpl.IsEmpty()) {
|
||||
tmpl = NewFunctionTemplate(env->isolate(), IllegalConstructor);
|
||||
tmpl->Inherit(HandleWrap::GetConstructorTemplate(env));
|
||||
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount);
|
||||
tmpl->SetClassName(state.endpoint_udp_string());
|
||||
state.set_udp_constructor_template(tmpl);
|
||||
}
|
||||
return tmpl;
|
||||
}
|
||||
JS_CONSTRUCTOR(Impl);
|
||||
|
||||
static Impl* Create(Endpoint* endpoint) {
|
||||
Local<Object> obj;
|
||||
if (!GetConstructorTemplate(endpoint->env())
|
||||
->InstanceTemplate()
|
||||
->NewInstance(endpoint->env()->context())
|
||||
.ToLocal(&obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
JS_NEW_INSTANCE_OR_RETURN(endpoint->env(), obj, nullptr);
|
||||
return new Impl(endpoint, obj);
|
||||
}
|
||||
|
||||
|
|
@ -367,6 +347,12 @@ class Endpoint::UDP::Impl final : public HandleWrap {
|
|||
friend class UDP;
|
||||
};
|
||||
|
||||
JS_CONSTRUCTOR_IMPL(Endpoint::UDP::Impl, udp_constructor_template, {
|
||||
JS_ILLEGAL_CONSTRUCTOR();
|
||||
JS_INHERIT(HandleWrap);
|
||||
JS_CLASS(endpoint_udp);
|
||||
})
|
||||
|
||||
Endpoint::UDP::UDP(Endpoint* endpoint) : impl_(Impl::Create(endpoint)) {
|
||||
DCHECK(impl_);
|
||||
// The endpoint starts in an inactive, unref'd state. It will be ref'd when
|
||||
|
|
@ -512,29 +498,18 @@ void Endpoint::UDP::MemoryInfo(MemoryTracker* tracker) const {
|
|||
|
||||
// ============================================================================
|
||||
|
||||
bool Endpoint::HasInstance(Environment* env, Local<Value> value) {
|
||||
return GetConstructorTemplate(env)->HasInstance(value);
|
||||
}
|
||||
|
||||
Local<FunctionTemplate> Endpoint::GetConstructorTemplate(Environment* env) {
|
||||
auto& state = BindingData::Get(env);
|
||||
auto tmpl = state.endpoint_constructor_template();
|
||||
if (tmpl.IsEmpty()) {
|
||||
auto isolate = env->isolate();
|
||||
tmpl = NewFunctionTemplate(isolate, New);
|
||||
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
|
||||
tmpl->SetClassName(state.endpoint_string());
|
||||
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount);
|
||||
SetProtoMethod(isolate, tmpl, "listen", DoListen);
|
||||
SetProtoMethod(isolate, tmpl, "closeGracefully", DoCloseGracefully);
|
||||
SetProtoMethod(isolate, tmpl, "connect", DoConnect);
|
||||
SetProtoMethod(isolate, tmpl, "markBusy", MarkBusy);
|
||||
SetProtoMethod(isolate, tmpl, "ref", Ref);
|
||||
SetProtoMethodNoSideEffect(isolate, tmpl, "address", LocalAddress);
|
||||
state.set_endpoint_constructor_template(tmpl);
|
||||
}
|
||||
return tmpl;
|
||||
}
|
||||
JS_CONSTRUCTOR_IMPL(Endpoint, endpoint_constructor_template, {
|
||||
auto isolate = env->isolate();
|
||||
JS_NEW_CONSTRUCTOR();
|
||||
JS_INHERIT(AsyncWrap);
|
||||
JS_CLASS(endpoint);
|
||||
SetProtoMethod(isolate, tmpl, "listen", DoListen);
|
||||
SetProtoMethod(isolate, tmpl, "closeGracefully", DoCloseGracefully);
|
||||
SetProtoMethod(isolate, tmpl, "connect", DoConnect);
|
||||
SetProtoMethod(isolate, tmpl, "markBusy", MarkBusy);
|
||||
SetProtoMethod(isolate, tmpl, "ref", Ref);
|
||||
SetProtoMethodNoSideEffect(isolate, tmpl, "address", LocalAddress);
|
||||
})
|
||||
|
||||
void Endpoint::InitPerIsolate(IsolateData* data, Local<ObjectTemplate> target) {
|
||||
// TODO(@jasnell): Implement the per-isolate state
|
||||
|
|
@ -576,17 +551,17 @@ void Endpoint::InitPerContext(Realm* realm, Local<Object> target) {
|
|||
NODE_DEFINE_CONSTANT(target, DEFAULT_MAX_PACKET_LENGTH);
|
||||
|
||||
static constexpr auto CLOSECONTEXT_CLOSE =
|
||||
static_cast<int>(CloseContext::CLOSE);
|
||||
static_cast<uint8_t>(CloseContext::CLOSE);
|
||||
static constexpr auto CLOSECONTEXT_BIND_FAILURE =
|
||||
static_cast<int>(CloseContext::BIND_FAILURE);
|
||||
static_cast<uint8_t>(CloseContext::BIND_FAILURE);
|
||||
static constexpr auto CLOSECONTEXT_LISTEN_FAILURE =
|
||||
static_cast<int>(CloseContext::LISTEN_FAILURE);
|
||||
static_cast<uint8_t>(CloseContext::LISTEN_FAILURE);
|
||||
static constexpr auto CLOSECONTEXT_RECEIVE_FAILURE =
|
||||
static_cast<int>(CloseContext::RECEIVE_FAILURE);
|
||||
static_cast<uint8_t>(CloseContext::RECEIVE_FAILURE);
|
||||
static constexpr auto CLOSECONTEXT_SEND_FAILURE =
|
||||
static_cast<int>(CloseContext::SEND_FAILURE);
|
||||
static_cast<uint8_t>(CloseContext::SEND_FAILURE);
|
||||
static constexpr auto CLOSECONTEXT_START_FAILURE =
|
||||
static_cast<int>(CloseContext::START_FAILURE);
|
||||
static_cast<uint8_t>(CloseContext::START_FAILURE);
|
||||
NODE_DEFINE_CONSTANT(target, CLOSECONTEXT_CLOSE);
|
||||
NODE_DEFINE_CONSTANT(target, CLOSECONTEXT_BIND_FAILURE);
|
||||
NODE_DEFINE_CONSTANT(target, CLOSECONTEXT_LISTEN_FAILURE);
|
||||
|
|
@ -628,15 +603,10 @@ Endpoint::Endpoint(Environment* env,
|
|||
Debug(this, "Endpoint created. Options %s", options.ToString());
|
||||
}
|
||||
|
||||
const auto defineProperty = [&](auto name, auto value) {
|
||||
object
|
||||
->DefineOwnProperty(
|
||||
env->context(), name, value, PropertyAttribute::ReadOnly)
|
||||
.Check();
|
||||
};
|
||||
|
||||
defineProperty(env->state_string(), state_.GetArrayBuffer());
|
||||
defineProperty(env->stats_string(), stats_.GetArrayBuffer());
|
||||
JS_DEFINE_READONLY_PROPERTY(
|
||||
env, object, env->state_string(), state_.GetArrayBuffer());
|
||||
JS_DEFINE_READONLY_PROPERTY(
|
||||
env, object, env->stats_string(), stats_.GetArrayBuffer());
|
||||
}
|
||||
|
||||
SocketAddress Endpoint::local_address() const {
|
||||
|
|
@ -1676,7 +1646,7 @@ void Endpoint::EmitClose(CloseContext context, int status) {
|
|||
// ======================================================================================
|
||||
// Endpoint JavaScript API
|
||||
|
||||
void Endpoint::New(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD_IMPL(Endpoint::New) {
|
||||
DCHECK(args.IsConstructCall());
|
||||
auto env = Environment::GetCurrent(args);
|
||||
Options options;
|
||||
|
|
@ -1689,7 +1659,7 @@ void Endpoint::New(const FunctionCallbackInfo<Value>& args) {
|
|||
new Endpoint(env, args.This(), options);
|
||||
}
|
||||
|
||||
void Endpoint::DoConnect(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD_IMPL(Endpoint::DoConnect) {
|
||||
auto env = Environment::GetCurrent(args);
|
||||
Endpoint* endpoint;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
||||
|
|
@ -1723,7 +1693,7 @@ void Endpoint::DoConnect(const FunctionCallbackInfo<Value>& args) {
|
|||
if (session) args.GetReturnValue().Set(session->object());
|
||||
}
|
||||
|
||||
void Endpoint::DoListen(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD_IMPL(Endpoint::DoListen) {
|
||||
Endpoint* endpoint;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
||||
auto env = Environment::GetCurrent(args);
|
||||
|
|
@ -1734,19 +1704,19 @@ void Endpoint::DoListen(const FunctionCallbackInfo<Value>& args) {
|
|||
}
|
||||
}
|
||||
|
||||
void Endpoint::MarkBusy(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD_IMPL(Endpoint::MarkBusy) {
|
||||
Endpoint* endpoint;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
||||
endpoint->MarkAsBusy(args[0]->IsTrue());
|
||||
}
|
||||
|
||||
void Endpoint::DoCloseGracefully(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD_IMPL(Endpoint::DoCloseGracefully) {
|
||||
Endpoint* endpoint;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
||||
endpoint->CloseGracefully();
|
||||
}
|
||||
|
||||
void Endpoint::LocalAddress(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD_IMPL(Endpoint::LocalAddress) {
|
||||
auto env = Environment::GetCurrent(args);
|
||||
Endpoint* endpoint;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
||||
|
|
@ -1756,7 +1726,7 @@ void Endpoint::LocalAddress(const FunctionCallbackInfo<Value>& args) {
|
|||
if (addr) args.GetReturnValue().Set(addr->object());
|
||||
}
|
||||
|
||||
void Endpoint::Ref(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD_IMPL(Endpoint::Ref) {
|
||||
Endpoint* endpoint;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&endpoint, args.This());
|
||||
auto env = Environment::GetCurrent(args);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace node::quic {
|
|||
class Endpoint final : public AsyncWrap, public Packet::Listener {
|
||||
public:
|
||||
static constexpr uint64_t DEFAULT_MAX_CONNECTIONS =
|
||||
std::min<uint64_t>(kMaxSizeT, static_cast<uint64_t>(kMaxSafeJsInteger));
|
||||
std::min<uint64_t>(kMaxSizeT, kMaxSafeJsInteger);
|
||||
static constexpr uint64_t DEFAULT_MAX_CONNECTIONS_PER_HOST = 100;
|
||||
static constexpr uint64_t DEFAULT_MAX_SOCKETADDRESS_LRU_SIZE =
|
||||
(DEFAULT_MAX_CONNECTIONS_PER_HOST * 10);
|
||||
|
|
@ -143,13 +143,8 @@ class Endpoint final : public AsyncWrap, public Packet::Listener {
|
|||
std::string ToString() const;
|
||||
};
|
||||
|
||||
bool HasInstance(Environment* env, v8::Local<v8::Value> value);
|
||||
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
|
||||
Environment* env);
|
||||
static void InitPerIsolate(IsolateData* data,
|
||||
v8::Local<v8::ObjectTemplate> target);
|
||||
static void InitPerContext(Realm* realm, v8::Local<v8::Object> target);
|
||||
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
|
||||
JS_CONSTRUCTOR(Endpoint);
|
||||
JS_BINDING_INIT_BOILERPLATE();
|
||||
|
||||
Endpoint(Environment* env,
|
||||
v8::Local<v8::Object> object,
|
||||
|
|
@ -300,7 +295,7 @@ class Endpoint final : public AsyncWrap, public Packet::Listener {
|
|||
void MaybeDestroy();
|
||||
|
||||
// Specifies the general reason the endpoint is being destroyed.
|
||||
enum class CloseContext {
|
||||
enum class CloseContext : uint8_t {
|
||||
CLOSE,
|
||||
BIND_FAILURE,
|
||||
START_FAILURE,
|
||||
|
|
@ -330,7 +325,7 @@ class Endpoint final : public AsyncWrap, public Packet::Listener {
|
|||
|
||||
// Create a new Endpoint.
|
||||
// @param Endpoint::Options options - Options to configure the Endpoint.
|
||||
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
JS_METHOD(New);
|
||||
|
||||
// Methods on the Endpoint instance:
|
||||
|
||||
|
|
@ -341,31 +336,30 @@ class Endpoint final : public AsyncWrap, public Packet::Listener {
|
|||
// the Session.
|
||||
// @param v8::ArrayBufferView remote_transport_params - The remote transport
|
||||
// params.
|
||||
static void DoConnect(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
JS_METHOD(DoConnect);
|
||||
|
||||
// Start listening as a QUIC server
|
||||
// @param Session::Options options - Options to configure the Session.
|
||||
static void DoListen(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
JS_METHOD(DoListen);
|
||||
|
||||
// Mark the Endpoint as busy, temporarily pausing handling of new initial
|
||||
// packets.
|
||||
// @param bool on - If true, mark the Endpoint as busy.
|
||||
static void MarkBusy(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
JS_METHOD(MarkBusy);
|
||||
static void FastMarkBusy(v8::Local<v8::Object> receiver, bool on);
|
||||
|
||||
// DoCloseGracefully is the signal that endpoint should close. Any packets
|
||||
// that are already in the queue or in flight will be allowed to finish, but
|
||||
// the EndpoingWrap will be otherwise no longer able to receive or send
|
||||
// packets.
|
||||
static void DoCloseGracefully(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
JS_METHOD(DoCloseGracefully);
|
||||
|
||||
// Get the local address of the Endpoint.
|
||||
// @return node::SocketAddress - The local address of the Endpoint.
|
||||
static void LocalAddress(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
JS_METHOD(LocalAddress);
|
||||
|
||||
// Ref() causes a listening Endpoint to keep the event loop active.
|
||||
static void Ref(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
JS_METHOD(Ref);
|
||||
static void FastRef(v8::Local<v8::Object> receiver, bool on);
|
||||
|
||||
void Receive(const uv_buf_t& buf, const SocketAddress& from);
|
||||
|
|
|
|||
|
|
@ -20,34 +20,18 @@
|
|||
|
||||
namespace node {
|
||||
|
||||
using v8::FunctionCallbackInfo;
|
||||
using v8::FunctionTemplate;
|
||||
using v8::Local;
|
||||
using v8::Object;
|
||||
using v8::ObjectTemplate;
|
||||
using v8::Value;
|
||||
|
||||
namespace quic {
|
||||
|
||||
// ============================================================================
|
||||
|
||||
bool Http3Application::HasInstance(Environment* env, Local<Value> value) {
|
||||
return GetConstructorTemplate(env)->HasInstance(value);
|
||||
}
|
||||
|
||||
Local<FunctionTemplate> Http3Application::GetConstructorTemplate(
|
||||
Environment* env) {
|
||||
auto& state = BindingData::Get(env);
|
||||
auto tmpl = state.http3application_constructor_template();
|
||||
if (tmpl.IsEmpty()) {
|
||||
auto isolate = env->isolate();
|
||||
tmpl = NewFunctionTemplate(isolate, New);
|
||||
tmpl->SetClassName(state.http3application_string());
|
||||
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount);
|
||||
state.set_http3application_constructor_template(tmpl);
|
||||
}
|
||||
return tmpl;
|
||||
}
|
||||
JS_CONSTRUCTOR_IMPL(Http3Application, http3application_constructor_template, {
|
||||
JS_NEW_CONSTRUCTOR();
|
||||
JS_CLASS(http3application);
|
||||
})
|
||||
|
||||
void Http3Application::InitPerIsolate(IsolateData* isolate_data,
|
||||
Local<ObjectTemplate> target) {
|
||||
|
|
@ -73,17 +57,11 @@ Http3Application::Http3Application(Environment* env,
|
|||
MakeWeak();
|
||||
}
|
||||
|
||||
void Http3Application::New(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD_IMPL(Http3Application::New) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
CHECK(args.IsConstructCall());
|
||||
|
||||
Local<Object> obj;
|
||||
if (!GetConstructorTemplate(env)
|
||||
->InstanceTemplate()
|
||||
->NewInstance(env->context())
|
||||
.ToLocal(&obj)) {
|
||||
return;
|
||||
}
|
||||
JS_NEW_INSTANCE(env, obj);
|
||||
|
||||
Session::Application::Options options;
|
||||
if (!args[0]->IsUndefined() &&
|
||||
|
|
|
|||
|
|
@ -11,13 +11,8 @@ namespace node::quic {
|
|||
// Provides an implementation of the HTTP/3 Application implementation
|
||||
class Http3Application final : public Session::ApplicationProvider {
|
||||
public:
|
||||
static bool HasInstance(Environment* env, v8::Local<v8::Value> value);
|
||||
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
|
||||
Environment* env);
|
||||
static void InitPerIsolate(IsolateData* isolate_data,
|
||||
v8::Local<v8::ObjectTemplate> target);
|
||||
static void InitPerContext(Realm* realm, v8::Local<v8::Object> target);
|
||||
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
|
||||
JS_CONSTRUCTOR(Http3Application);
|
||||
JS_BINDING_INIT_BOILERPLATE();
|
||||
|
||||
Http3Application(Environment* env,
|
||||
v8::Local<v8::Object> object,
|
||||
|
|
@ -32,7 +27,7 @@ class Http3Application final : public Session::ApplicationProvider {
|
|||
std::string ToString() const;
|
||||
|
||||
private:
|
||||
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
JS_METHOD(New);
|
||||
|
||||
Session::Application_Options options_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,29 +20,15 @@ using v8::Object;
|
|||
|
||||
namespace quic {
|
||||
|
||||
Local<FunctionTemplate> LogStream::GetConstructorTemplate(Environment* env) {
|
||||
auto& state = BindingData::Get(env);
|
||||
auto tmpl = state.logstream_constructor_template();
|
||||
if (tmpl.IsEmpty()) {
|
||||
tmpl = FunctionTemplate::New(env->isolate());
|
||||
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
|
||||
tmpl->InstanceTemplate()->SetInternalFieldCount(
|
||||
StreamBase::kInternalFieldCount);
|
||||
tmpl->SetClassName(state.logstream_string());
|
||||
StreamBase::AddMethods(env, tmpl);
|
||||
state.set_logstream_constructor_template(tmpl);
|
||||
}
|
||||
return tmpl;
|
||||
}
|
||||
JS_CONSTRUCTOR_IMPL(LogStream, logstream_constructor_template, {
|
||||
tmpl = FunctionTemplate::New(env->isolate());
|
||||
JS_INHERIT(AsyncWrap);
|
||||
JS_CLASS_FIELDS(logstream, StreamBase::kInternalFieldCount);
|
||||
StreamBase::AddMethods(env, tmpl);
|
||||
})
|
||||
|
||||
BaseObjectPtr<LogStream> LogStream::Create(Environment* env) {
|
||||
Local<Object> obj;
|
||||
if (!GetConstructorTemplate(env)
|
||||
->InstanceTemplate()
|
||||
->NewInstance(env->context())
|
||||
.ToLocal(&obj)) {
|
||||
return {};
|
||||
}
|
||||
JS_NEW_INSTANCE_OR_RETURN(env, obj, nullptr);
|
||||
return MakeDetachedBaseObject<LogStream>(env, obj);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <env.h>
|
||||
#include <stream_base.h>
|
||||
#include <list>
|
||||
#include "defs.h"
|
||||
|
||||
namespace node::quic {
|
||||
|
||||
|
|
@ -14,8 +15,7 @@ namespace node::quic {
|
|||
// and Keylog diagnostic data (one instance for each).
|
||||
class LogStream final : public AsyncWrap, public StreamBase {
|
||||
public:
|
||||
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
|
||||
Environment* env);
|
||||
JS_CONSTRUCTOR(LogStream);
|
||||
|
||||
static BaseObjectPtr<LogStream> Create(Environment* env);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
namespace node {
|
||||
|
||||
using v8::FunctionTemplate;
|
||||
using v8::Local;
|
||||
using v8::Object;
|
||||
|
||||
|
|
@ -97,18 +96,11 @@ void Packet::Truncate(size_t len) {
|
|||
data_->data_.SetLength(len);
|
||||
}
|
||||
|
||||
Local<FunctionTemplate> Packet::GetConstructorTemplate(Environment* env) {
|
||||
auto& state = BindingData::Get(env);
|
||||
Local<FunctionTemplate> tmpl = state.packet_constructor_template();
|
||||
if (tmpl.IsEmpty()) {
|
||||
tmpl = NewFunctionTemplate(env->isolate(), IllegalConstructor);
|
||||
tmpl->Inherit(ReqWrap<uv_udp_send_t>::GetConstructorTemplate(env));
|
||||
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount);
|
||||
tmpl->SetClassName(state.packetwrap_string());
|
||||
state.set_packet_constructor_template(tmpl);
|
||||
}
|
||||
return tmpl;
|
||||
}
|
||||
JS_CONSTRUCTOR_IMPL(Packet, packet_constructor_template, {
|
||||
JS_ILLEGAL_CONSTRUCTOR();
|
||||
JS_INHERIT(ReqWrap<uv_udp_send_t>);
|
||||
JS_CLASS(packetwrap);
|
||||
})
|
||||
|
||||
BaseObjectPtr<Packet> Packet::Create(Environment* env,
|
||||
Listener* listener,
|
||||
|
|
@ -116,14 +108,7 @@ BaseObjectPtr<Packet> Packet::Create(Environment* env,
|
|||
size_t length,
|
||||
const char* diagnostic_label) {
|
||||
if (BindingData::Get(env).packet_freelist.empty()) {
|
||||
Local<Object> obj;
|
||||
if (!GetConstructorTemplate(env)
|
||||
->InstanceTemplate()
|
||||
->NewInstance(env->context())
|
||||
.ToLocal(&obj)) [[unlikely]] {
|
||||
return {};
|
||||
}
|
||||
|
||||
JS_NEW_INSTANCE_OR_RETURN(env, obj, {});
|
||||
return MakeBaseObject<Packet>(
|
||||
env, listener, obj, destination, length, diagnostic_label);
|
||||
}
|
||||
|
|
@ -137,14 +122,7 @@ BaseObjectPtr<Packet> Packet::Create(Environment* env,
|
|||
BaseObjectPtr<Packet> Packet::Clone() const {
|
||||
auto& binding = BindingData::Get(env());
|
||||
if (binding.packet_freelist.empty()) {
|
||||
Local<Object> obj;
|
||||
if (!GetConstructorTemplate(env())
|
||||
->InstanceTemplate()
|
||||
->NewInstance(env()->context())
|
||||
.ToLocal(&obj)) [[unlikely]] {
|
||||
return {};
|
||||
}
|
||||
|
||||
JS_NEW_INSTANCE_OR_RETURN(env(), obj, {});
|
||||
return MakeBaseObject<Packet>(env(), listener_, obj, destination_, data_);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,8 +49,7 @@ class Packet final : public ReqWrap<uv_udp_send_t> {
|
|||
struct Data;
|
||||
|
||||
public:
|
||||
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
|
||||
Environment* env);
|
||||
JS_CONSTRUCTOR(Packet);
|
||||
|
||||
class Listener {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -37,13 +37,9 @@
|
|||
namespace node {
|
||||
|
||||
using v8::Array;
|
||||
using v8::ArrayBuffer;
|
||||
using v8::ArrayBufferView;
|
||||
using v8::BackingStoreInitializationMode;
|
||||
using v8::BigInt;
|
||||
using v8::Boolean;
|
||||
using v8::FunctionCallbackInfo;
|
||||
using v8::FunctionTemplate;
|
||||
using v8::HandleScope;
|
||||
using v8::Int32;
|
||||
using v8::Integer;
|
||||
|
|
@ -55,9 +51,7 @@ using v8::MaybeLocal;
|
|||
using v8::Nothing;
|
||||
using v8::Object;
|
||||
using v8::ObjectTemplate;
|
||||
using v8::PropertyAttribute;
|
||||
using v8::String;
|
||||
using v8::Uint32;
|
||||
using v8::Undefined;
|
||||
using v8::Value;
|
||||
|
||||
|
|
@ -319,7 +313,7 @@ bool SetOption(Environment* env,
|
|||
"The cc_algorithm option is invalid");
|
||||
return false;
|
||||
}
|
||||
algo = static_cast<ngtcp2_cc_algo>(num->Value());
|
||||
algo = FromV8Value<ngtcp2_cc_algo>(num);
|
||||
}
|
||||
options->*member = algo;
|
||||
}
|
||||
|
|
@ -653,7 +647,7 @@ struct Session::Impl final : public MemoryRetainer {
|
|||
|
||||
// JavaScript APIs
|
||||
|
||||
static void Destroy(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(Destroy) {
|
||||
auto env = Environment::GetCurrent(args);
|
||||
Session* session;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||
|
|
@ -663,7 +657,7 @@ struct Session::Impl final : public MemoryRetainer {
|
|||
session->Destroy();
|
||||
}
|
||||
|
||||
static void GetRemoteAddress(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(GetRemoteAddress) {
|
||||
auto env = Environment::GetCurrent(args);
|
||||
Session* session;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||
|
|
@ -678,7 +672,7 @@ struct Session::Impl final : public MemoryRetainer {
|
|||
->object());
|
||||
}
|
||||
|
||||
static void GetCertificate(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(GetCertificate) {
|
||||
auto env = Environment::GetCurrent(args);
|
||||
Session* session;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||
|
|
@ -692,7 +686,7 @@ struct Session::Impl final : public MemoryRetainer {
|
|||
args.GetReturnValue().Set(ret);
|
||||
}
|
||||
|
||||
static void GetEphemeralKeyInfo(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(GetEphemeralKeyInfo) {
|
||||
auto env = Environment::GetCurrent(args);
|
||||
Session* session;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||
|
|
@ -707,7 +701,7 @@ struct Session::Impl final : public MemoryRetainer {
|
|||
args.GetReturnValue().Set(ret);
|
||||
}
|
||||
|
||||
static void GetPeerCertificate(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(GetPeerCertificate) {
|
||||
auto env = Environment::GetCurrent(args);
|
||||
Session* session;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||
|
|
@ -721,7 +715,7 @@ struct Session::Impl final : public MemoryRetainer {
|
|||
args.GetReturnValue().Set(ret);
|
||||
}
|
||||
|
||||
static void GracefulClose(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(GracefulClose) {
|
||||
auto env = Environment::GetCurrent(args);
|
||||
Session* session;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||
|
|
@ -733,7 +727,7 @@ struct Session::Impl final : public MemoryRetainer {
|
|||
session->Close(CloseMethod::GRACEFUL);
|
||||
}
|
||||
|
||||
static void SilentClose(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(SilentClose) {
|
||||
// This is exposed for testing purposes only!
|
||||
auto env = Environment::GetCurrent(args);
|
||||
Session* session;
|
||||
|
|
@ -746,7 +740,7 @@ struct Session::Impl final : public MemoryRetainer {
|
|||
session->Close(CloseMethod::SILENT);
|
||||
}
|
||||
|
||||
static void UpdateKey(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(UpdateKey) {
|
||||
auto env = Environment::GetCurrent(args);
|
||||
Session* session;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||
|
|
@ -763,7 +757,7 @@ struct Session::Impl final : public MemoryRetainer {
|
|||
args.GetReturnValue().Set(session->tls_session().InitiateKeyUpdate());
|
||||
}
|
||||
|
||||
static void OpenStream(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(OpenStream) {
|
||||
auto env = Environment::GetCurrent(args);
|
||||
Session* session;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||
|
|
@ -782,7 +776,7 @@ struct Session::Impl final : public MemoryRetainer {
|
|||
}
|
||||
|
||||
SendPendingDataScope send_scope(session);
|
||||
auto direction = static_cast<Direction>(args[0].As<Uint32>()->Value());
|
||||
auto direction = FromV8Value<Direction>(args[0]);
|
||||
Local<Object> stream;
|
||||
if (session->OpenStream(direction, std::move(data_source)).ToLocal(&stream))
|
||||
[[likely]] {
|
||||
|
|
@ -790,7 +784,7 @@ struct Session::Impl final : public MemoryRetainer {
|
|||
}
|
||||
}
|
||||
|
||||
static void SendDatagram(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(SendDatagram) {
|
||||
auto env = Environment::GetCurrent(args);
|
||||
Session* session;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&session, args.This());
|
||||
|
|
@ -1276,23 +1270,12 @@ Session::SendPendingDataScope::~SendPendingDataScope() {
|
|||
}
|
||||
|
||||
// ============================================================================
|
||||
bool Session::HasInstance(Environment* env, Local<Value> value) {
|
||||
return GetConstructorTemplate(env)->HasInstance(value);
|
||||
}
|
||||
|
||||
BaseObjectPtr<Session> Session::Create(
|
||||
Endpoint* endpoint,
|
||||
const Config& config,
|
||||
TLSContext* tls_context,
|
||||
const std::optional<SessionTicket>& ticket) {
|
||||
Local<Object> obj;
|
||||
if (!GetConstructorTemplate(endpoint->env())
|
||||
->InstanceTemplate()
|
||||
->NewInstance(endpoint->env()->context())
|
||||
.ToLocal(&obj)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
JS_NEW_INSTANCE_OR_RETURN(endpoint->env(), obj, {});
|
||||
return MakeDetachedBaseObject<Session>(
|
||||
endpoint, obj, config, tls_context, ticket);
|
||||
}
|
||||
|
|
@ -1311,27 +1294,23 @@ Session::Session(Endpoint* endpoint,
|
|||
DCHECK(impl_);
|
||||
MakeWeak();
|
||||
Debug(this, "Session created.");
|
||||
|
||||
const auto defineProperty = [&](auto name, auto value) {
|
||||
object
|
||||
->DefineOwnProperty(
|
||||
env()->context(), name, value, PropertyAttribute::ReadOnly)
|
||||
.Check();
|
||||
};
|
||||
|
||||
defineProperty(env()->state_string(), impl_->state_.GetArrayBuffer());
|
||||
defineProperty(env()->stats_string(), impl_->stats_.GetArrayBuffer());
|
||||
|
||||
auto& binding = BindingData::Get(env());
|
||||
|
||||
JS_DEFINE_READONLY_PROPERTY(
|
||||
env(), object, env()->stats_string(), impl_->stats_.GetArrayBuffer());
|
||||
JS_DEFINE_READONLY_PROPERTY(
|
||||
env(), object, env()->state_string(), impl_->state_.GetArrayBuffer());
|
||||
|
||||
if (config.options.qlog) [[unlikely]] {
|
||||
qlog_stream_ = LogStream::Create(env());
|
||||
defineProperty(binding.qlog_string(), qlog_stream_->object());
|
||||
JS_DEFINE_READONLY_PROPERTY(
|
||||
env(), object, binding.qlog_string(), qlog_stream_->object());
|
||||
}
|
||||
|
||||
if (config.options.tls_options.keylog) [[unlikely]] {
|
||||
keylog_stream_ = LogStream::Create(env());
|
||||
defineProperty(binding.keylog_string(), keylog_stream_->object());
|
||||
JS_DEFINE_READONLY_PROPERTY(
|
||||
env(), object, binding.keylog_string(), keylog_stream_->object());
|
||||
}
|
||||
|
||||
UpdateDataStats();
|
||||
|
|
@ -2348,10 +2327,7 @@ void Session::DatagramReceived(const uint8_t* data,
|
|||
Debug(this, "Session is receiving datagram of size %zu", datalen);
|
||||
auto& stats_ = impl_->stats_;
|
||||
STAT_INCREMENT(Stats, datagrams_received);
|
||||
auto backing = ArrayBuffer::NewBackingStore(
|
||||
env()->isolate(),
|
||||
datalen,
|
||||
BackingStoreInitializationMode::kUninitialized);
|
||||
JS_TRY_ALLOCATE_BACKING(env(), backing, datalen)
|
||||
memcpy(backing->Data(), data, datalen);
|
||||
EmitDatagram(Store(std::move(backing), datalen), flag);
|
||||
}
|
||||
|
|
@ -2777,28 +2753,19 @@ void Session::EmitKeylog(const char* line) {
|
|||
|
||||
// ============================================================================
|
||||
|
||||
Local<FunctionTemplate> Session::GetConstructorTemplate(Environment* env) {
|
||||
auto& state = BindingData::Get(env);
|
||||
auto tmpl = state.session_constructor_template();
|
||||
if (tmpl.IsEmpty()) {
|
||||
auto isolate = env->isolate();
|
||||
tmpl = NewFunctionTemplate(isolate, IllegalConstructor);
|
||||
tmpl->SetClassName(state.session_string());
|
||||
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
|
||||
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount);
|
||||
#define V(name, key, no_side_effect) \
|
||||
if (no_side_effect) { \
|
||||
SetProtoMethodNoSideEffect(isolate, tmpl, #key, Impl::name); \
|
||||
SetProtoMethodNoSideEffect(env->isolate(), tmpl, #key, Impl::name); \
|
||||
} else { \
|
||||
SetProtoMethod(isolate, tmpl, #key, Impl::name); \
|
||||
SetProtoMethod(env->isolate(), tmpl, #key, Impl::name); \
|
||||
}
|
||||
SESSION_JS_METHODS(V)
|
||||
|
||||
JS_CONSTRUCTOR_IMPL(Session, session_constructor_template, {
|
||||
JS_ILLEGAL_CONSTRUCTOR();
|
||||
JS_INHERIT(AsyncWrap);
|
||||
JS_CLASS(session);
|
||||
SESSION_JS_METHODS(V)
|
||||
})
|
||||
#undef V
|
||||
state.set_session_constructor_template(tmpl);
|
||||
}
|
||||
return tmpl;
|
||||
}
|
||||
|
||||
void Session::RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
||||
#define V(name, _, __) registry->Register(Impl::name);
|
||||
|
|
@ -2823,9 +2790,9 @@ void Session::InitPerContext(Realm* realm, Local<Object> target) {
|
|||
PreferredAddress::Initialize(realm->env(), target);
|
||||
|
||||
static constexpr auto STREAM_DIRECTION_BIDIRECTIONAL =
|
||||
static_cast<uint32_t>(Direction::BIDIRECTIONAL);
|
||||
static_cast<uint8_t>(Direction::BIDIRECTIONAL);
|
||||
static constexpr auto STREAM_DIRECTION_UNIDIRECTIONAL =
|
||||
static_cast<uint32_t>(Direction::UNIDIRECTIONAL);
|
||||
static_cast<uint8_t>(Direction::UNIDIRECTIONAL);
|
||||
static constexpr auto QUIC_PROTO_MAX = NGTCP2_PROTO_VER_MAX;
|
||||
static constexpr auto QUIC_PROTO_MIN = NGTCP2_PROTO_VER_MIN;
|
||||
|
||||
|
|
|
|||
|
|
@ -250,13 +250,8 @@ class Session final : public AsyncWrap, private SessionTicket::AppData::Source {
|
|||
std::string ToString() const;
|
||||
};
|
||||
|
||||
static bool HasInstance(Environment* env, v8::Local<v8::Value> value);
|
||||
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
|
||||
Environment* env);
|
||||
static void InitPerIsolate(IsolateData* isolate_data,
|
||||
v8::Local<v8::ObjectTemplate> target);
|
||||
static void InitPerContext(Realm* env, v8::Local<v8::Object> target);
|
||||
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
|
||||
JS_CONSTRUCTOR(Session);
|
||||
JS_BINDING_INIT_BOILERPLATE();
|
||||
|
||||
static BaseObjectPtr<Session> Create(
|
||||
Endpoint* endpoint,
|
||||
|
|
@ -334,7 +329,7 @@ class Session final : public AsyncWrap, private SessionTicket::AppData::Source {
|
|||
// A non-const variation to allow certain modifications.
|
||||
Config& config();
|
||||
|
||||
enum class CreateStreamOption {
|
||||
enum class CreateStreamOption : uint8_t {
|
||||
NOTIFY,
|
||||
DO_NOT_NOTIFY,
|
||||
};
|
||||
|
|
@ -423,7 +418,7 @@ class Session final : public AsyncWrap, private SessionTicket::AppData::Source {
|
|||
// defined there to manage it.
|
||||
void set_wrapped();
|
||||
|
||||
enum class CloseMethod {
|
||||
enum class CloseMethod : uint8_t {
|
||||
// Immediate close with a roundtrip through JavaScript, causing all
|
||||
// currently opened streams to be closed. An attempt will be made to
|
||||
// send a CONNECTION_CLOSE frame to the peer. If closing while within
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ class SessionTicket final : public MemoryRetainer {
|
|||
// server-side of the Session::Application that sets it.
|
||||
class SessionTicket::AppData final {
|
||||
public:
|
||||
enum class Status {
|
||||
enum class Status : uint8_t {
|
||||
TICKET_IGNORE = SSL_TICKET_RETURN_IGNORE,
|
||||
TICKET_IGNORE_RENEW = SSL_TICKET_RETURN_IGNORE_RENEW,
|
||||
TICKET_USE = SSL_TICKET_RETURN_USE,
|
||||
|
|
@ -83,7 +83,7 @@ class SessionTicket::AppData final {
|
|||
// Session.
|
||||
class Source {
|
||||
public:
|
||||
enum class Flag { STATUS_NONE, STATUS_RENEW };
|
||||
enum class Flag : uint8_t { STATUS_NONE, STATUS_RENEW };
|
||||
|
||||
// Collect application data into the given AppData instance.
|
||||
virtual void CollectSessionTicketAppData(AppData* app_data) const = 0;
|
||||
|
|
|
|||
|
|
@ -20,10 +20,7 @@ namespace node {
|
|||
using v8::Array;
|
||||
using v8::ArrayBuffer;
|
||||
using v8::ArrayBufferView;
|
||||
using v8::BackingStoreInitializationMode;
|
||||
using v8::BigInt;
|
||||
using v8::FunctionCallbackInfo;
|
||||
using v8::FunctionTemplate;
|
||||
using v8::Global;
|
||||
using v8::Integer;
|
||||
using v8::Just;
|
||||
|
|
@ -32,9 +29,7 @@ using v8::Maybe;
|
|||
using v8::Nothing;
|
||||
using v8::Object;
|
||||
using v8::ObjectTemplate;
|
||||
using v8::PropertyAttribute;
|
||||
using v8::SharedArrayBuffer;
|
||||
using v8::Uint32;
|
||||
using v8::Value;
|
||||
|
||||
namespace quic {
|
||||
|
|
@ -185,7 +180,7 @@ Maybe<std::shared_ptr<DataQueue>> Stream::GetDataQueueFromSource(
|
|||
// Stream object.
|
||||
struct Stream::Impl {
|
||||
// Attaches an outbound data source to the stream.
|
||||
static void AttachSource(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(AttachSource) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
|
||||
std::shared_ptr<DataQueue> dataqueue;
|
||||
|
|
@ -196,7 +191,7 @@ struct Stream::Impl {
|
|||
}
|
||||
}
|
||||
|
||||
static void Destroy(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(Destroy) {
|
||||
Stream* stream;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
||||
if (args.Length() > 1) {
|
||||
|
|
@ -209,17 +204,16 @@ struct Stream::Impl {
|
|||
}
|
||||
}
|
||||
|
||||
static void SendHeaders(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(SendHeaders) {
|
||||
Stream* stream;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
||||
CHECK(args[0]->IsUint32()); // Kind
|
||||
CHECK(args[1]->IsArray()); // Headers
|
||||
CHECK(args[2]->IsUint32()); // Flags
|
||||
|
||||
HeadersKind kind = static_cast<HeadersKind>(args[0].As<Uint32>()->Value());
|
||||
HeadersKind kind = FromV8Value<HeadersKind>(args[0]);
|
||||
Local<Array> headers = args[1].As<Array>();
|
||||
HeadersFlags flags =
|
||||
static_cast<HeadersFlags>(args[2].As<Uint32>()->Value());
|
||||
HeadersFlags flags = FromV8Value<HeadersFlags>(args[2]);
|
||||
|
||||
// If the stream is pending, the headers will be queued until the
|
||||
// stream is opened, at which time the queued header block will be
|
||||
|
|
@ -236,7 +230,7 @@ struct Stream::Impl {
|
|||
// Tells the peer to stop sending data for this stream. This has the effect
|
||||
// of shutting down the readable side of the stream for this peer. Any data
|
||||
// that has already been received is still readable.
|
||||
static void StopSending(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(StopSending) {
|
||||
Stream* stream;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
||||
uint64_t code = 0;
|
||||
|
|
@ -261,7 +255,7 @@ struct Stream::Impl {
|
|||
// more data for this stream. This has the effect of shutting down the
|
||||
// writable side of the stream for this peer. Any data that is held in the
|
||||
// outbound queue will be dropped. The stream may still be readable.
|
||||
static void ResetStream(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(ResetStream) {
|
||||
Stream* stream;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
||||
uint64_t code = 0;
|
||||
|
|
@ -288,16 +282,14 @@ struct Stream::Impl {
|
|||
}
|
||||
}
|
||||
|
||||
static void SetPriority(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(SetPriority) {
|
||||
Stream* stream;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
||||
CHECK(args[0]->IsUint32()); // Priority
|
||||
CHECK(args[1]->IsUint32()); // Priority flag
|
||||
|
||||
StreamPriority priority =
|
||||
static_cast<StreamPriority>(args[0].As<Uint32>()->Value());
|
||||
StreamPriorityFlags flags =
|
||||
static_cast<StreamPriorityFlags>(args[1].As<Uint32>()->Value());
|
||||
StreamPriority priority = FromV8Value<StreamPriority>(args[0]);
|
||||
StreamPriorityFlags flags = FromV8Value<StreamPriorityFlags>(args[1]);
|
||||
|
||||
if (stream->is_pending()) {
|
||||
stream->pending_priority_ = PendingPriority{
|
||||
|
|
@ -310,7 +302,7 @@ struct Stream::Impl {
|
|||
}
|
||||
}
|
||||
|
||||
static void GetPriority(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(GetPriority) {
|
||||
Stream* stream;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
||||
|
||||
|
|
@ -323,7 +315,7 @@ struct Stream::Impl {
|
|||
args.GetReturnValue().Set(static_cast<uint32_t>(priority));
|
||||
}
|
||||
|
||||
static void GetReader(const FunctionCallbackInfo<Value>& args) {
|
||||
JS_METHOD(GetReader) {
|
||||
Stream* stream;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&stream, args.This());
|
||||
BaseObjectPtr<Blob::Reader> reader = stream->get_reader();
|
||||
|
|
@ -697,33 +689,19 @@ class Stream::Outbound final : public MemoryRetainer {
|
|||
|
||||
// ============================================================================
|
||||
|
||||
bool Stream::HasInstance(Environment* env, Local<Value> value) {
|
||||
return GetConstructorTemplate(env)->HasInstance(value);
|
||||
}
|
||||
|
||||
Local<FunctionTemplate> Stream::GetConstructorTemplate(Environment* env) {
|
||||
auto& state = BindingData::Get(env);
|
||||
auto tmpl = state.stream_constructor_template();
|
||||
if (tmpl.IsEmpty()) {
|
||||
auto isolate = env->isolate();
|
||||
tmpl = NewFunctionTemplate(isolate, IllegalConstructor);
|
||||
tmpl->SetClassName(state.stream_string());
|
||||
tmpl->Inherit(AsyncWrap::GetConstructorTemplate(env));
|
||||
tmpl->InstanceTemplate()->SetInternalFieldCount(kInternalFieldCount);
|
||||
#define V(name, key, no_side_effect) \
|
||||
if (no_side_effect) { \
|
||||
SetProtoMethodNoSideEffect(isolate, tmpl, #key, Impl::name); \
|
||||
SetProtoMethodNoSideEffect(env->isolate(), tmpl, #key, Impl::name); \
|
||||
} else { \
|
||||
SetProtoMethod(isolate, tmpl, #key, Impl::name); \
|
||||
SetProtoMethod(env->isolate(), tmpl, #key, Impl::name); \
|
||||
}
|
||||
|
||||
STREAM_JS_METHODS(V)
|
||||
|
||||
JS_CONSTRUCTOR_IMPL(Stream, stream_constructor_template, {
|
||||
JS_ILLEGAL_CONSTRUCTOR();
|
||||
JS_INHERIT(AsyncWrap);
|
||||
JS_CLASS(stream);
|
||||
STREAM_JS_METHODS(V)
|
||||
})
|
||||
#undef V
|
||||
state.set_stream_constructor_template(tmpl);
|
||||
}
|
||||
return tmpl;
|
||||
}
|
||||
|
||||
void Stream::RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
||||
#define V(name, _, __) registry->Register(Impl::name);
|
||||
|
|
@ -755,16 +733,16 @@ void Stream::InitPerContext(Realm* realm, Local<Object> target) {
|
|||
#undef V
|
||||
|
||||
constexpr int QUIC_STREAM_HEADERS_KIND_HINTS =
|
||||
static_cast<int>(HeadersKind::HINTS);
|
||||
static_cast<uint8_t>(HeadersKind::HINTS);
|
||||
constexpr int QUIC_STREAM_HEADERS_KIND_INITIAL =
|
||||
static_cast<int>(HeadersKind::INITIAL);
|
||||
static_cast<uint8_t>(HeadersKind::INITIAL);
|
||||
constexpr int QUIC_STREAM_HEADERS_KIND_TRAILING =
|
||||
static_cast<int>(HeadersKind::TRAILING);
|
||||
static_cast<uint8_t>(HeadersKind::TRAILING);
|
||||
|
||||
constexpr int QUIC_STREAM_HEADERS_FLAGS_NONE =
|
||||
static_cast<int>(HeadersFlags::NONE);
|
||||
static_cast<uint8_t>(HeadersFlags::NONE);
|
||||
constexpr int QUIC_STREAM_HEADERS_FLAGS_TERMINAL =
|
||||
static_cast<int>(HeadersFlags::TERMINAL);
|
||||
static_cast<uint8_t>(HeadersFlags::TERMINAL);
|
||||
|
||||
NODE_DEFINE_CONSTANT(target, QUIC_STREAM_HEADERS_KIND_HINTS);
|
||||
NODE_DEFINE_CONSTANT(target, QUIC_STREAM_HEADERS_KIND_INITIAL);
|
||||
|
|
@ -784,14 +762,7 @@ BaseObjectPtr<Stream> Stream::Create(Session* session,
|
|||
std::shared_ptr<DataQueue> source) {
|
||||
DCHECK_GE(id, 0);
|
||||
DCHECK_NOT_NULL(session);
|
||||
Local<Object> obj;
|
||||
if (!GetConstructorTemplate(session->env())
|
||||
->InstanceTemplate()
|
||||
->NewInstance(session->env()->context())
|
||||
.ToLocal(&obj)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
JS_NEW_INSTANCE_OR_RETURN(session->env(), obj, {});
|
||||
return MakeDetachedBaseObject<Stream>(
|
||||
BaseObjectWeakPtr<Session>(session), obj, id, std::move(source));
|
||||
}
|
||||
|
|
@ -800,14 +771,7 @@ BaseObjectPtr<Stream> Stream::Create(Session* session,
|
|||
Direction direction,
|
||||
std::shared_ptr<DataQueue> source) {
|
||||
DCHECK_NOT_NULL(session);
|
||||
Local<Object> obj;
|
||||
if (!GetConstructorTemplate(session->env())
|
||||
->InstanceTemplate()
|
||||
->NewInstance(session->env()->context())
|
||||
.ToLocal(&obj)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
JS_NEW_INSTANCE_OR_RETURN(session->env(), obj, {});
|
||||
return MakeBaseObject<Stream>(
|
||||
BaseObjectWeakPtr<Session>(session), obj, direction, std::move(source));
|
||||
}
|
||||
|
|
@ -829,15 +793,10 @@ Stream::Stream(BaseObjectWeakPtr<Session> session,
|
|||
// inbound queue so that we can update the stream flow control.
|
||||
inbound_->addBackpressureListener(this);
|
||||
|
||||
const auto defineProperty = [&](auto name, auto value) {
|
||||
object
|
||||
->DefineOwnProperty(
|
||||
env()->context(), name, value, PropertyAttribute::ReadOnly)
|
||||
.Check();
|
||||
};
|
||||
|
||||
defineProperty(env()->state_string(), state_.GetArrayBuffer());
|
||||
defineProperty(env()->stats_string(), stats_.GetArrayBuffer());
|
||||
JS_DEFINE_READONLY_PROPERTY(
|
||||
env(), object, env()->state_string(), state_.GetArrayBuffer());
|
||||
JS_DEFINE_READONLY_PROPERTY(
|
||||
env(), object, env()->stats_string(), stats_.GetArrayBuffer());
|
||||
|
||||
set_outbound(std::move(source));
|
||||
|
||||
|
|
@ -866,15 +825,10 @@ Stream::Stream(BaseObjectWeakPtr<Session> session,
|
|||
// inbound queue so that we can update the stream flow control.
|
||||
inbound_->addBackpressureListener(this);
|
||||
|
||||
const auto defineProperty = [&](auto name, auto value) {
|
||||
object
|
||||
->DefineOwnProperty(
|
||||
env()->context(), name, value, PropertyAttribute::ReadOnly)
|
||||
.Check();
|
||||
};
|
||||
|
||||
defineProperty(env()->state_string(), state_.GetArrayBuffer());
|
||||
defineProperty(env()->stats_string(), stats_.GetArrayBuffer());
|
||||
JS_DEFINE_READONLY_PROPERTY(
|
||||
env(), object, env()->state_string(), state_.GetArrayBuffer());
|
||||
JS_DEFINE_READONLY_PROPERTY(
|
||||
env(), object, env()->stats_string(), stats_.GetArrayBuffer());
|
||||
|
||||
set_outbound(std::move(source));
|
||||
|
||||
|
|
@ -1203,8 +1157,7 @@ void Stream::ReceiveData(const uint8_t* data,
|
|||
|
||||
STAT_INCREMENT_N(Stats, bytes_received, len);
|
||||
STAT_RECORD_TIMESTAMP(Stats, received_at);
|
||||
auto backing = ArrayBuffer::NewBackingStore(
|
||||
env()->isolate(), len, BackingStoreInitializationMode::kUninitialized);
|
||||
JS_TRY_ALLOCATE_BACKING(env(), backing, len)
|
||||
memcpy(backing->Data(), data, len);
|
||||
inbound_->append(DataQueue::CreateInMemoryEntryFromBackingStore(
|
||||
std::move(backing), 0, len));
|
||||
|
|
|
|||
|
|
@ -147,13 +147,8 @@ class Stream final : public AsyncWrap,
|
|||
|
||||
static Stream* From(void* stream_user_data);
|
||||
|
||||
static bool HasInstance(Environment* env, v8::Local<v8::Value> value);
|
||||
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
|
||||
Environment* env);
|
||||
static void InitPerIsolate(IsolateData* data,
|
||||
v8::Local<v8::ObjectTemplate> target);
|
||||
static void InitPerContext(Realm* realm, v8::Local<v8::Object> target);
|
||||
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
|
||||
JS_CONSTRUCTOR(Stream);
|
||||
JS_BINDING_INIT_BOILERPLATE();
|
||||
|
||||
// Creates a new non-pending stream.
|
||||
static BaseObjectPtr<Stream> Create(
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@ using ncrypto::SSLPointer;
|
|||
using ncrypto::SSLSessionPointer;
|
||||
using ncrypto::X509Pointer;
|
||||
using v8::ArrayBuffer;
|
||||
using v8::BackingStoreInitializationMode;
|
||||
using v8::BackingStoreOnFailureMode;
|
||||
using v8::Just;
|
||||
using v8::Local;
|
||||
using v8::Maybe;
|
||||
|
|
@ -361,12 +359,7 @@ int TLSContext::OnNewSession(SSL* ssl, SSL_SESSION* sess) {
|
|||
// enough memory to allocate the backing store, then we ignore it
|
||||
// and continue without emitting the sessionticket event.
|
||||
if (size > 0 && size <= crypto::SecureContext::kMaxSessionSize) {
|
||||
auto ticket = ArrayBuffer::NewBackingStore(
|
||||
session.env()->isolate(),
|
||||
size,
|
||||
BackingStoreInitializationMode::kUninitialized,
|
||||
BackingStoreOnFailureMode::kReturnNull);
|
||||
if (!ticket) return 0;
|
||||
JS_TRY_ALLOCATE_BACKING_OR_RETURN(session.env(), ticket, size, 0);
|
||||
auto data = reinterpret_cast<unsigned char*>(ticket->Data());
|
||||
if (i2d_SSL_SESSION(sess, &data) > 0) {
|
||||
session.EmitSessionTicket(Store(std::move(ticket), size));
|
||||
|
|
|
|||
|
|
@ -15,9 +15,6 @@
|
|||
|
||||
namespace node {
|
||||
|
||||
using v8::ArrayBuffer;
|
||||
using v8::BackingStoreInitializationMode;
|
||||
using v8::BackingStoreOnFailureMode;
|
||||
using v8::Just;
|
||||
using v8::Local;
|
||||
using v8::Maybe;
|
||||
|
|
@ -195,14 +192,7 @@ Store TransportParams::Encode(Environment* env, int version) const {
|
|||
return {};
|
||||
}
|
||||
|
||||
auto result = ArrayBuffer::NewBackingStore(
|
||||
env->isolate(),
|
||||
size,
|
||||
BackingStoreInitializationMode::kUninitialized,
|
||||
BackingStoreOnFailureMode::kReturnNull);
|
||||
if (!result) {
|
||||
return {};
|
||||
}
|
||||
JS_TRY_ALLOCATE_BACKING_OR_RETURN(env, result, size, {});
|
||||
|
||||
auto ret = ngtcp2_transport_params_encode_versioned(
|
||||
static_cast<uint8_t*>(result->Data()), size, version, ¶ms_);
|
||||
|
|
|
|||
|
|
@ -142,7 +142,4 @@ for (const [, envVar, config] of nodeOptionsCC.matchAll(addOptionRE)) {
|
|||
// add alias handling
|
||||
manPagesOptions.delete('-trace-events-enabled');
|
||||
|
||||
// TODO(@jasnell): Need to determine why the documentation for this option is not being recognized
|
||||
manPagesOptions.delete('-no-experimental-quic');
|
||||
|
||||
assert.strictEqual(manPagesOptions.size, 0, `Man page options not documented: ${[...manPagesOptions]}`);
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ if (!common.hasIntl) {
|
|||
common.skip('missing Intl');
|
||||
}
|
||||
|
||||
if (process.config.variables.node_quic) {
|
||||
common.skip('this test assumes default configuration options');
|
||||
if (!common.hasQuic) {
|
||||
common.skip('this test requires QUIC');
|
||||
}
|
||||
|
||||
const {
|
||||
|
|
|
|||
|
|
@ -130,8 +130,6 @@ assert(undocumented.delete('--verify-base-objects'));
|
|||
assert(undocumented.delete('--no-verify-base-objects'));
|
||||
assert(undocumented.delete('--trace-promises'));
|
||||
assert(undocumented.delete('--no-trace-promises'));
|
||||
assert(undocumented.delete('--experimental-quic'));
|
||||
assert(undocumented.delete('--no-experimental-quic'));
|
||||
|
||||
// Remove negated versions of the flags.
|
||||
for (const flag of undocumented) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ const expectedKeys = new Map([
|
|||
['uv', ['boolean']],
|
||||
['ipv6', ['boolean']],
|
||||
['openssl_is_boringssl', ['boolean']],
|
||||
['quic', ['boolean']],
|
||||
['quic', ['boolean', 'undefined']],
|
||||
['tls_alpn', ['boolean']],
|
||||
['tls_sni', ['boolean']],
|
||||
['tls_ocsp', ['boolean']],
|
||||
|
|
|
|||
|
|
@ -46,11 +46,6 @@ if (common.hasCrypto) {
|
|||
expected_keys.push('ncrypto');
|
||||
}
|
||||
|
||||
if (common.hasQuic) {
|
||||
expected_keys.push('ngtcp2');
|
||||
expected_keys.push('nghttp3');
|
||||
}
|
||||
|
||||
if (common.hasIntl) {
|
||||
expected_keys.push('icu');
|
||||
expected_keys.push('cldr');
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user