mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-24 05:52:49 +08:00
135 lines
4.4 KiB
C#
135 lines
4.4 KiB
C#
namespace Ocelot.Infrastructure
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Ocelot.Infrastructure.RequestData;
|
|
using Ocelot.Middleware;
|
|
using Ocelot.Request.Middleware;
|
|
using Ocelot.Responses;
|
|
|
|
public class Placeholders : IPlaceholders
|
|
{
|
|
private readonly Dictionary<string, Func<Response<string>>> _placeholders;
|
|
private readonly Dictionary<string, Func<DownstreamRequest, string>> _requestPlaceholders;
|
|
private readonly IBaseUrlFinder _finder;
|
|
private readonly IRequestScopedDataRepository _repo;
|
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
|
|
|
public Placeholders(IBaseUrlFinder finder, IRequestScopedDataRepository repo, IHttpContextAccessor httpContextAccessor)
|
|
{
|
|
_repo = repo;
|
|
_httpContextAccessor = httpContextAccessor;
|
|
_finder = finder;
|
|
_placeholders = new Dictionary<string, Func<Response<string>>>
|
|
{
|
|
{ "{BaseUrl}", GetBaseUrl() },
|
|
{ "{TraceId}", GetTraceId() },
|
|
{ "{RemoteIpAddress}", GetRemoteIpAddress() }
|
|
};
|
|
|
|
_requestPlaceholders = new Dictionary<string, Func<DownstreamRequest, string>>
|
|
{
|
|
{ "{DownstreamBaseUrl}", GetDownstreamBaseUrl() }
|
|
};
|
|
}
|
|
|
|
public Response<string> Get(string key)
|
|
{
|
|
if (_placeholders.ContainsKey(key))
|
|
{
|
|
var response = _placeholders[key].Invoke();
|
|
if (!response.IsError)
|
|
{
|
|
return new OkResponse<string>(response.Data);
|
|
}
|
|
}
|
|
|
|
return new ErrorResponse<string>(new CouldNotFindPlaceholderError(key));
|
|
}
|
|
|
|
public Response<string> Get(string key, DownstreamRequest request)
|
|
{
|
|
if (_requestPlaceholders.ContainsKey(key))
|
|
{
|
|
return new OkResponse<string>(_requestPlaceholders[key].Invoke(request));
|
|
}
|
|
|
|
return new ErrorResponse<string>(new CouldNotFindPlaceholderError(key));
|
|
}
|
|
|
|
public Response Add(string key, Func<Response<string>> func)
|
|
{
|
|
if (_placeholders.ContainsKey(key))
|
|
{
|
|
return new ErrorResponse(new CannotAddPlaceholderError($"Unable to add placeholder: {key}, placeholder already exists"));
|
|
}
|
|
|
|
_placeholders.Add(key, func);
|
|
return new OkResponse();
|
|
}
|
|
|
|
public Response Remove(string key)
|
|
{
|
|
if (!_placeholders.ContainsKey(key))
|
|
{
|
|
return new ErrorResponse(new CannotRemovePlaceholderError($"Unable to remove placeholder: {key}, placeholder does not exists"));
|
|
}
|
|
|
|
_placeholders.Remove(key);
|
|
return new OkResponse();
|
|
}
|
|
|
|
private Func<Response<string>> GetRemoteIpAddress()
|
|
{
|
|
return () =>
|
|
{
|
|
// this can blow up so adding try catch and return error
|
|
try
|
|
{
|
|
var remoteIdAddress = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();
|
|
return new OkResponse<string>(remoteIdAddress);
|
|
}
|
|
catch
|
|
{
|
|
return new ErrorResponse<string>(new CouldNotFindPlaceholderError("{RemoteIpAddress}"));
|
|
}
|
|
};
|
|
}
|
|
|
|
private Func<DownstreamRequest, string> GetDownstreamBaseUrl()
|
|
{
|
|
return x =>
|
|
{
|
|
var downstreamUrl = $"{x.Scheme}://{x.Host}";
|
|
|
|
if (x.Port != 80 && x.Port != 443)
|
|
{
|
|
downstreamUrl = $"{downstreamUrl}:{x.Port}";
|
|
}
|
|
|
|
return $"{downstreamUrl}/";
|
|
};
|
|
}
|
|
|
|
private Func<Response<string>> GetTraceId()
|
|
{
|
|
return () =>
|
|
{
|
|
var traceId = _repo.Get<string>("TraceId");
|
|
if (traceId.IsError)
|
|
{
|
|
return new ErrorResponse<string>(traceId.Errors);
|
|
}
|
|
|
|
return new OkResponse<string>(traceId.Data);
|
|
};
|
|
}
|
|
|
|
private Func<Response<string>> GetBaseUrl()
|
|
{
|
|
return () => new OkResponse<string>(_finder.Find());
|
|
}
|
|
}
|
|
}
|