-
Notifications
You must be signed in to change notification settings - Fork 447
/
Copy pathHttpContentExtensions.cs
141 lines (128 loc) · 5 KB
/
HttpContentExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WebApiClientCore;
using WebApiClientCore.Exceptions;
using WebApiClientCore.Internals;
namespace System.Net.Http
{
/// <summary>
/// HttpContent扩展
/// </summary>
public static class HttpContentExtensions
{
private const string IsBufferedPropertyName = "IsBuffered";
private const string IsBufferedGetMethodName = "get_IsBuffered";
/// <summary>
/// IsBuffered字段
/// </summary>
private static readonly Func<HttpContent, bool>? isBufferedFunc;
/// <summary>
/// 静态构造器
/// </summary>
[DynamicDependency(DynamicallyAccessedMemberTypes.NonPublicProperties, typeof(HttpContent))]
static HttpContentExtensions()
{
var property = typeof(HttpContent).GetProperty(IsBufferedPropertyName, BindingFlags.Instance | BindingFlags.NonPublic);
if (property != null)
{
#if NET8_0_OR_GREATER
if (property.GetGetMethod(nonPublic: true)?.Name == IsBufferedGetMethodName)
{
isBufferedFunc = GetIsBuffered;
}
#endif
if (isBufferedFunc == null)
{
isBufferedFunc = LambdaUtil.CreateGetFunc<HttpContent, bool>(property);
}
}
}
#if NET8_0_OR_GREATER
[UnsafeAccessor(UnsafeAccessorKind.Method, Name = IsBufferedGetMethodName)]
private static extern bool GetIsBuffered(HttpContent httpContent);
#endif
/// <summary>
/// 获取是否已缓存数据
/// </summary>
/// <param name="httpContent"></param>
/// <returns></returns>
public static bool? IsBuffered(this HttpContent httpContent)
{
return isBufferedFunc == null ? null : isBufferedFunc(httpContent);
}
/// <summary>
/// 确保HttpContent的内容未被缓存
/// 已被缓存则抛出HttpContentBufferedException
/// </summary>
/// <param name="httpContent"></param>
/// <exception cref="HttpContentBufferedException"></exception>
public static void EnsureNotBuffered(this HttpContent httpContent)
{
if (httpContent.IsBuffered() == true)
{
throw new HttpContentBufferedException();
}
}
/// <summary>
/// 读取为二进制数组并转换为 utf8 编码
/// </summary>
/// <param name="httpContent"></param>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
public static Task<byte[]> ReadAsUtf8ByteArrayAsync(this HttpContent httpContent)
{
return httpContent.ReadAsByteArrayAsync(Encoding.UTF8, default);
}
/// <summary>
/// 读取为二进制数组并转换为指定的编码
/// </summary>
/// <param name="httpContent"></param>
/// <param name="dstEncoding">目标编码</param>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
public static Task<byte[]> ReadAsByteArrayAsync(this HttpContent httpContent, Encoding dstEncoding)
{
return httpContent.ReadAsByteArrayAsync(dstEncoding, default);
}
/// <summary>
/// 读取为二进制数组并转换为指定的编码
/// </summary>
/// <param name="httpContent"></param>
/// <param name="dstEncoding">目标编码</param>
/// <param name="cancellationToken"></param>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
public static async Task<byte[]> ReadAsByteArrayAsync(this HttpContent httpContent, Encoding dstEncoding, CancellationToken cancellationToken)
{
var encoding = httpContent.GetEncoding();
var byteArray = await httpContent.ReadAsByteArrayAsync(cancellationToken).ConfigureAwait(false);
return encoding.Equals(dstEncoding) ? byteArray : Encoding.Convert(encoding, dstEncoding, byteArray);
}
/// <summary>
/// 获取编码信息
/// </summary>
/// <param name="httpContent"></param>
/// <returns></returns>
public static Encoding GetEncoding(this HttpContent httpContent)
{
var contentType = httpContent.Headers.ContentType;
if (contentType == null)
{
return Encoding.UTF8;
}
var charSet = contentType.CharSet.AsSpan();
if (charSet.IsEmpty)
{
return Encoding.UTF8;
}
var encoding = charSet.Trim('"');
return encoding.Equals(Encoding.UTF8.WebName, StringComparison.OrdinalIgnoreCase)
? Encoding.UTF8
: Encoding.GetEncoding(encoding.ToString());
}
}
}