-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathDynamicResponseBuilder.cs
More file actions
91 lines (74 loc) · 2.91 KB
/
Copy pathDynamicResponseBuilder.cs
File metadata and controls
91 lines (74 loc) · 2.91 KB
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
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information
using System;
#if NET8_0_OR_GREATER
using System.Buffers;
#endif
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Elastic.Transport;
internal class DynamicResponseBuilder<T> : TypedResponseBuilder<T> where T : DynamicResponseBase, new()
{
protected override T Build(ApiCallDetails apiCallDetails, BoundConfiguration boundConfiguration, Stream responseStream, string contentType, long contentLength) =>
BuildCoreAsync(false, apiCallDetails, boundConfiguration, responseStream, contentType, contentLength).EnsureCompleted();
protected override Task<T> BuildAsync(ApiCallDetails apiCallDetails, BoundConfiguration boundConfiguration, Stream responseStream, string contentType, long contentLength, CancellationToken cancellationToken = default) =>
BuildCoreAsync(true, apiCallDetails, boundConfiguration, responseStream, contentType, contentLength, cancellationToken).AsTask();
private static async ValueTask<T> BuildCoreAsync(bool isAsync, ApiCallDetails apiCallDetails, BoundConfiguration boundConfiguration, Stream responseStream,
string contentType, long contentLength, CancellationToken cancellationToken = default)
{
//if not json store the result under "body"
if (!boundConfiguration.ConnectionSettings.ProductRegistration.IsJsonContentType(contentType))
{
DynamicDictionary dictionary;
string stringValue;
if (apiCallDetails.ResponseBodyInBytes is not null)
{
stringValue = Encoding.UTF8.GetString(apiCallDetails.ResponseBodyInBytes);
dictionary = new DynamicDictionary
{
["body"] = new DynamicValue(stringValue)
};
return new T { Body = dictionary };
}
#if NET8_0_OR_GREATER
if (contentLength is > (-1) and <= 1_048_576)
{
var buffer = ArrayPool<byte>.Shared.Rent((int)contentLength);
responseStream.ReadExactly(buffer, 0, (int)contentLength);
stringValue = Encoding.UTF8.GetString(buffer.AsSpan(0, (int)contentLength));
ArrayPool<byte>.Shared.Return(buffer);
dictionary = new DynamicDictionary
{
["body"] = new DynamicValue(stringValue)
};
return new T { Body = dictionary };
}
#endif
var sr = new StreamReader(responseStream);
if (isAsync)
{
stringValue = await sr.ReadToEndAsync
(
#if NET8_0_OR_GREATER
cancellationToken
#endif
).ConfigureAwait(false);
}
else
{
stringValue = sr.ReadToEnd();
}
dictionary = new DynamicDictionary
{
["body"] = new DynamicValue(stringValue)
};
return new T { Body = dictionary };
}
var body = LowLevelRequestResponseSerializer.Instance.Deserialize<DynamicDictionary>(responseStream);
return new T { Body = body };
}
}
internal class DynamicResponseBuilder : DynamicResponseBuilder<DynamicResponse>;