|
@@ -5,64 +5,48 @@ using GenHTTP.Modules.IO.Streaming;
|
|
|
using GenHTTP.Modules.IO.Strings;
|
|
|
using InABox.Clients;
|
|
|
using InABox.Core;
|
|
|
+using InABox.Database;
|
|
|
+using InABox.Rpc;
|
|
|
+using InABox.Server;
|
|
|
using PRSServices;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
+using System.IO;
|
|
|
using System.Linq;
|
|
|
+using System.Reflection;
|
|
|
using System.Text;
|
|
|
using System.Threading.Tasks;
|
|
|
using RequestMethod = GenHTTP.Api.Protocol.RequestMethod;
|
|
|
|
|
|
namespace PRSServer;
|
|
|
|
|
|
-public class HTTPDatabaseProxyProperties : DatabaseProxyProperties
|
|
|
+
|
|
|
+public class HTTPDatabaseProxyHandlerProperties
|
|
|
{
|
|
|
- [IntegerEditor]
|
|
|
- [EditorSequence(2)]
|
|
|
- public int ListenPort { get; set; }
|
|
|
+ public HTTPDatabaseProxyProperties Properties { get; set; }
|
|
|
|
|
|
- [EditorSequence(3)]
|
|
|
- [FileNameEditor("Certificate Files (*.pfx)|*.pfx")]
|
|
|
- public string CertificateFile { get; set; }
|
|
|
+ public IRpcClientTransport ServerTransport { get; set; }
|
|
|
|
|
|
- public override ServerType Type() => ServerType.Proxy;
|
|
|
+ public HTTPDatabaseProxyHandlerProperties(HTTPDatabaseProxyProperties properties, IRpcClientTransport serverTransport)
|
|
|
+ {
|
|
|
+ Properties = properties;
|
|
|
+ ServerTransport = serverTransport;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-internal class HTTPDatabaseProxyHandler : Handler<HTTPDatabaseProxyProperties>
|
|
|
+internal class HTTPDatabaseProxyHandler : Handler<HTTPDatabaseProxyHandlerProperties>
|
|
|
{
|
|
|
- private readonly List<string> endpoints;
|
|
|
- private readonly List<string> operations;
|
|
|
-
|
|
|
- public RestHandler(IHandler parent)
|
|
|
- {
|
|
|
- Parent = parent;
|
|
|
+ private HTTPDatabaseProxyProperties Properties { get; set; }
|
|
|
|
|
|
- endpoints = new();
|
|
|
- operations = new();
|
|
|
-
|
|
|
- var types = CoreUtils.TypeList(
|
|
|
- x => x.IsSubclassOf(typeof(Entity))
|
|
|
- && x.GetInterfaces().Contains(typeof(IRemotable))
|
|
|
- );
|
|
|
- var DBTypes = DbFactory.SupportedTypes();
|
|
|
-
|
|
|
- foreach (var t in types)
|
|
|
- if (DBTypes.Contains(t.EntityName().Replace(".", "_")))
|
|
|
- {
|
|
|
- operations.Add(t.EntityName().Replace(".", "_"));
|
|
|
-
|
|
|
- endpoints.Add(string.Format("List{0}", t.Name));
|
|
|
- endpoints.Add(string.Format("Load{0}", t.Name));
|
|
|
- endpoints.Add(string.Format("Save{0}", t.Name));
|
|
|
- endpoints.Add(string.Format("MultiSave{0}", t.Name));
|
|
|
- endpoints.Add(string.Format("Delete{0}", t.Name));
|
|
|
- endpoints.Add(string.Format("MultiDelete{0}", t.Name));
|
|
|
- }
|
|
|
+ public IRpcClientTransport ServerTransport { get; set; }
|
|
|
|
|
|
- endpoints.Add("QueryMultiple");
|
|
|
+ public override void Init(HTTPDatabaseProxyHandlerProperties properties)
|
|
|
+ {
|
|
|
+ Properties = properties.Properties;
|
|
|
+ ServerTransport = properties.ServerTransport;
|
|
|
}
|
|
|
|
|
|
- private RequestData GetRequestData(IRequest request)
|
|
|
+ private static RequestData GetRequestData(IRequest request)
|
|
|
{
|
|
|
BinarySerializationSettings settings = BinarySerializationSettings.V1_0;
|
|
|
if (request.Query.TryGetValue("serializationVersion", out var versionString))
|
|
@@ -89,7 +73,7 @@ internal class HTTPDatabaseProxyHandler : Handler<HTTPDatabaseProxyProperties>
|
|
|
/// </summary>
|
|
|
/// <param name="request"></param>
|
|
|
/// <returns></returns>
|
|
|
- public ValueTask<IResponse?> HandleAsync(IRequest request)
|
|
|
+ public override ValueTask<IResponse?> HandleAsync(IRequest request)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
@@ -145,6 +129,51 @@ internal class HTTPDatabaseProxyHandler : Handler<HTTPDatabaseProxyProperties>
|
|
|
return new ValueTask<IResponse?>(request.Respond().Status(ResponseStatus.InternalServerError).Build());
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ private IResponseBuilder DoForward<TRequest, TResponse, TCommand, TParameters, TResult>(
|
|
|
+ IRequest request,
|
|
|
+ RequestData data,
|
|
|
+ Func<TRequest, TParameters> convertRequest,
|
|
|
+ Func<TRequest, TResult, TResponse> convertResponse
|
|
|
+ )
|
|
|
+ where TRequest : Request
|
|
|
+ where TResponse : Response, new()
|
|
|
+ where TCommand : IRpcCommand<TParameters,TResult>
|
|
|
+ where TParameters : IRpcCommandParameters, ISerializeBinary
|
|
|
+ where TResult : IRpcCommandResult, ISerializeBinary, new()
|
|
|
+ {
|
|
|
+ var requestObj = Deserialize<TRequest>(request.Content, data.RequestFormat, data.BinarySerializationSettings, true);
|
|
|
+
|
|
|
+ var internalMessage = new InternalServerMessage
|
|
|
+ {
|
|
|
+ Session = requestObj.Credentials.Session,
|
|
|
+ Payload = convertRequest(requestObj).WriteBinary(BinarySerializationSettings.Latest)
|
|
|
+ };
|
|
|
+
|
|
|
+ var serverResponse = ServerTransport.Send(typeof(TCommand).Name, internalMessage, checkErrors: false);
|
|
|
+
|
|
|
+ TResponse response;
|
|
|
+ if(serverResponse.Error == RpcError.NONE)
|
|
|
+ {
|
|
|
+ var result = Serialization.ReadBinary<TResult>(serverResponse.Payload, BinarySerializationSettings.Latest)
|
|
|
+ ?? throw new Exception($"Cannot Deserialize {typeof(TCommand).Name}");
|
|
|
+ response = convertResponse(requestObj, result);
|
|
|
+ response.Status = StatusCode.OK;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ response = new TResponse
|
|
|
+ {
|
|
|
+ Status = serverResponse.Error switch
|
|
|
+ {
|
|
|
+ RpcError.UNAUTHENTICATED => StatusCode.Unauthenticated,
|
|
|
+ _ => StatusCode.Error
|
|
|
+ },
|
|
|
+ };
|
|
|
+ response.Messages.Add(Encoding.UTF8.GetString(serverResponse.Payload));
|
|
|
+ }
|
|
|
+ return SerializeResponse(request, data.ResponseFormat, data.BinarySerializationSettings, response);
|
|
|
+ }
|
|
|
|
|
|
/// <summary>
|
|
|
/// Returns the Splash Logo and Color Scheme for this Database
|
|
@@ -154,27 +183,56 @@ internal class HTTPDatabaseProxyHandler : Handler<HTTPDatabaseProxyProperties>
|
|
|
private IResponseBuilder GetServerInfo(IRequest request)
|
|
|
{
|
|
|
var data = GetRequestData(request);
|
|
|
- var response = new InfoResponse(Client.Info());
|
|
|
- response.Status = StatusCode.OK;
|
|
|
- return SerializeResponse(request, data.ResponseFormat, data.BinarySerializationSettings, response);
|
|
|
+ return DoForward<InfoRequest, InfoResponse, RpcInfoCommand, RpcInfoParameters, RpcInfoResult>(
|
|
|
+ request, data,
|
|
|
+ x => new RpcInfoParameters(),
|
|
|
+ (r, x) => new InfoResponse
|
|
|
+ {
|
|
|
+ Info = x.Info ?? new DatabaseInfo()
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
#region Authentication
|
|
|
|
|
|
private IResponseBuilder Validate(IRequest request, RequestData data)
|
|
|
{
|
|
|
- var requestObj = Deserialize<ValidateRequest>(request.Content, data.RequestFormat, data.BinarySerializationSettings, true);
|
|
|
- var response = RestService.Validate(requestObj);
|
|
|
-
|
|
|
- return SerializeResponse(request, data.ResponseFormat, data.BinarySerializationSettings, response);
|
|
|
+ return DoForward<ValidateRequest, ValidateResponse, RpcValidateCommand, RpcValidateParameters, RpcValidateResult>(
|
|
|
+ request, data,
|
|
|
+ x => new RpcValidateParameters
|
|
|
+ {
|
|
|
+ UserID = x.UserID,
|
|
|
+ Password = x.Password,
|
|
|
+ PIN = x.PIN,
|
|
|
+ UsePIN = x.UsePIN,
|
|
|
+ SessionID = x.Credentials.Session,
|
|
|
+ Platform = x.Credentials.Platform,
|
|
|
+ Version = x.Credentials.Version,
|
|
|
+ },
|
|
|
+ (r, x) => new ValidateResponse
|
|
|
+ {
|
|
|
+ ValidationStatus = x.Status,
|
|
|
+ UserGuid = x.UserGuid,
|
|
|
+ UserID = x.UserID,
|
|
|
+ SecurityID = x.SecurityID,
|
|
|
+ Session = x.SessionID,
|
|
|
+ Recipient2FA = x.Recipient2FA,
|
|
|
+ PasswordExpiration = x.PasswordExpiration
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
private IResponseBuilder Check2FA(IRequest request, RequestData data)
|
|
|
{
|
|
|
- var requestObj = Deserialize<Check2FARequest>(request.Content, data.RequestFormat, data.BinarySerializationSettings, true);
|
|
|
- var response = RestService.Check2FA(requestObj);
|
|
|
-
|
|
|
- return SerializeResponse(request, data.ResponseFormat, data.BinarySerializationSettings, response);
|
|
|
+ return DoForward<Check2FARequest, Check2FAResponse, RpcCheck2FACommand, RpcCheck2FAParameters, RpcCheck2FAResult>(
|
|
|
+ request, data,
|
|
|
+ x => new RpcCheck2FAParameters
|
|
|
+ {
|
|
|
+ Code = x.Code,
|
|
|
+ SessionId = x.Credentials.Session
|
|
|
+ },
|
|
|
+ (r, x) => new Check2FAResponse
|
|
|
+ {
|
|
|
+ Valid = x.Valid
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
@@ -182,7 +240,7 @@ internal class HTTPDatabaseProxyHandler : Handler<HTTPDatabaseProxyProperties>
|
|
|
#region Database
|
|
|
|
|
|
private static MethodInfo GetMethod(string name) =>
|
|
|
- typeof(RestHandler).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static)
|
|
|
+ typeof(HTTPDatabaseProxyHandler).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance)
|
|
|
?? throw new Exception($"Invalid method '{name}'");
|
|
|
|
|
|
private static readonly List<Tuple<string, MethodInfo>> methodMap = new()
|
|
@@ -207,36 +265,148 @@ internal class HTTPDatabaseProxyHandler : Handler<HTTPDatabaseProxyProperties>
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private static QueryResponse<T> List<T>(IRequest request, RequestData data) where T : Entity, new()
|
|
|
+ private IResponseBuilder List<T>(IRequest request, RequestData data) where T : Entity, new()
|
|
|
{
|
|
|
- var requestObject = Deserialize<QueryRequest<T>>(request.Content, data.RequestFormat, data.BinarySerializationSettings, true);
|
|
|
- return RestService<T>.List(requestObject);
|
|
|
+ return DoForward<QueryRequest<T>, QueryResponse<T>, RpcQueryCommand, RpcQueryParameters, RpcQueryResult>(
|
|
|
+ request, data,
|
|
|
+ x => new RpcQueryParameters
|
|
|
+ {
|
|
|
+ Queries = new[]
|
|
|
+ {
|
|
|
+ new RpcQueryDefinition
|
|
|
+ {
|
|
|
+ Key = typeof(T).Name,
|
|
|
+ Type = typeof(T),
|
|
|
+ Filter = x.Filter,
|
|
|
+ Columns = x.Columns,
|
|
|
+ Sort = x.Sort
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ (r, x) => new QueryResponse<T>
|
|
|
+ {
|
|
|
+ Items = x.Tables[0].Table
|
|
|
+ });
|
|
|
}
|
|
|
- private static SaveResponse<T> Save<T>(IRequest request, RequestData data) where T : Entity, new()
|
|
|
+ private IResponseBuilder Save<T>(IRequest request, RequestData data) where T : Entity, new()
|
|
|
{
|
|
|
- var requestObject = Deserialize<SaveRequest<T>>(request.Content, data.RequestFormat, data.BinarySerializationSettings, true);
|
|
|
- return RestService<T>.Save(requestObject);
|
|
|
+ return DoForward<SaveRequest<T>, SaveResponse<T>, RpcSaveCommand, RpcSaveParameters, RpcSaveResult>(
|
|
|
+ request, data,
|
|
|
+ x => new RpcSaveParameters
|
|
|
+ {
|
|
|
+ AuditNote = x.AuditNote,
|
|
|
+ Items = new[] { x.Item },
|
|
|
+ Type = typeof(T)
|
|
|
+ },
|
|
|
+ (r, x) =>
|
|
|
+ {
|
|
|
+ if (r.ReturnOnlyChanged)
|
|
|
+ {
|
|
|
+ return new SaveResponse<T>
|
|
|
+ {
|
|
|
+ ChangedValues = x.Deltas[0]
|
|
|
+ };
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ var deltas = x.Deltas[0];
|
|
|
+ r.Item.SetObserving(false);
|
|
|
+ foreach (var (key, value) in deltas)
|
|
|
+ {
|
|
|
+ if (CoreUtils.TryGetProperty<T>(key, out var property))
|
|
|
+ CoreUtils.SetPropertyValue(deltas, key, CoreUtils.ChangeType(value, property.PropertyType));
|
|
|
+ }
|
|
|
+ r.Item.CommitChanges();
|
|
|
+ r.Item.SetObserving(true);
|
|
|
+ return new SaveResponse<T>
|
|
|
+ {
|
|
|
+ Item = r.Item
|
|
|
+ };
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
- private static DeleteResponse<T> Delete<T>(IRequest request, RequestData data) where T : Entity, new()
|
|
|
+ private IResponseBuilder Delete<T>(IRequest request, RequestData data) where T : Entity, new()
|
|
|
{
|
|
|
- var requestObject = Deserialize<DeleteRequest<T>>(request.Content, data.RequestFormat, data.BinarySerializationSettings, true);
|
|
|
- return RestService<T>.Delete(requestObject);
|
|
|
+ return DoForward<DeleteRequest<T>, DeleteResponse<T>, RpcDeleteCommand, RpcDeleteParameters, RpcDeleteResult>(
|
|
|
+ request, data,
|
|
|
+ x => new RpcDeleteParameters
|
|
|
+ {
|
|
|
+ AuditNote = x.AuditNote,
|
|
|
+ IDs = new[] { x.Item.ID },
|
|
|
+ Type = typeof(T)
|
|
|
+ },
|
|
|
+ (r, x) => new DeleteResponse<T>());
|
|
|
}
|
|
|
- private static MultiSaveResponse<T> MultiSave<T>(IRequest request, RequestData data) where T : Entity, new()
|
|
|
+ private IResponseBuilder MultiSave<T>(IRequest request, RequestData data) where T : Entity, new()
|
|
|
{
|
|
|
- var requestObject = Deserialize<MultiSaveRequest<T>>(request.Content, data.RequestFormat, data.BinarySerializationSettings, true);
|
|
|
- return RestService<T>.MultiSave(requestObject);
|
|
|
+ return DoForward<MultiSaveRequest<T>, MultiSaveResponse<T>, RpcSaveCommand, RpcSaveParameters, RpcSaveResult>(
|
|
|
+ request, data,
|
|
|
+ x => new RpcSaveParameters
|
|
|
+ {
|
|
|
+ AuditNote = x.AuditNote,
|
|
|
+ Items = x.Items,
|
|
|
+ Type = typeof(T)
|
|
|
+ },
|
|
|
+ (r, x) =>
|
|
|
+ {
|
|
|
+ if (r.ReturnOnlyChanged)
|
|
|
+ {
|
|
|
+ return new MultiSaveResponse<T>
|
|
|
+ {
|
|
|
+ ChangedValues = x.Deltas.ToList()
|
|
|
+ };
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ for (int i = 0; i < x.Deltas.Length; i++)
|
|
|
+ {
|
|
|
+ r.Items[i].SetObserving(false);
|
|
|
+ foreach (var (key, value) in x.Deltas[i])
|
|
|
+ {
|
|
|
+ if (CoreUtils.TryGetProperty<T>(key, out var property))
|
|
|
+ CoreUtils.SetPropertyValue(r.Items[i], key, CoreUtils.ChangeType(value, property.PropertyType));
|
|
|
+ }
|
|
|
+ r.Items[i].CommitChanges();
|
|
|
+ r.Items[i].SetObserving(true);
|
|
|
+ }
|
|
|
+ return new MultiSaveResponse<T>
|
|
|
+ {
|
|
|
+ Items = r.Items
|
|
|
+ };
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
- private static MultiDeleteResponse<T> MultiDelete<T>(IRequest request, RequestData data) where T : Entity, new()
|
|
|
+ private IResponseBuilder MultiDelete<T>(IRequest request, RequestData data) where T : Entity, new()
|
|
|
{
|
|
|
- var requestObject = Deserialize<MultiDeleteRequest<T>>(request.Content, data.RequestFormat, data.BinarySerializationSettings, true);
|
|
|
- return RestService<T>.MultiDelete(requestObject);
|
|
|
+ return DoForward<MultiDeleteRequest<T>, MultiDeleteResponse<T>, RpcDeleteCommand, RpcDeleteParameters, RpcDeleteResult>(
|
|
|
+ request, data,
|
|
|
+ x => new RpcDeleteParameters
|
|
|
+ {
|
|
|
+ AuditNote = x.AuditNote,
|
|
|
+ IDs = x.Items.Select(x => x.ID).ToArray(),
|
|
|
+ Type = typeof(T)
|
|
|
+ },
|
|
|
+ (r, x) => new MultiDeleteResponse<T>());
|
|
|
}
|
|
|
- private static MultiQueryResponse QueryMultiple(IRequest request, RequestData data)
|
|
|
+ private IResponseBuilder QueryMultiple(IRequest request, RequestData data)
|
|
|
{
|
|
|
- var requestObject = Deserialize<MultiQueryRequest>(request.Content, data.RequestFormat, data.BinarySerializationSettings, true);
|
|
|
-
|
|
|
- return RestService.QueryMultiple(requestObject, false);
|
|
|
+ return DoForward<MultiQueryRequest, MultiQueryResponse, RpcQueryCommand, RpcQueryParameters, RpcQueryResult>(
|
|
|
+ request, data,
|
|
|
+ x => new RpcQueryParameters
|
|
|
+ {
|
|
|
+ Queries = x.Queries.Select(x => new RpcQueryDefinition
|
|
|
+ {
|
|
|
+ Key = x.Key,
|
|
|
+ Type = CoreUtils.GetEntity(x.Value.Type),
|
|
|
+ Filter = x.Value.Filter,
|
|
|
+ Columns = x.Value.Columns,
|
|
|
+ Sort = x.Value.Sort
|
|
|
+ }).ToArray()
|
|
|
+ },
|
|
|
+ (r, x) => new MultiQueryResponse
|
|
|
+ {
|
|
|
+ Tables = x.Tables.ToDictionary(x => x.Key, x => x.Table)
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
private static T Deserialize<T>(Stream? stream, SerializationFormat requestFormat, BinarySerializationSettings binarySettings, bool strict = false)
|
|
@@ -255,7 +425,7 @@ internal class HTTPDatabaseProxyHandler : Handler<HTTPDatabaseProxyProperties>
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private IResponseBuilder SerializeResponse(IRequest request, SerializationFormat responseFormat, BinarySerializationSettings binarySettings, Response? result)
|
|
|
+ private static IResponseBuilder SerializeResponse(IRequest request, SerializationFormat responseFormat, BinarySerializationSettings binarySettings, Response? result)
|
|
|
{
|
|
|
if (responseFormat == SerializationFormat.Binary && result is ISerializeBinary binary)
|
|
|
{
|
|
@@ -289,7 +459,7 @@ internal class HTTPDatabaseProxyHandler : Handler<HTTPDatabaseProxyProperties>
|
|
|
if (endpoint.StartsWith("QueryMultiple"))
|
|
|
{
|
|
|
var result = QueryMultiple(request, requestData);
|
|
|
- return new ValueTask<IResponse?>(SerializeResponse(request, requestData.ResponseFormat, requestData.BinarySerializationSettings, result).Build());
|
|
|
+ return new ValueTask<IResponse?>(result.Build());
|
|
|
}
|
|
|
|
|
|
foreach (var (name, method) in methodMap)
|
|
@@ -307,9 +477,9 @@ internal class HTTPDatabaseProxyHandler : Handler<HTTPDatabaseProxyProperties>
|
|
|
}
|
|
|
|
|
|
var resolvedMethod = method.MakeGenericMethod(entityType);
|
|
|
- var result = resolvedMethod.Invoke(null, new object[] { request, requestData }) as Response;
|
|
|
+ var result = (resolvedMethod.Invoke(null, new object[] { request, requestData }) as IResponseBuilder)!;
|
|
|
|
|
|
- return new ValueTask<IResponse?>(SerializeResponse(request, requestData.ResponseFormat, requestData.BinarySerializationSettings, result).Build());
|
|
|
+ return new ValueTask<IResponse?>(result.Build());
|
|
|
}
|
|
|
|
|
|
Logger.Send(LogType.Error, request.Client.IPAddress.ToString(),
|
|
@@ -336,7 +506,6 @@ internal class HTTPDatabaseProxyHandler : Handler<HTTPDatabaseProxyProperties>
|
|
|
|
|
|
#region Installer
|
|
|
|
|
|
-
|
|
|
private IResponseBuilder GetUpdateFile(IRequest request)
|
|
|
{
|
|
|
var endpoint = request.Target.Current;
|
|
@@ -378,17 +547,15 @@ internal class HTTPDatabaseProxyHandler : Handler<HTTPDatabaseProxyProperties>
|
|
|
|
|
|
internal class HTTPDatabaseProxyEngine : DatabaseProxyEngine<HTTPDatabaseProxyProperties>
|
|
|
{
|
|
|
- private Listener<HTTPDatabaseProxyHandler, HTTPDatabaseProxyProperties>? Listener;
|
|
|
+ private Listener<HTTPDatabaseProxyHandler, HTTPDatabaseProxyHandlerProperties>? Listener;
|
|
|
|
|
|
protected override void RunProxy()
|
|
|
{
|
|
|
- Logger.Send(LogType.Information, "", "Registering Classes");
|
|
|
-
|
|
|
Logger.Send(LogType.Information, "", "Starting Listener on port " + Properties.ListenPort);
|
|
|
|
|
|
try
|
|
|
{
|
|
|
- Listener = new Listener<HTTPDatabaseProxyHandler, HTTPDatabaseProxyProperties>(Properties);
|
|
|
+ Listener = new Listener<HTTPDatabaseProxyHandler, HTTPDatabaseProxyHandlerProperties>(new HTTPDatabaseProxyHandlerProperties(Properties, ServerTransport));
|
|
|
Listener.InitHTTPS((ushort)Properties.ListenPort, CertificateFileName());
|
|
|
Listener.Start();
|
|
|
}
|