@@ -57,27 +57,32 @@ package struct QPACKStateMachine: ~Copyable {
5757 }
5858
5959 private let state : State
60+ private let localMaxTableCapacity : Int
6061
61- private init ( state: consuming State ) {
62+ private init ( state: consuming State , localMaxTableCapacity : Int ) {
6263 self . state = state
64+ self . localMaxTableCapacity = localMaxTableCapacity
6365 }
6466
65- init ( ) {
66- self . init ( state: . initial( . init( encoder: . init( ) ) ) )
67+ init ( localMaxTableCapacity : Int ) {
68+ self . init ( state: . initial( . init( encoder: . init( ) ) ) , localMaxTableCapacity : localMaxTableCapacity )
6769 }
6870
6971 mutating func receivedRemoteSettings(
7072 maxQueueSize: Int ,
7173 dynamicTableSize: Int
7274 ) -> GotRemoteSettingsAction ? {
75+ let localMaxTableCapacity = self . localMaxTableCapacity
7376 switch consume self. state {
7477 case . initial( let initial) :
7578 // RFC 9204 § 4.2: An endpoint MAY avoid creating an encoder stream if it will not be used
76- if dynamicTableSize == 0 {
79+ // This should include if the local table will not be used either
80+ if dynamicTableSize == 0 || localMaxTableCapacity == 0 {
7781 self = . init(
7882 state: . withoutDynamic(
7983 . init( encoder: initial. encoder)
80- )
84+ ) ,
85+ localMaxTableCapacity: localMaxTableCapacity
8186 )
8287 return nil
8388 } else {
@@ -88,7 +93,8 @@ package struct QPACKStateMachine: ~Copyable {
8893 maxQueueSize: maxQueueSize,
8994 dynamicTableSize: dynamicTableSize
9095 )
91- )
96+ ) ,
97+ localMaxTableCapacity: localMaxTableCapacity
9298 )
9399 return . makeEncoderInstructionStream
94100 }
@@ -109,6 +115,7 @@ package struct QPACKStateMachine: ~Copyable {
109115 }
110116
111117 mutating func outboundEncoderStreamReady( ) -> OutboundEncoderStreamReadyAction {
118+ let localMaxTableCapacity = self . localMaxTableCapacity
112119 switch consume self. state {
113120 case . initial:
114121 fatalError ( " Encoder stream created when not needed or already made " )
@@ -128,35 +135,37 @@ package struct QPACKStateMachine: ~Copyable {
128135 . init(
129136 encoder: dynamicEncoder
130137 )
131- )
138+ ) ,
139+ localMaxTableCapacity: localMaxTableCapacity
132140 )
133141 return . sendEncoderInstruction( instruction)
134142 }
135143 }
136144
137145 mutating func encodeHeaders( _ headers: [ HTTPField ] , forStream streamID: QUICStreamID ) -> QPACKEncodeResult {
146+ let localMaxTableCapacity = self . localMaxTableCapacity
138147 switch consume self. state {
139148 case . initial( let initial) :
140149 let result = QPACKEncodeResult ( fieldSection: initial. encoder. encode ( headers: headers) , instructions: [ ] )
141- self = . init( state: . initial( initial) )
150+ self = . init( state: . initial( initial) , localMaxTableCapacity : localMaxTableCapacity )
142151 return result
143152 case . awaitingStream( let awaiting) :
144153 let result = QPACKEncodeResult (
145154 fieldSection: awaiting. encoder. encode ( headers: headers) ,
146155 instructions: [ ]
147156 )
148- self = . init( state: . awaitingStream( awaiting) )
157+ self = . init( state: . awaitingStream( awaiting) , localMaxTableCapacity : localMaxTableCapacity )
149158 return result
150159 case . withoutDynamic( let woDynamic) :
151160 let result = QPACKEncodeResult (
152161 fieldSection: woDynamic. encoder. encode ( headers: headers) ,
153162 instructions: [ ]
154163 )
155- self = . init( state: . withoutDynamic( woDynamic) )
164+ self = . init( state: . withoutDynamic( woDynamic) , localMaxTableCapacity : localMaxTableCapacity )
156165 return result
157166 case . withDynamic( var withDynamic) :
158167 let result = withDynamic. encoder. encode ( headers: headers, forStream: streamID)
159- self = . init( state: . withDynamic( withDynamic) )
168+ self = . init( state: . withDynamic( withDynamic) , localMaxTableCapacity : localMaxTableCapacity )
160169 return result
161170 }
162171 }
@@ -178,20 +187,21 @@ package struct QPACKStateMachine: ~Copyable {
178187 location: location
179188 )
180189 }
190+ let localMaxTableCapacity = self . localMaxTableCapacity
181191 switch consume self. state {
182192 case . initial( let initial) :
183- self = . init( state: . initial( initial) )
193+ self = . init( state: . initial( initial) , localMaxTableCapacity : localMaxTableCapacity )
184194 return . emitConnectionError( noDynamicTableError ( location: . here( ) ) )
185195 case . awaitingStream( let awaitingStream) :
186- self = . init( state: . awaitingStream( awaitingStream) )
196+ self = . init( state: . awaitingStream( awaitingStream) , localMaxTableCapacity : localMaxTableCapacity )
187197 return . emitConnectionError( noDynamicTableError ( location: . here( ) ) )
188198 case . withoutDynamic( let withoutDynamic) :
189- self = . init( state: . withoutDynamic( withoutDynamic) )
199+ self = . init( state: . withoutDynamic( withoutDynamic) , localMaxTableCapacity : localMaxTableCapacity )
190200 return . emitConnectionError( noDynamicTableError ( location: . here( ) ) )
191201 case . withDynamic( var withDynamic) :
192202 do {
193203 try withDynamic. encoder. processInstruction ( instruction)
194- self = . init( state: . withDynamic( withDynamic) )
204+ self = . init( state: . withDynamic( withDynamic) , localMaxTableCapacity : localMaxTableCapacity )
195205 return nil
196206 } catch {
197207 @inline ( never)
@@ -208,7 +218,7 @@ package struct QPACKStateMachine: ~Copyable {
208218 )
209219 }
210220 // TODO: move to error state?
211- self = . init( state: . withDynamic( withDynamic) )
221+ self = . init( state: . withDynamic( withDynamic) , localMaxTableCapacity : localMaxTableCapacity )
212222 return . emitConnectionError( invalidDecoderInstructionError ( cause: error, location: . here( ) ) )
213223 }
214224 }
@@ -284,8 +294,8 @@ package struct QPACKStateMachine: ~Copyable {
284294 private var decoderQueue : FieldSectionQueue
285295 private var outboundDecoderInstructionQueue : OutboundDecoderInstructionQueue
286296
287- package init ( decoderMaxTableSize: Int , decoderMaxBlockedStreams: Int ) {
288- self . encoderState = . init( )
297+ package init ( decoderMaxTableSize: Int , decoderMaxBlockedStreams: Int , localEncoderMaxTableCapacity : Int = 0 ) {
298+ self . encoderState = . init( localMaxTableCapacity : localEncoderMaxTableCapacity )
289299 self . qpackDecoder = . init( dynamicTableMaxCapacity: decoderMaxTableSize)
290300 self . decoderQueue = . init( maxItems: decoderMaxBlockedStreams)
291301 self . outboundDecoderInstructionQueue = . init( )
0 commit comments