diff --git a/src/quic/session.cc b/src/quic/session.cc index fd057790cde6f3..5f9f3a70241f19 100644 --- a/src/quic/session.cc +++ b/src/quic/session.cc @@ -2856,6 +2856,146 @@ Session::OptionsObject::OptionsObject(Environment* env, MakeWeak(); } +template +Maybe Session::OptionsObject::SetOption(Opt* options, + const Local& object, + const Local& name, + uint64_t Opt::*member) { + Local value; + if (!object->Get(env()->context(), name).ToLocal(&value)) + return Nothing(); + + if (value->IsUndefined()) return Just(false); + + CHECK_IMPLIES(!value->IsBigInt(), value->IsNumber()); + + uint64_t val = 0; + if (value->IsBigInt()) { + bool lossless = true; + val = value.As()->Uint64Value(&lossless); + if (!lossless) { + Utf8Value label(env()->isolate(), name); + THROW_ERR_OUT_OF_RANGE( + env(), + (std::string("options.") + (*label) + " is out of range").c_str()); + return Nothing(); + } + } else { + val = static_cast(value.As()->Value()); + } + options->*member = val; + return Just(true); +} + +template +Maybe Session::OptionsObject::SetOption(Opt* options, + const Local& object, + const Local& name, + uint32_t Opt::*member) { + Local value; + if (!object->Get(env()->context(), name).ToLocal(&value)) + return Nothing(); + + if (value->IsUndefined()) return Just(false); + + CHECK(value->IsUint32()); + uint32_t val = value.As()->Value(); + options->*member = val; + return Just(true); +} + +template +Maybe Session::OptionsObject::SetOption(Opt* options, + const Local& object, + const Local& name, + bool Opt::*member) { + Local value; + if (!object->Get(env()->context(), name).ToLocal(&value)) + return Nothing(); + if (value->IsUndefined()) return Just(false); + CHECK(value->IsBoolean()); + options->*member = value->IsTrue(); + return Just(true); +} + +template +Maybe Session::OptionsObject::SetOption(Opt* options, + const Local& object, + const Local& name, + std::string Opt::*member) { + Local value; + if (!object->Get(env()->context(), name).ToLocal(&value)) + return Nothing(); + if (value->IsUndefined()) return Just(false); + Utf8Value val(env()->isolate(), value); + options->*member = val.ToString(); + return Just(true); +} + +template +Maybe Session::OptionsObject::SetOption( + Opt* options, + const Local& object, + const Local& name, + std::vector> Opt::*member) { + Local value; + if (!object->Get(env()->context(), name).ToLocal(&value)) + return Nothing(); + if (value->IsArray()) { + auto context = env()->context(); + auto values = value.As(); + uint32_t count = values->Length(); + for (uint32_t n = 0; n < count; n++) { + Local item; + if (!values->Get(context, n).ToLocal(&item)) { + return Nothing(); + } + if (crypto::KeyObjectHandle::HasInstance(env(), item)) { + crypto::KeyObjectHandle* handle; + ASSIGN_OR_RETURN_UNWRAP(&handle, item, Nothing()); + (options->*member).push_back(handle->Data()); + } + } + } else if (crypto::KeyObjectHandle::HasInstance(env(), value)) { + crypto::KeyObjectHandle* handle; + ASSIGN_OR_RETURN_UNWRAP(&handle, value, Nothing()); + (options->*member).push_back(handle->Data()); + } else { + UNREACHABLE(); + } + return Just(true); +} + +template +Maybe Session::OptionsObject::SetOption(Opt* options, + const Local& object, + const Local& name, + std::vector Opt::*member) { + Local value; + if (!object->Get(env()->context(), name).ToLocal(&value)) + return Nothing(); + if (value->IsArray()) { + auto context = env()->context(); + auto values = value.As(); + uint32_t count = values->Length(); + for (uint32_t n = 0; n < count; n++) { + Local item; + if (!values->Get(context, n).ToLocal(&item)) { + return Nothing(); + } + if (item->IsArrayBufferView()) { + Store store(item.As()); + (options->*member).push_back(std::move(store)); + } + } + } else if (value->IsArrayBufferView()) { + Store store(value.As()); + (options->*member).push_back(std::move(store)); + } + + return Just(true); +} + void Session::OptionsObject::New(const FunctionCallbackInfo& args) { CHECK(args.IsConstructCall()); auto env = Environment::GetCurrent(args); @@ -3169,146 +3309,6 @@ void Session::OptionsObject::New(const FunctionCallbackInfo& args) { } } -template -Maybe Session::OptionsObject::SetOption(Opt* options, - const Local& object, - const Local& name, - uint64_t Opt::*member) { - Local value; - if (!object->Get(env()->context(), name).ToLocal(&value)) - return Nothing(); - - if (value->IsUndefined()) return Just(false); - - CHECK_IMPLIES(!value->IsBigInt(), value->IsNumber()); - - uint64_t val = 0; - if (value->IsBigInt()) { - bool lossless = true; - val = value.As()->Uint64Value(&lossless); - if (!lossless) { - Utf8Value label(env()->isolate(), name); - THROW_ERR_OUT_OF_RANGE( - env(), - (std::string("options.") + (*label) + " is out of range").c_str()); - return Nothing(); - } - } else { - val = static_cast(value.As()->Value()); - } - options->*member = val; - return Just(true); -} - -template -Maybe Session::OptionsObject::SetOption(Opt* options, - const Local& object, - const Local& name, - uint32_t Opt::*member) { - Local value; - if (!object->Get(env()->context(), name).ToLocal(&value)) - return Nothing(); - - if (value->IsUndefined()) return Just(false); - - CHECK(value->IsUint32()); - uint32_t val = value.As()->Value(); - options->*member = val; - return Just(true); -} - -template -Maybe Session::OptionsObject::SetOption(Opt* options, - const Local& object, - const Local& name, - bool Opt::*member) { - Local value; - if (!object->Get(env()->context(), name).ToLocal(&value)) - return Nothing(); - if (value->IsUndefined()) return Just(false); - CHECK(value->IsBoolean()); - options->*member = value->IsTrue(); - return Just(true); -} - -template -Maybe Session::OptionsObject::SetOption(Opt* options, - const Local& object, - const Local& name, - std::string Opt::*member) { - Local value; - if (!object->Get(env()->context(), name).ToLocal(&value)) - return Nothing(); - if (value->IsUndefined()) return Just(false); - Utf8Value val(env()->isolate(), value); - options->*member = val.ToString(); - return Just(true); -} - -template -Maybe Session::OptionsObject::SetOption( - Opt* options, - const Local& object, - const Local& name, - std::vector> Opt::*member) { - Local value; - if (!object->Get(env()->context(), name).ToLocal(&value)) - return Nothing(); - if (value->IsArray()) { - auto context = env()->context(); - auto values = value.As(); - uint32_t count = values->Length(); - for (uint32_t n = 0; n < count; n++) { - Local item; - if (!values->Get(context, n).ToLocal(&item)) { - return Nothing(); - } - if (crypto::KeyObjectHandle::HasInstance(env(), item)) { - crypto::KeyObjectHandle* handle; - ASSIGN_OR_RETURN_UNWRAP(&handle, item, Nothing()); - (options->*member).push_back(handle->Data()); - } - } - } else if (crypto::KeyObjectHandle::HasInstance(env(), value)) { - crypto::KeyObjectHandle* handle; - ASSIGN_OR_RETURN_UNWRAP(&handle, value, Nothing()); - (options->*member).push_back(handle->Data()); - } else { - UNREACHABLE(); - } - return Just(true); -} - -template -Maybe Session::OptionsObject::SetOption(Opt* options, - const Local& object, - const Local& name, - std::vector Opt::*member) { - Local value; - if (!object->Get(env()->context(), name).ToLocal(&value)) - return Nothing(); - if (value->IsArray()) { - auto context = env()->context(); - auto values = value.As(); - uint32_t count = values->Length(); - for (uint32_t n = 0; n < count; n++) { - Local item; - if (!values->Get(context, n).ToLocal(&item)) { - return Nothing(); - } - if (item->IsArrayBufferView()) { - Store store(item.As()); - (options->*member).push_back(std::move(store)); - } - } - } else if (value->IsArrayBufferView()) { - Store store(value.As()); - (options->*member).push_back(std::move(store)); - } - - return Just(true); -} - void Session::OptionsObject::MemoryInfo(MemoryTracker* tracker) const { tracker->TrackField("options", options_); }