forked from NetCoreStack/Proxy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHttpDispatchProxy.cs
More file actions
127 lines (107 loc) · 4.54 KB
/
HttpDispatchProxy.cs
File metadata and controls
127 lines (107 loc) · 4.54 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
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
using Microsoft.AspNetCore.Http;
using NetCoreStack.Proxy.Internal;
using System;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;
namespace NetCoreStack.Proxy
{
public class HttpDispatchProxy : DispatchProxyAsync
{
private ProxyContext _proxyContext;
private IProxyManager _proxyManager;
public HttpDispatchProxy()
{
}
private object CreateContextProperties(RequestContext context, MethodInfo targetMethod)
{
var properties = new
{
EnvironmentName = Environment.MachineName,
Message = $"Proxy call from Sandbox: {Environment.MachineName} to API method: {targetMethod?.Name}",
Method = context?.Request?.Method,
Authority = context?.Request?.RequestUri?.Authority,
LocalPath = context?.Request?.RequestUri?.LocalPath,
RequestRegion = context?.RegionKey
};
return properties;
}
/// <summary>
/// Call after resolve the proxy
/// </summary>
/// <param name="proxyFactory"></param>
public void Initialize(ProxyContext context, IProxyManager proxyManager)
{
_proxyContext = context;
_proxyManager = proxyManager;
}
private async Task<ResponseContext> InternalInvokeAsync(MethodInfo targetMethod, object[] args, Type genericReturnType = null)
{
var culture = _proxyContext.CultureFactory?.Invoke();
var descriptor = new RequestDescriptor(targetMethod,
_proxyContext.ProxyType,
_proxyContext.ClientIp,
_proxyContext.UserAgent,
_proxyContext.Query,
culture,
args);
RequestContext requestContext = await _proxyManager.CreateRequestAsync(descriptor);
ResponseContext responseContext = null;
try
{
HttpResponseMessage response = null;
string metadata = string.Empty;
if (_proxyManager.HasFilter)
{
await Task.WhenAll(_proxyManager.RequestFilters.Select(t => t.InvokeAsync(requestContext)));
}
response = await _proxyManager.HttpClient.SendAsync(requestContext.Request);
responseContext = await ProxyResultExecutor.ExecuteAsync(response,
requestContext,
genericReturnType);
}
catch (Exception ex)
{
var properties = CreateContextProperties(requestContext, targetMethod);
var result = properties.GetConfigurationContextDetail(properties);
throw new ProxyException(result, ex);
}
if ((int)responseContext.Response.StatusCode == StatusCodes.Status404NotFound)
{
var properties = CreateContextProperties(requestContext, targetMethod);
var result = properties.GetConfigurationContextDetail(properties);
throw new ProxyException(result, new HttpRequestException());
}
return responseContext;
}
public override async Task InvokeAsync(MethodInfo method, object[] args)
{
if (method.Name == "get_ControllerContext")
{
throw new NotSupportedException($"\"ActionContext\" is not supported for proxy instance");
}
using (ResponseContext responseContext = await InternalInvokeAsync(method, args)) { }
}
public override async Task<T> InvokeAsyncT<T>(MethodInfo method, object[] args)
{
if (method.Name == "get_ControllerContext")
{
throw new NotSupportedException($"\"ActionContext\" is not supported for proxy instance");
}
using (ResponseContext responseContext = await InternalInvokeAsync(method, args, typeof(T)))
{
return (T)responseContext.Value;
}
}
public override object Invoke(MethodInfo method, object[] args)
{
if (method.Name == "get_ControllerContext")
{
throw new NotSupportedException($"\"ActionContext\" is not supported for proxy instance");
}
ResponseContext context = Task.Run(async () => await InternalInvokeAsync(method, args).ConfigureAwait(false)).Result;
return context.Value;
}
}
}