From 147cef29c10eb7bcb335971e794d04eef3fecf01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Tue, 11 Oct 2022 18:44:13 +0200 Subject: [PATCH] Use StreamContent.LoadIntoBufferAsync() to allow reading compressed responses multiple times --- .../OpenIddictClientSystemNetHttpHandlers.cs | 9 +++++++++ .../OpenIddictValidationSystemNetHttpHandlers.cs | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs b/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs index 9c7e7996..d3f10dfd 100644 --- a/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs +++ b/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs @@ -347,6 +347,10 @@ public static partial class OpenIddictClientSystemNetHttpHandlers try { + // Note: HttpCompletionOption.ResponseContentRead is deliberately used to force the + // response stream to be buffered so that can it can be read multiple times if needed + // (e.g if the JSON deserialization process fails, the stream is read as a string + // during a second pass a second time for logging/debuggability purposes). response = await client.SendAsync(request, HttpCompletionOption.ResponseContentRead); } @@ -524,7 +528,12 @@ public static partial class OpenIddictClientSystemNetHttpHandlers // to the HTTP response message to use the specified stream transformations. if (stream is not null) { + // Note: StreamContent.LoadIntoBufferAsync is deliberately used to force the stream + // content to be buffered so that can it can be read multiple times if needed + // (e.g if the JSON deserialization process fails, the stream is read as a string + // during a second pass a second time for logging/debuggability purposes). var content = new StreamContent(stream); + await content.LoadIntoBufferAsync(); // Copy the headers from the original content to the new instance. foreach (var header in response.Content.Headers) diff --git a/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs b/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs index 748c9193..ab38845e 100644 --- a/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs +++ b/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs @@ -348,6 +348,10 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers try { + // Note: HttpCompletionOption.ResponseContentRead is deliberately used to force the + // response stream to be buffered so that can it can be read multiple times if needed + // (e.g if the JSON deserialization process fails, the stream is read as a string + // during a second pass a second time for logging/debuggability purposes). response = await client.SendAsync(request, HttpCompletionOption.ResponseContentRead); } @@ -525,7 +529,12 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers // to the HTTP response message to use the specified stream transformations. if (stream is not null) { + // Note: StreamContent.LoadIntoBufferAsync is deliberately used to force the stream + // content to be buffered so that can it can be read multiple times if needed + // (e.g if the JSON deserialization process fails, the stream is read as a string + // during a second pass a second time for logging/debuggability purposes). var content = new StreamContent(stream); + await content.LoadIntoBufferAsync(); // Copy the headers from the original content to the new instance. foreach (var header in response.Content.Headers)