| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -724,6 +724,18 @@ added: v23.8.0 | |||
| 724 | 724 | ||
| 725 | 725 | A `QuicSession` represents the local side of a QUIC connection. | |
| 726 | 726 | ||
| 727 | + ### `session.applicationOptions` | ||
| 728 | + | ||
| 729 | + <!-- YAML | ||
| 730 | + added: REPLACEME | ||
| 731 | + --> | ||
| 732 | + | ||
| 733 | + * Type: {quic.ApplicationOptions} | ||
| 734 | + | ||
| 735 | + The current application-level options for this session. These include settings | ||
| 736 | + that are specific to the negotiated application protocol (e.g. HTTP/3) and may | ||
| 737 | + be negotiated separately from the transport parameters. Read only. | ||
| 738 | + | ||
| 727 | 739 | ### `session.close([options])` | |
| 728 | 740 | ||
| 729 | 741 | <!-- YAML | |
@@ -2218,6 +2230,70 @@ added: v23.8.0 | |||
| 2218 | 2230 | ||
| 2219 | 2231 | ## Types | |
| 2220 | 2232 | ||
| 2233 | + ### type: `ApplicationOptions` | ||
| 2234 | + | ||
| 2235 | + <!-- YAML | ||
| 2236 | + added: REPLACEME | ||
| 2237 | + --> | ||
| 2238 | + | ||
| 2239 | + * Type: {Object} | ||
| 2240 | + | ||
| 2241 | + The application specific options. | ||
| 2242 | + | ||
| 2243 | + #### `applicationOptions.maxHeaderPairs` | ||
| 2244 | + | ||
| 2245 | + * Type: {bigint|number} | ||
| 2246 | + | ||
| 2247 | + Maximum number of header name-value pairs accepted per header block. | ||
| 2248 | + Headers beyond this limit are silently dropped. **Default:** `128` | ||
| 2249 | + | ||
| 2250 | + #### `applicationOptions.maxHeaderLength` | ||
| 2251 | + | ||
| 2252 | + * Type: {bigint|number} | ||
| 2253 | + | ||
| 2254 | + Maximum total byte length of all header names and values combined per header | ||
| 2255 | + block. Headers that would push the total over this limit are silently | ||
| 2256 | + dropped. **Default:** `8192` | ||
| 2257 | + | ||
| 2258 | + #### `applicationOptions.maxFieldSectionSize` | ||
| 2259 | + | ||
| 2260 | + * Type: {bigint|number} | ||
| 2261 | + | ||
| 2262 | + Maximum size of a compressed header field section (QPACK). `0` means | ||
| 2263 | + unlimited. **Default:** `0` | ||
| 2264 | + | ||
| 2265 | + #### `applicationOptions.qpackMaxDTableCapacity` | ||
| 2266 | + | ||
| 2267 | + * Type: {bigint|number} | ||
| 2268 | + | ||
| 2269 | + QPACK dynamic table capacity in bytes. Set to `0` to disable the dynamic | ||
| 2270 | + table. **Default:** `4096` | ||
| 2271 | + | ||
| 2272 | + #### `applicationOptions.qpackEncoderMaxDTableCapacity` | ||
| 2273 | + | ||
| 2274 | + * Type: {bigint|number} | ||
| 2275 | + | ||
| 2276 | + QPACK encoder maximum dynamic table capacity. **Default:** `4096` | ||
| 2277 | + | ||
| 2278 | + #### `applicationOptions.qpackBlockedStreams` | ||
| 2279 | + | ||
| 2280 | + * Type: {bigint|number} | ||
| 2281 | + | ||
| 2282 | + Maximum number of streams that can e blocked waiting for QPACK dynamic table | ||
| 2283 | + updates. **Default:** `100` | ||
| 2284 | + | ||
| 2285 | + #### `applicationOptions.enableConnectProtocol` | ||
| 2286 | + | ||
| 2287 | + * Type: {boolean} | ||
| 2288 | + | ||
| 2289 | + Enable the extended CONNECT protocol (RFC 9220). **Default:** `false` | ||
| 2290 | + | ||
| 2291 | + #### `applicationOptions.enableDatagrams` | ||
| 2292 | + | ||
| 2293 | + * Type: {boolean} | ||
| 2294 | + | ||
| 2295 | + Enable HTTP/3 datagrams (RFC 9297). **Default:** `false` | ||
| 2296 | + | ||
| 2221 | 2297 | ### Type: `EndpointOptions` | |
| 2222 | 2298 | ||
| 2223 | 2299 | <!-- YAML | |
@@ -2474,30 +2550,9 @@ Default: `'h3'` | |||
| 2474 | 2550 | added: REPLACEME | |
| 2475 | 2551 | --> | |
| 2476 | 2552 | ||
| 2477 | - * Type: {Object} | ||
| 2553 | + * Type: {quic.ApplicationOptions} | ||
| 2478 | 2554 | ||
| 2479 | - HTTP/3 application-specific options. These only apply when the negotiated | ||
| 2480 | - ALPN selects the HTTP/3 application (`'h3'`). | ||
| 2481 | - | ||
| 2482 | - * `maxHeaderPairs` {number} Maximum number of header name-value pairs | ||
| 2483 | - accepted per header block. Headers beyond this limit are silently | ||
| 2484 | - dropped. **Default:** `128` | ||
| 2485 | - * `maxHeaderLength` {number} Maximum total byte length of all header | ||
| 2486 | - names and values combined per header block. Headers that would push | ||
| 2487 | - the total over this limit are silently dropped. **Default:** `8192` | ||
| 2488 | - * `maxFieldSectionSize` {number} Maximum size of a compressed header | ||
| 2489 | - field section (QPACK). `0` means unlimited. **Default:** `0` | ||
| 2490 | - * `qpackMaxDTableCapacity` {number} QPACK dynamic table capacity in | ||
| 2491 | - bytes. Set to `0` to disable the dynamic table. **Default:** `4096` | ||
| 2492 | - * `qpackEncoderMaxDTableCapacity` {number} QPACK encoder maximum | ||
| 2493 | - dynamic table capacity. **Default:** `4096` | ||
| 2494 | - * `qpackBlockedStreams` {number} Maximum number of streams that can | ||
| 2495 | - be blocked waiting for QPACK dynamic table updates. | ||
| 2496 | - **Default:** `100` | ||
| 2497 | - * `enableConnectProtocol` {boolean} Enable the extended CONNECT | ||
| 2498 | - protocol (RFC 9220). **Default:** `false` | ||
| 2499 | - * `enableDatagrams` {boolean} Enable HTTP/3 datagrams (RFC 9297). | ||
| 2500 | - **Default:** `false` | ||
| 2555 | + Application-specific options. | ||
| 2501 | 2556 | ||
| 2502 | 2557 | ```mjs | |
| 2503 | 2558 | const { listen } = await import('node:quic'); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2678,6 +2678,14 @@ class QuicSession { | |||
| 2678 | 2678 | debug('session created'); | |
| 2679 | 2679 | } | |
| 2680 | 2680 | ||
| 2681 | + get applicationOptions() { | ||
| 2682 | + // We don't cache application options because they may be updated by the | ||
| 2683 | + // C++ layer after session creation depending on the behavior of the | ||
| 2684 | + // application. | ||
| 2685 | + if (this.destroyed) return null; | ||
| 2686 | + return this.#handle.applicationOptions(); | ||
| 2687 | + } | ||
| 2688 | + | ||
| 2681 | 2689 | get localTransportParams() { | |
| 2682 | 2690 | if (this.#inner.localTransportParams !== undefined) { | |
| 2683 | 2691 | return this.#inner.localTransportParams; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,9 +19,13 @@ | |||
| 19 | 19 | ||
| 20 | 20 | namespace node { | |
| 21 | 21 | ||
| 22 | + using v8::BigInt; | ||
| 23 | + using v8::Boolean; | ||
| 24 | + using v8::DictionaryTemplate; | ||
| 22 | 25 | using v8::Just; | |
| 23 | 26 | using v8::Local; | |
| 24 | 27 | using v8::Maybe; | |
| 28 | + using v8::MaybeLocal; | ||
| 25 | 29 | using v8::Nothing; | |
| 26 | 30 | using v8::Object; | |
| 27 | 31 | using v8::Value; | |
@@ -114,6 +118,44 @@ Maybe<Session::Application_Options> Session::Application_Options::From( | |||
| 114 | 118 | return Just<Application_Options>(options); | |
| 115 | 119 | } | |
| 116 | 120 | ||
| 121 | + MaybeLocal<Object> Session::Application_Options::ToObject( | ||
| 122 | + Environment* env) const { | ||
| 123 | + auto& binding_data = BindingData::Get(env); | ||
| 124 | + auto tmpl = binding_data.application_options_template(); | ||
| 125 | + static constexpr std::string_view names[] = { | ||
| 126 | + "maxHeaderPairs", | ||
| 127 | + "maxHeaderLength", | ||
| 128 | + "maxFieldSectionSize", | ||
| 129 | + "qpackMaxDtableCapacity", | ||
| 130 | + "qpackEncoderMaxDtableCapacity", | ||
| 131 | + "qpackBlockedStreams", | ||
| 132 | + "enableConnectProtocol", | ||
| 133 | + "enableDatagrams", | ||
| 134 | + }; | ||
| 135 | + if (tmpl.IsEmpty()) { | ||
| 136 | + tmpl = DictionaryTemplate::New(env->isolate(), names); | ||
| 137 | + binding_data.set_application_options_template(tmpl); | ||
| 138 | + } | ||
| 139 | + MaybeLocal<Value> values[] = { | ||
| 140 | + BigInt::NewFromUnsigned(env->isolate(), max_header_pairs), | ||
| 141 | + BigInt::NewFromUnsigned(env->isolate(), max_header_length), | ||
| 142 | + BigInt::NewFromUnsigned(env->isolate(), max_field_section_size), | ||
| 143 | + BigInt::NewFromUnsigned(env->isolate(), qpack_max_dtable_capacity), | ||
| 144 | + BigInt::NewFromUnsigned(env->isolate(), | ||
| 145 | + qpack_encoder_max_dtable_capacity), | ||
| 146 | + BigInt::NewFromUnsigned(env->isolate(), qpack_blocked_streams), | ||
| 147 | + Boolean::New(env->isolate(), enable_connect_protocol), | ||
| 148 | + Boolean::New(env->isolate(), enable_datagrams), | ||
| 149 | + }; | ||
| 150 | + static_assert(std::size(values) == std::size(names)); | ||
| 151 | + | ||
| 152 | + auto obj = tmpl->NewInstance(env->context(), values); | ||
| 153 | + if (obj->SetPrototypeV2(env->context(), Null(env->isolate())).IsNothing()) { | ||
| 154 | + return {}; | ||
| 155 | + } | ||
| 156 | + return obj; | ||
| 157 | + } | ||
| 158 | + | ||
| 117 | 159 | // ============================================================================ | |
| 118 | 160 | ||
| 119 | 161 | std::string Session::Application::StreamData::ToString() const { | |
@@ -655,7 +697,10 @@ class DefaultApplication final : public Session::Application { | |||
| 655 | 697 | // Marked NOLINT because the cpp linter gets confused about this using | |
| 656 | 698 | // statement not being sorted with the using v8 statements at the top | |
| 657 | 699 | // of the namespace. | |
| 658 | - using Application::Application; // NOLINT | ||
| 700 | + DefaultApplication(Session* session, const Options& options) | ||
| 701 | + : Session::Application(session, options), options_(options) {} | ||
| 702 | + | ||
| 703 | + const Options& options() const override { return options_; } | ||
| 659 | 704 | ||
| 660 | 705 | Session::Application::Type type() const override { | |
| 661 | 706 | return Session::Application::Type::DEFAULT; | |
@@ -827,6 +872,8 @@ class DefaultApplication final : public Session::Application { | |||
| 827 | 872 | } | |
| 828 | 873 | } | |
| 829 | 874 | ||
| 875 | + Options options_; | ||
| 876 | + | ||
| 830 | 877 | Stream::Queue stream_queue_; | |
| 831 | 878 | }; | |
| 832 | 879 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -38,6 +38,10 @@ class Session::Application : public MemoryRetainer { | |||
| 38 | 38 | Application(Session* session, const Options& options); | |
| 39 | 39 | DISALLOW_COPY_AND_MOVE(Application) | |
| 40 | 40 | ||
| 41 | + // Get the active options for this application. These may differ from the | ||
| 42 | + // options passed at construction time since some options can be negotiated. | ||
| 43 | + virtual const Options& options() const = 0; | ||
| 44 | + | ||
| 41 | 45 | // The type of Application, exposed via the session state so JS | |
| 42 | 46 | // can observe which Application was selected after ALPN negotiation. | |
| 43 | 47 | // This is used primarily for testing/debugging. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -385,7 +385,17 @@ void BindingData::set_transport_params_template( | |||
| 385 | 385 | ||
| 386 | 386 | Local<DictionaryTemplate> BindingData::transport_params_template() const { | |
| 387 | 387 | return PersistentToLocal::Default(env()->isolate(), | |
| 388 | - transport_params_template_); | ||
| 388 | + transport_params_template_); | ||
| 389 | + } | ||
| 390 | + | ||
| 391 | + void BindingData::set_application_options_template( | ||
| 392 | + Local<DictionaryTemplate> tmpl) { | ||
| 393 | + application_options_template_.Reset(env()->isolate(), tmpl); | ||
| 394 | + } | ||
| 395 | + | ||
| 396 | + Local<DictionaryTemplate> BindingData::application_options_template() const { | ||
| 397 | + return PersistentToLocal::Default(env()->isolate(), | ||
| 398 | + application_options_template_); | ||
| 389 | 399 | } | |
| 390 | 400 | ||
| 391 | 401 | #define V(name, _) \ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -306,6 +306,9 @@ class BindingData final | |||
| 306 | 306 | void set_transport_params_template(v8::Local<v8::DictionaryTemplate> tmpl); | |
| 307 | 307 | v8::Local<v8::DictionaryTemplate> transport_params_template() const; | |
| 308 | 308 | ||
| 309 | + void set_application_options_template(v8::Local<v8::DictionaryTemplate> tmpl); | ||
| 310 | + v8::Local<v8::DictionaryTemplate> application_options_template() const; | ||
| 311 | + | ||
| 309 | 312 | #define V(name, _) \ | |
| 310 | 313 | void set_##name##_callback(v8::Local<v8::Function> fn); \ | |
| 311 | 314 | v8::Local<v8::Function> name##_callback() const; | |
@@ -325,6 +328,7 @@ class BindingData final | |||
| 325 | 328 | #undef V | |
| 326 | 329 | ||
| 327 | 330 | v8::Global<v8::DictionaryTemplate> transport_params_template_; | |
| 331 | + v8::Global<v8::DictionaryTemplate> application_options_template_; | ||
| 328 | 332 | ||
| 329 | 333 | #define V(name, _) v8::Global<v8::Function> name##_callback_; | |
| 330 | 334 | QUIC_JS_CALLBACKS(V) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -157,6 +157,8 @@ class Http3ApplicationImpl final : public Session::Application { | |||
| 157 | 157 | session->set_priority_supported(); | |
| 158 | 158 | } | |
| 159 | 159 | ||
| 160 | + const Options& options() const override { return options_; } | ||
| 161 | + | ||
| 160 | 162 | Session::Application::Type type() const override { | |
| 161 | 163 | return Session::Application::Type::HTTP3; | |
| 162 | 164 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -193,6 +193,7 @@ uint64_t MaxDatagramPayload(uint64_t max_frame_size) { | |||
| 193 | 193 | V(SendDatagram, sendDatagram, SIDE_EFFECT) \ | |
| 194 | 194 | V(LocalTransportParams, localTransportParams, NO_SIDE_EFFECT) \ | |
| 195 | 195 | V(RemoteTransportParams, remoteTransportParams, NO_SIDE_EFFECT) \ | |
| 196 | + V(ApplicationOptions, applicationOptions, NO_SIDE_EFFECT) | ||
| 196 | 197 | ||
| 197 | 198 | struct Session::State final { | |
| 198 | 199 | #define V(_, name, type) type name; | |
@@ -1195,6 +1196,24 @@ struct Session::Impl final : public MemoryRetainer { | |||
| 1195 | 1196 | args.GetReturnValue().Set(obj); | |
| 1196 | 1197 | } | |
| 1197 | 1198 | } | |
| 1199 | + | ||
| 1200 | + JS_METHOD(ApplicationOptions) { | ||
| 1201 | + auto env = Environment::GetCurrent(args); | ||
| 1202 | + Session* session; | ||
| 1203 | + ASSIGN_OR_RETURN_UNWRAP(&session, args.This()); | ||
| 1204 | + | ||
| 1205 | + Local<Object> obj; | ||
| 1206 | + if (!session->has_application()) { | ||
| 1207 | + // The application has not yet been selected (ALPN negotiation is not | ||
| 1208 | + // yet complete on the server) or the session has been destroyed. In | ||
| 1209 | + // either case, the application options are not available. | ||
| 1210 | + return args.GetReturnValue().SetUndefined(); | ||
| 1211 | + } | ||
| 1212 | + auto& options = session->application().options(); | ||
| 1213 | + if (options.ToObject(env).ToLocal(&obj)) { | ||
| 1214 | + args.GetReturnValue().Set(obj); | ||
| 1215 | + } | ||
| 1216 | + } | ||
| 1198 | 1217 | // Internal ngtcp2 callbacks | |
| 1199 | 1218 | ||
| 1200 | 1219 | static int on_acknowledge_stream_data_offset(ngtcp2_conn* conn, | |
@@ -2082,6 +2101,10 @@ TLSSession& Session::tls_session() const { | |||
| 2082 | 2101 | return *tls_session_; | |
| 2083 | 2102 | } | |
| 2084 | 2103 | ||
| 2104 | + bool Session::has_application() const { | ||
| 2105 | + return !is_destroyed() && impl_->application_ != nullptr; | ||
| 2106 | + } | ||
| 2107 | + | ||
| 2085 | 2108 | Session::Application& Session::application() const { | |
| 2086 | 2109 | DCHECK(!is_destroyed()); | |
| 2087 | 2110 | DCHECK(impl_->application_); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -91,6 +91,8 @@ class Session final : public AsyncWrap, private SessionTicket::AppData::Source { | |||
| 91 | 91 | ||
| 92 | 92 | std::string ToString() const; | |
| 93 | 93 | ||
| 94 | + v8::MaybeLocal<v8::Object> ToObject(Environment* env) const; | ||
| 95 | + | ||
| 94 | 96 | static const Application_Options kDefault; | |
| 95 | 97 | }; | |
| 96 | 98 | ||
@@ -324,6 +326,7 @@ class Session final : public AsyncWrap, private SessionTicket::AppData::Source { | |||
| 324 | 326 | uint32_t version() const; | |
| 325 | 327 | Endpoint& endpoint() const; | |
| 326 | 328 | TLSSession& tls_session() const; | |
| 329 | + bool has_application() const; | ||
| 327 | 330 | Application& application() const; | |
| 328 | 331 | const Config& config() const; | |
| 329 | 332 | const Options& options() const; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments