-
Notifications
You must be signed in to change notification settings - Fork 7
/
JsonServerResponseWrapper.cs
93 lines (83 loc) · 3.09 KB
/
JsonServerResponseWrapper.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
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Tochka.JsonRpc.Common;
using Tochka.JsonRpc.Common.Models.Request;
using Tochka.JsonRpc.Common.Models.Request.Untyped;
using Tochka.JsonRpc.Common.Serializers;
namespace Tochka.JsonRpc.Server.Models.Response
{
public class JsonServerResponseWrapper : IServerResponseWrapper
{
public IHeaderDictionary Headers { get; }
public JToken Value { get; }
public JsonServerResponseWrapper(JToken value, IUntypedCall call, IHeaderDictionary headers)
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
Value = SetId(value, call);
Headers = headers;
}
internal static JToken SetId(JToken value, IUntypedCall call)
{
if (call is UntypedRequest request)
{
value[JsonRpcConstants.IdProperty] = request.RawId;
}
return value;
}
/// <summary>
/// Set code 200, set content-type, add headers if not null, write json body if not null
/// </summary>
/// <returns></returns>
public async Task Write(HandlingContext context, HeaderJsonRpcSerializer headerJsonRpcSerializer)
{
var sink = context.OriginalHttpContext.Response;
if (Headers != null)
{
foreach (var header in Headers)
{
sink.Headers.Append(header.Key, header.Value);
}
}
sink.StatusCode = 200;
sink.ContentLength = null;
var responseMediaType = new MediaTypeHeaderValue(JsonRpcConstants.ContentType)
{
Encoding = context.RequestEncoding
};
sink.ContentType = responseMediaType.ToString();
if (!context.WriteResponse)
{
return;
}
using (var writer = new HttpResponseStreamWriter(sink.Body, context.RequestEncoding))
{
using (var jsonWriter = new JsonTextWriter(writer))
{
jsonWriter.Formatting = headerJsonRpcSerializer.Settings.Formatting;
await Value.WriteToAsync(jsonWriter, context.OriginalHttpContext.RequestAborted);
}
}
SetResponseContextItem(context.OriginalHttpContext);
}
/// <summary>
/// Store ambient information about response. Useful for metrics
/// </summary>
/// <param name="context"></param>
private void SetResponseContextItem(HttpContext context)
{
var errorCode = Value[JsonRpcConstants.ErrorProperty]?[JsonRpcConstants.ErrorCodeProperty]?.Value<string>();
if (!string.IsNullOrEmpty(errorCode))
{
context.Items[JsonRpcConstants.ResponseErrorCodeItemKey] = errorCode;
}
}
}
}