Skip to content

Commit ac1fe70

Browse files
authored
Merge branch 'main' into static-table-find
2 parents 06ecf9b + 8119053 commit ac1fe70

4 files changed

Lines changed: 27 additions & 17 deletions

File tree

Sources/HTTP3/HTTP3ConnectionStateMachine.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ package struct HTTP3ConnectionStateMachine: ~Copyable {
8888
var qpackState: QPACKStateMachine
8989
/// The type of the connection (client or server).
9090
let type: HTTP3ConnectionType
91+
let encoderMaxTableSize: Int
9192
var streamIDTracker = StreamIDTracker()
9293
var quiescingState: HTTP3ConnectionQuiescingStateMachine
9394

@@ -97,6 +98,7 @@ package struct HTTP3ConnectionStateMachine: ~Copyable {
9798
self.inboundQPACKEncoderStream = .init()
9899
self.qpackState = notStarted.qpackState
99100
self.type = notStarted.type
101+
self.encoderMaxTableSize = Int(clamping: notStarted.localSettings.qpackMaximumTableCapacity)
100102
self.quiescingState = .init(type: notStarted.type)
101103
}
102104
}
@@ -524,7 +526,10 @@ package struct HTTP3ConnectionStateMachine: ~Copyable {
524526
case .initialized(var initializedState):
525527
let action = initializedState.qpackState.receivedRemoteSettings(
526528
maxQueueSize: Int(clamping: settings.qpackBlockedStreams),
527-
dynamicTableSize: Int(clamping: settings.qpackMaximumTableCapacity)
529+
effectiveDynamicTableSize: min(
530+
initializedState.encoderMaxTableSize,
531+
Int(clamping: settings.qpackMaximumTableCapacity)
532+
)
528533
)
529534
self = .init(state: .initialized(initializedState))
530535
switch action {

Sources/HTTP3/QPACK/QPACKStateMachine.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ package struct QPACKStateMachine: ~Copyable {
6868

6969
mutating func receivedRemoteSettings(
7070
maxQueueSize: Int,
71-
dynamicTableSize: Int
71+
effectiveDynamicTableSize: Int
7272
) -> GotRemoteSettingsAction? {
7373
switch consume self.state {
7474
case .initial(let initial):
7575
// RFC 9204 § 4.2: An endpoint MAY avoid creating an encoder stream if it will not be used
76-
if dynamicTableSize == 0 {
76+
if effectiveDynamicTableSize == 0 {
7777
self = .init(
7878
state: .withoutDynamic(
7979
.init(encoder: initial.encoder)
@@ -86,7 +86,7 @@ package struct QPACKStateMachine: ~Copyable {
8686
.init(
8787
encoder: initial.encoder,
8888
maxQueueSize: maxQueueSize,
89-
dynamicTableSize: dynamicTableSize
89+
dynamicTableSize: effectiveDynamicTableSize
9090
)
9191
)
9292
)
@@ -298,9 +298,12 @@ package struct QPACKStateMachine: ~Copyable {
298298
/// Call this when the settings have been received from the remote. This must never be called more than once.
299299
package mutating func receivedRemoteSettings(
300300
maxQueueSize: Int,
301-
dynamicTableSize: Int
301+
effectiveDynamicTableSize: Int
302302
) -> GotRemoteSettingsAction? {
303-
self.encoderState.receivedRemoteSettings(maxQueueSize: maxQueueSize, dynamicTableSize: dynamicTableSize)
303+
self.encoderState.receivedRemoteSettings(
304+
maxQueueSize: maxQueueSize,
305+
effectiveDynamicTableSize: effectiveDynamicTableSize
306+
)
304307
}
305308

306309
package enum OutboundEncoderStreamReadyAction: Hashable, Sendable {

Tests/HTTP3Tests/HTTP3ConnectionStateMachineTests.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -363,11 +363,12 @@ struct HTTP3ConnectionStateMachineTests {
363363

364364
@Test
365365
func testGotSettingsWithQPACK() {
366+
let localSettings = HTTP3Settings(qpackMaximumTableCapacity: 200)
366367
let remoteSettings = HTTP3Settings(qpackMaximumTableCapacity: 100)
367-
var stateMachine = HTTP3ConnectionStateMachine(settings: .init(), type: .client)
368+
var stateMachine = HTTP3ConnectionStateMachine(settings: localSettings, type: .client)
368369

369370
let action1 = stateMachine.initialize()
370-
#expect(action1 == .createControlStream)
371+
#expect(action1 == .createControlAndDecoderStreams)
371372

372373
let action2 = stateMachine.receivedControlFrame(.settings(remoteSettings))
373374
guard case .makeEncoderInstructionStream = action2 else {
@@ -733,11 +734,12 @@ struct HTTP3ConnectionStateMachineTests {
733734

734735
@Test
735736
func testEncoderStreamReadyAfterShutdown() {
737+
let localSettings = HTTP3Settings(qpackMaximumTableCapacity: 200)
736738
let remoteSettings = HTTP3Settings(qpackMaximumTableCapacity: 100)
737-
var stateMachine = HTTP3ConnectionStateMachine(settings: .init(), type: .client)
739+
var stateMachine = HTTP3ConnectionStateMachine(settings: localSettings, type: .client)
738740

739741
let action1 = stateMachine.initialize()
740-
#expect(action1 == .createControlStream)
742+
#expect(action1 == .createControlAndDecoderStreams)
741743

742744
let action2 = stateMachine.receivedControlFrame(.settings(remoteSettings))
743745
guard case .makeEncoderInstructionStream = action2 else {

Tests/HTTP3Tests/QPACKStateMachineTests.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ struct QPACKStateMachineTests {
2727
@Test
2828
func testSettingsWithoutDynamicTable() {
2929
var stateMachine = QPACKStateMachine(decoderMaxTableSize: 1024, decoderMaxBlockedStreams: 100)
30-
let action = stateMachine.receivedRemoteSettings(maxQueueSize: 0, dynamicTableSize: 0)
30+
let action = stateMachine.receivedRemoteSettings(maxQueueSize: 0, effectiveDynamicTableSize: 0)
3131
switch action {
3232
case .makeEncoderInstructionStream:
3333
Issue.record("Expected no outbound encoder stream")
@@ -59,7 +59,7 @@ struct QPACKStateMachineTests {
5959
@Test
6060
func testEncodeHeadersInWaitingForStreamState() {
6161
var stateMachine = QPACKStateMachine(decoderMaxTableSize: 1024, decoderMaxBlockedStreams: 100)
62-
let action = stateMachine.receivedRemoteSettings(maxQueueSize: 100, dynamicTableSize: 100)
62+
let action = stateMachine.receivedRemoteSettings(maxQueueSize: 100, effectiveDynamicTableSize: 100)
6363
#expect(action == .makeEncoderInstructionStream)
6464
// We have received remote settings, and been asked to create outbound encoder stream
6565
// However, the outbound stream isn't ready yet, so the dynamic table should not be used
@@ -69,7 +69,7 @@ struct QPACKStateMachineTests {
6969
@Test
7070
func testEncodeHeadersInWithoutDynamicState() {
7171
var stateMachine = QPACKStateMachine(decoderMaxTableSize: 1024, decoderMaxBlockedStreams: 100)
72-
let action = stateMachine.receivedRemoteSettings(maxQueueSize: 100, dynamicTableSize: 0)
72+
let action = stateMachine.receivedRemoteSettings(maxQueueSize: 100, effectiveDynamicTableSize: 0)
7373
#expect(action == nil) // No outbound stream because 0 size
7474
// We have received remote settings, but they specify 0 table size. Therefore we should not use dynamic table
7575
stateMachine.assertEncodesWithoutUsingDynamicTable()
@@ -78,7 +78,7 @@ struct QPACKStateMachineTests {
7878
@Test
7979
func testEncodeHeadersInWithDynamicState() {
8080
var stateMachine = QPACKStateMachine(decoderMaxTableSize: 1024, decoderMaxBlockedStreams: 100)
81-
let action1 = stateMachine.receivedRemoteSettings(maxQueueSize: 100, dynamicTableSize: 300)
81+
let action1 = stateMachine.receivedRemoteSettings(maxQueueSize: 100, effectiveDynamicTableSize: 300)
8282
#expect(action1 == .makeEncoderInstructionStream)
8383
let action2 = stateMachine.outboundEncoderStreamReady()
8484
// The stream is ready so we should immediately start using the table at max capacity
@@ -464,7 +464,7 @@ struct QPACKStateMachineTests {
464464
@Test
465465
func testGotDecoderInstructionWhenExplicitlyNoDynamicTable() {
466466
var stateMachine = QPACKStateMachine(decoderMaxTableSize: 1024, decoderMaxBlockedStreams: 100)
467-
_ = stateMachine.receivedRemoteSettings(maxQueueSize: 0, dynamicTableSize: 0)
467+
_ = stateMachine.receivedRemoteSettings(maxQueueSize: 0, effectiveDynamicTableSize: 0)
468468
// This instruction is invalid because remote explicitly told us no dynamic table capacity
469469
let action = stateMachine.receivedIncomingDecoderInstruction(.sectionAcknowledgement(streamID: 1))
470470
guard case .emitConnectionError(let error) = action else {
@@ -481,7 +481,7 @@ struct QPACKStateMachineTests {
481481
@Test
482482
func testGotDecoderInstructionWhenAwaitingStream() {
483483
var stateMachine = QPACKStateMachine(decoderMaxTableSize: 1024, decoderMaxBlockedStreams: 100)
484-
_ = stateMachine.receivedRemoteSettings(maxQueueSize: 100, dynamicTableSize: 100)
484+
_ = stateMachine.receivedRemoteSettings(maxQueueSize: 100, effectiveDynamicTableSize: 100)
485485
// We can't receive instructions from the remote decoder until we ourselves have sent an instruction to indicate support of the dynamic table
486486
let action = stateMachine.receivedIncomingDecoderInstruction(.sectionAcknowledgement(streamID: 1))
487487
guard case .emitConnectionError(let error) = action else {
@@ -660,7 +660,7 @@ extension QPACKStateMachine {
660660
/// Simulate receiving settings from the remote which allows the local encoder to use the dynamic table.
661661
fileprivate mutating func setupRemoteDynamicTable(maxSize: Int) {
662662
// remote sends us settings saying we may use the dynamic table
663-
let actions1 = self.receivedRemoteSettings(maxQueueSize: 100, dynamicTableSize: maxSize)
663+
let actions1 = self.receivedRemoteSettings(maxQueueSize: 100, effectiveDynamicTableSize: maxSize)
664664
switch actions1 {
665665
// We open an encoder stream
666666
case .makeEncoderInstructionStream:

0 commit comments

Comments
 (0)