Skip to content

Commit 6d50c8f

Browse files
authored
Merge pull request #2209 from microsoftgraph/bugfixes/HttpMessageClone
Fixes request content cloning exception in .NET 4.x
2 parents 981a626 + f958c28 commit 6d50c8f

File tree

1 file changed

+32
-18
lines changed

1 file changed

+32
-18
lines changed

tools/Custom/HttpMessageLogFormatter.cs

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,27 +34,34 @@ internal static async Task<HttpRequestMessage> CloneAsync(this HttpRequestMessag
3434
// Set Content if previous requestClone had one.
3535
if (originalRequest.Content != null)
3636
{
37-
// HttpClient doesn't rewind streams and we have to explicitly do so.
38-
var ms = new MemoryStream();
39-
await originalRequest.Content.CopyToAsync(ms);
40-
ms.Position = 0;
41-
newRequest.Content = new StreamContent(ms);
42-
// Attempt to copy request content headers with a single retry.
43-
// HttpHeaders dictionary is not thread-safe when targeting anything below .NET 7. For more information, see https://github.com/dotnet/runtime/issues/61798.
44-
int retryCount = 0;
45-
int maxRetryCount = 2;
46-
while (retryCount < maxRetryCount)
37+
// Try cloning request content; otherwise, skip due to https://github.com/dotnet/corefx/pull/19082 in .NET 4.x.
38+
try
4739
{
48-
try
40+
// HttpClient doesn't rewind streams and we have to explicitly do so.
41+
var ms = new MemoryStream();
42+
await originalRequest.Content.CopyToAsync(ms).ConfigureAwait(false);
43+
ms.Position = 0;
44+
newRequest.Content = new StreamContent(ms);
45+
// Attempt to copy request content headers with a single retry.
46+
// HttpHeaders dictionary is not thread-safe when targeting anything below .NET 7. For more information, see https://github.com/dotnet/runtime/issues/61798.
47+
int retryCount = 0;
48+
int maxRetryCount = 2;
49+
while (retryCount < maxRetryCount)
4950
{
50-
originalRequest.Content.Headers?.ToList().ForEach(header => newRequest.Content.Headers.TryAddWithoutValidation(header.Key, header.Value));
51-
retryCount = maxRetryCount;
52-
}
53-
catch (InvalidOperationException)
54-
{
55-
retryCount++;
51+
try
52+
{
53+
originalRequest.Content?.Headers?.ToList().ForEach(header => newRequest.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value));
54+
retryCount = maxRetryCount;
55+
}
56+
catch (InvalidOperationException)
57+
{
58+
retryCount++;
59+
}
5660
}
5761
}
62+
catch
63+
{
64+
}
5865
}
5966
return newRequest;
6067
}
@@ -66,7 +73,14 @@ public static async Task<string> GetHttpRequestLogAsync(HttpRequestMessage reque
6673
string body = string.Empty;
6774
try
6875
{
69-
body = (requestClone.Content == null) ? string.Empty : FormatString(await requestClone.Content.ReadAsStringAsync());
76+
if (requestClone.Content != null)
77+
{
78+
body = FormatString(await requestClone.Content.ReadAsStringAsync());
79+
}
80+
else if (requestClone.Content == null && request.Content != null)
81+
{
82+
body = "Skipped: Content body was disposed before the logger could access it.";
83+
}
7084
}
7185
catch { }
7286

0 commit comments

Comments
 (0)