@@ -1221,6 +1221,34 @@ export interface DoubleKnockOptions {
12211221 tracerProvider ?: TracerProvider ;
12221222}
12231223
1224+ /**
1225+ * Helper function to create a new Request for redirect handling.
1226+ * @param request The original request.
1227+ * @param location The redirect location.
1228+ * @param body The request body as ArrayBuffer or undefined.
1229+ * @returns A new Request object for the redirect.
1230+ */
1231+ function createRedirectRequest (
1232+ request : Request ,
1233+ location : string ,
1234+ body : ArrayBuffer | undefined ,
1235+ ) : Request {
1236+ return new Request ( location , {
1237+ method : request . method ,
1238+ headers : request . headers ,
1239+ body,
1240+ redirect : "manual" ,
1241+ signal : request . signal ,
1242+ mode : request . mode ,
1243+ credentials : request . credentials ,
1244+ referrer : request . referrer ,
1245+ referrerPolicy : request . referrerPolicy ,
1246+ integrity : request . integrity ,
1247+ keepalive : request . keepalive ,
1248+ cache : request . cache ,
1249+ } ) ;
1250+ }
1251+
12241252/**
12251253 * Performs a double-knock request to the given URL. For the details of
12261254 * double-knocking, see
@@ -1264,19 +1292,7 @@ export async function doubleKnock(
12641292 ? await request . clone ( ) . arrayBuffer ( )
12651293 : undefined ;
12661294 return doubleKnock (
1267- new Request ( location , {
1268- method : request . method ,
1269- headers : request . headers ,
1270- body,
1271- redirect : "manual" ,
1272- signal : request . signal ,
1273- mode : request . mode ,
1274- credentials : request . credentials ,
1275- referrer : request . referrer ,
1276- referrerPolicy : request . referrerPolicy ,
1277- integrity : request . integrity ,
1278- keepalive : request . keepalive ,
1279- } ) ,
1295+ createRedirectRequest ( request , location , body ) ,
12801296 identity ,
12811297 options ,
12821298 ) ;
@@ -1322,11 +1338,15 @@ export async function doubleKnock(
13221338 response . headers . has ( "Location" )
13231339 ) {
13241340 const location = response . headers . get ( "Location" ) ! ;
1341+ // IMPORTANT: Use arrayBuffer() instead of .body to prevent "TypeError: unusable"
1342+ // When using .body (ReadableStream), subsequent clone() calls in signRequest functions
1343+ // will fail because the stream has already been consumed. Using arrayBuffer() ensures
1344+ // the body can be safely cloned for HTTP signature generation.
13251345 const body = request . method !== "GET" && request . method !== "HEAD"
1326- ? request . clone ( ) . body
1327- : null ;
1346+ ? await request . clone ( ) . arrayBuffer ( )
1347+ : undefined ;
13281348 return doubleKnock (
1329- new Request ( location , { ... request , body } ) ,
1349+ createRedirectRequest ( request , location , body ) ,
13301350 identity ,
13311351 options ,
13321352 ) ;
0 commit comments