@@ -169,38 +169,44 @@ function parseContentLength(header: string | null): number | undefined {
169169 return Number . isFinite ( value ) && value >= 0 ? value : undefined ;
170170}
171171
172- /** Read a `ReadableStream<Uint8Array>` body with a hard byte cap; aborts and
173- * returns `{ exceeded: true }` if the cap is exceeded mid-stream. */
172+ /** Read a `ReadableStream<Uint8Array>` body with a hard byte cap. The returned
173+ * `bytes` holds the data read so far; `exceeded === true` means the cap was
174+ * hit and `bytes` should not be consumed. */
174175async function readBodyWithCap (
175176 body : ReadableStream < Uint8Array > | null ,
176177 maxBytes : number ,
177- ) : Promise < { exceeded : false ; bytes : Uint8Array } | { exceeded : true ; bytesRead : number } > {
178- if ( ! body ) return { exceeded : false , bytes : new Uint8Array ( 0 ) } ;
178+ ) : Promise < { exceeded : boolean ; bytes : Uint8Array ; bytesRead : number } > {
179+ if ( ! body ) return { exceeded : false , bytes : new Uint8Array ( 0 ) , bytesRead : 0 } ;
179180 const reader = body . getReader ( ) ;
180181 const chunks : Uint8Array [ ] = [ ] ;
181182 let total = 0 ;
183+ let exceeded = false ;
182184 try {
183185 for ( ; ; ) {
184186 const { value, done } = await reader . read ( ) ;
185187 if ( done ) break ;
186188 if ( ! value ) continue ;
187189 total += value . byteLength ;
188190 if ( total > maxBytes ) {
191+ exceeded = true ;
189192 await safeCancel ( reader ) ;
190- return { exceeded : true , bytesRead : total } ;
193+ break ;
191194 }
192195 chunks . push ( value ) ;
193196 }
194197 } finally {
195198 await safeReleaseLock ( reader ) ;
196199 }
200+ if ( exceeded ) {
201+ return { exceeded : true , bytes : new Uint8Array ( 0 ) , bytesRead : total } ;
202+ }
197203 const out = new Uint8Array ( total ) ;
198204 let offset = 0 ;
199205 for ( const chunk of chunks ) {
200206 out . set ( chunk , offset ) ;
201207 offset += chunk . byteLength ;
202208 }
203- return { exceeded : false , bytes : out } ;
209+ return { exceeded : false , bytes : out , bytesRead : total } ;
204210}
205211
206212/** Perform a single fetch with manual-redirect handling against the Riksbank
@@ -294,9 +300,10 @@ export async function fetchRiksbankPayload(
294300 `Riksbank JSON body exceeded ${ TEXT_RESPONSE_MAX_BYTES } bytes (read ${ capped . bytesRead } ); persisted as no-data.` ,
295301 ) ;
296302 }
303+ const jsonBytes = capped . bytes ;
297304 let json : unknown ;
298305 try {
299- json = JSON . parse ( new TextDecoder ( 'utf-8' ) . decode ( capped . bytes ) ) ;
306+ json = JSON . parse ( new TextDecoder ( 'utf-8' ) . decode ( jsonBytes ) ) ;
300307 } catch ( error ) {
301308 const detail = error instanceof Error ? error . message : String ( error ) ;
302309 return buildOutagePayload ( kind , finalUrlStr , contentType , `Riksbank JSON parse failed (${ detail } ).` ) ;
@@ -332,7 +339,8 @@ export async function fetchRiksbankPayload(
332339 `Riksbank PDF body exceeded ${ PDF_MAX_BYTES } bytes (read ${ capped . bytesRead } ); persisted as no-data.` ,
333340 ) ;
334341 }
335- const pdfBase64 = Buffer . from ( capped . bytes ) . toString ( 'base64' ) ;
342+ const pdfBytesRaw = capped . bytes ;
343+ const pdfBase64 = Buffer . from ( pdfBytesRaw ) . toString ( 'base64' ) ;
336344 return {
337345 provider : 'riksbank' ,
338346 kind,
@@ -341,7 +349,7 @@ export async function fetchRiksbankPayload(
341349 retrievedAt,
342350 status : 'ok' ,
343351 pdfBase64,
344- pdfBytes : capped . bytes . byteLength ,
352+ pdfBytes : pdfBytesRaw . byteLength ,
345353 economicProvenance : buildProvenance ( kind , finalUrlStr , retrievedAt ) ,
346354 } ;
347355 }
@@ -364,7 +372,8 @@ export async function fetchRiksbankPayload(
364372 `Riksbank text body exceeded ${ TEXT_RESPONSE_MAX_BYTES } bytes (read ${ capped . bytesRead } ); persisted as no-data.` ,
365373 ) ;
366374 }
367- const text = new TextDecoder ( 'utf-8' ) . decode ( capped . bytes ) ;
375+ const textBytes = capped . bytes ;
376+ const text = new TextDecoder ( 'utf-8' ) . decode ( textBytes ) ;
368377 const title = extractTitle ( text ) ;
369378 return {
370379 provider : 'riksbank' ,
0 commit comments