2021-02-26 10:06:15 +03:00
// SoftEther VPN Server JSON-RPC Stub code for C#
2019-05-28 05:42:26 +03:00
//
// JsonRpc.cs - JSON-RPC Client Utility Functions
//
2019-07-10 08:37:30 +03:00
// Automatically generated at 2019-07-10 14:36:11 by vpnserver-jsonrpc-codegen
2019-05-28 05:42:26 +03:00
//
// Licensed under the Apache License 2.0
// Copyright (c) 2014-2019 SoftEther VPN Project
using System ;
using System.IO ;
using System.Net.Security ;
using System.Net.Http ;
using System.Collections.Generic ;
using System.Text ;
using System.Security.Cryptography.X509Certificates ;
using System.Threading.Tasks ;
using Newtonsoft.Json ;
namespace SoftEther.JsonRpc
{
/// <summary>
/// Internal utility class
/// </summary>
static class ClientUtil
{
public const int DefaultMaxDepth = 8 ;
public static string NonNull ( this string s ) { if ( s = = null ) return "" ; else return s ; }
public static bool IsEmpty ( this string str )
{
if ( str = = null | | str . Trim ( ) . Length = = 0 )
return true ;
else
return false ;
}
public static bool IsFilled ( this string str ) = > ! IsEmpty ( str ) ;
public static string ObjectToJson ( this object obj , bool include_null = false , bool escape_html = false , int? max_depth = ClientUtil . DefaultMaxDepth , bool compact = false , bool reference_handling = false ) = > ClientUtil . Serialize ( obj , include_null , escape_html , max_depth , compact , reference_handling ) ;
public static T JsonToObject < T > ( this string str , bool include_null = false , int? max_depth = ClientUtil . DefaultMaxDepth ) = > ClientUtil . Deserialize < T > ( str , include_null , max_depth ) ;
public static object JsonToObject ( this string str , Type type , bool include_null = false , int? max_depth = ClientUtil . DefaultMaxDepth ) = > ClientUtil . Deserialize ( str , type , include_null , max_depth ) ;
public static string Serialize ( object obj , bool include_null = false , bool escape_html = false , int? max_depth = ClientUtil . DefaultMaxDepth , bool compact = false , bool reference_handling = false )
{
JsonSerializerSettings setting = new JsonSerializerSettings ( )
{
MaxDepth = max_depth ,
NullValueHandling = include_null ? NullValueHandling . Include : NullValueHandling . Ignore ,
ReferenceLoopHandling = ReferenceLoopHandling . Error ,
PreserveReferencesHandling = reference_handling ? PreserveReferencesHandling . All : PreserveReferencesHandling . None ,
StringEscapeHandling = escape_html ? StringEscapeHandling . EscapeHtml : StringEscapeHandling . Default ,
} ;
return JsonConvert . SerializeObject ( obj , compact ? Formatting . None : Formatting . Indented , setting ) ;
}
public static T Deserialize < T > ( string str , bool include_null = false , int? max_depth = ClientUtil . DefaultMaxDepth )
= > ( T ) Deserialize ( str , typeof ( T ) , include_null , max_depth ) ;
public static object Deserialize ( string str , Type type , bool include_null = false , int? max_depth = ClientUtil . DefaultMaxDepth )
{
JsonSerializerSettings setting = new JsonSerializerSettings ( )
{
MaxDepth = max_depth ,
NullValueHandling = include_null ? NullValueHandling . Include : NullValueHandling . Ignore ,
ObjectCreationHandling = ObjectCreationHandling . Replace ,
ReferenceLoopHandling = ReferenceLoopHandling . Error ,
} ;
return JsonConvert . DeserializeObject ( str , type , setting ) ;
}
public static void Print ( this object o )
{
string str = o . ObjectToJson ( ) ;
if ( o is string ) str = ( string ) o ;
Console . WriteLine ( str ) ;
}
}
/// <summary>
/// JSON-RPC exception class
/// </summary>
class JsonRpcException : Exception
{
public JsonRpcError RpcError { get ; }
public JsonRpcException ( JsonRpcError err )
: base ( $"Code={err.Code}, Message={err.Message.NonNull()}" +
( err = = null | | err . Data = = null ? "" : $", Data={err.Data.ObjectToJson(compact: true)}" ) )
{
this . RpcError = err ;
}
}
/// <summary>
/// JSON-RPC request class. See https://www.jsonrpc.org/specification
/// </summary>
class JsonRpcRequest
{
[JsonProperty("jsonrpc", Order = 1)]
public string Version { get ; set ; } = "2.0" ;
[JsonProperty("id", Order = 2)]
public string Id { get ; set ; } = null ;
[JsonProperty("method", Order = 3)]
public string Method { get ; set ; } = "" ;
[JsonProperty("params", Order = 4)]
public object Params { get ; set ; } = null ;
public JsonRpcRequest ( ) { }
public JsonRpcRequest ( string method , object param , string id )
{
this . Method = method ;
this . Params = param ;
this . Id = id ;
}
}
/// <summary>
/// JSON-RPC response class with generics
/// </summary>
/// <typeparam name="TResult"></typeparam>
class JsonRpcResponse < TResult >
{
[JsonProperty("jsonrpc", Order = 1)]
public virtual string Version { get ; set ; } = "2.0" ;
[JsonProperty("id", NullValueHandling = NullValueHandling.Include, Order = 2)]
public virtual string Id { get ; set ; } = null ;
[JsonProperty("result", Order = 3)]
public virtual TResult Result { get ; set ; } = default ( TResult ) ;
[JsonProperty("error", Order = 4)]
public virtual JsonRpcError Error { get ; set ; } = null ;
[JsonIgnore]
public virtual bool IsError = > this . Error ! = null ;
[JsonIgnore]
public virtual bool IsOk = > ! IsError ;
public virtual void ThrowIfError ( )
{
if ( this . IsError ) throw new JsonRpcException ( this . Error ) ;
}
public override string ToString ( )
{
return this . ObjectToJson ( compact : true ) ;
}
}
/// <summary>
/// JSON-RPC error class. See https://www.jsonrpc.org/specification
/// </summary>
class JsonRpcError
{
public JsonRpcError ( ) { }
public JsonRpcError ( int code , string message , object data = null )
{
this . Code = code ;
this . Message = message . NonNull ( ) ;
if ( this . Message . IsEmpty ( ) ) this . Message = $"JSON-RPC Error {code}" ;
this . Data = data ;
}
[JsonProperty("code")]
public int Code { get ; set ; } = 0 ;
[JsonProperty("message")]
public string Message { get ; set ; } = null ;
[JsonProperty("data")]
public object Data { get ; set ; } = null ;
}
/// <summary>
/// JSON-RPC client. See https://www.jsonrpc.org/specification
/// </summary>
class JsonRpcClient
{
HttpClientHandler client_handler ;
HttpClient client ;
public const int DefaultTimeoutMsecs = 60 * 1000 ;
public int TimeoutMsecs { get = > ( int ) client . Timeout . TotalMilliseconds ; set = > client . Timeout = new TimeSpan ( 0 , 0 , 0 , 0 , value ) ; }
public Dictionary < string , string > HttpHeaders { get ; } = new Dictionary < string , string > ( ) ;
string base_url ;
/// <summary>
/// JSON-RPC client class constructor
/// </summary>
/// <param name="url">The URL</param>
/// <param name="cert_check_proc">The SSL certificate validation callback</param>
public JsonRpcClient ( string url , Func < HttpRequestMessage , X509Certificate2 , X509Chain , SslPolicyErrors , bool > cert_check_proc = null )
{
if ( cert_check_proc = = null ) cert_check_proc = ( message , cert , chain , errors ) = > true ;
client_handler = new HttpClientHandler ( ) ;
this . client_handler . AllowAutoRedirect = true ;
this . client_handler . MaxAutomaticRedirections = 10 ;
client_handler . ServerCertificateCustomValidationCallback = cert_check_proc ;
client = new HttpClient ( client_handler , true ) ;
//Console.WriteLine("new HttpClient(client_handler, true);");
this . base_url = url ;
this . TimeoutMsecs = DefaultTimeoutMsecs ;
}
/// <summary>
/// Call a single RPC call (without error check). You can wait for the response with Task<string> or await statement.
/// </summary>
/// <param name="method_name">The name of RPC method</param>
/// <param name="param">The parameters</param>
public async Task < string > CallInternalAsync ( string method_name , object param )
{
string id = DateTime . Now . Ticks . ToString ( ) ;
JsonRpcRequest req = new JsonRpcRequest ( method_name , param , id ) ;
string req_string = req . ObjectToJson ( ) ;
//Console.WriteLine($"req: {req_string}");
HttpContent content = new StringContent ( req_string , Encoding . UTF8 , "application/json" ) ;
foreach ( string key in this . HttpHeaders . Keys )
{
string value = this . HttpHeaders [ key ] ;
content . Headers . Add ( key , value ) ;
}
HttpResponseMessage response = await this . client . PostAsync ( base_url , content ) ;
Stream responseStream = await response . Content . ReadAsStreamAsync ( ) ;
if ( ! response . IsSuccessStatusCode )
{
using ( StreamReader streamReader = new StreamReader ( responseStream ) )
{
throw new Exception ( $"Error: {response.StatusCode}: {await streamReader.ReadToEndAsync()}" ) ;
}
}
string ret_string ;
using ( StreamReader streamReader = new StreamReader ( responseStream ) )
{
ret_string = await streamReader . ReadToEndAsync ( ) ;
}
//Console.WriteLine($"ret: {ret_string}");
return ret_string ;
}
/// <summary>
/// Call a single RPC call (with error check). You can wait for the response with Promise<TResult> or await statement. In the case of error, it will be thrown.
/// </summary>
/// <param name="method_name">The name of RPC method</param>
/// <param name="param">The parameters</param>
public async Task < TResult > CallAsync < TResult > ( string method_name , object param )
{
string ret_string = await CallInternalAsync ( method_name , param ) ;
JsonRpcResponse < TResult > ret = ret_string . JsonToObject < JsonRpcResponse < TResult > > ( ) ;
ret . ThrowIfError ( ) ;
return ret . Result ;
}
}
}