2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-06-26 21:13:13 +00:00
This commit is contained in:
2019-12-02 03:16:19 +03:00
parent ba1fc9c18e
commit 66fd62c449
122 changed files with 443 additions and 409 deletions

View File

@ -1,52 +0,0 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Core
{
public class AsyncAwaiter<T> : INotifyCompletion
{
Action callback = null;
AsyncException exception = null;
T result;
public AsyncAwaiter(AsyncReply<T> reply)
{
reply.Then(x =>
{
this.IsCompleted = true;
this.result = x;
this.callback?.Invoke();
}).Error(x =>
{
exception = x;
this.IsCompleted = true;
this.callback?.Invoke();
});
}
public T GetResult()
{
if (exception != null)
throw exception;
return result;
}
public bool IsCompleted { get; private set; }
public void OnCompleted(Action continuation)
{
if (IsCompleted)
continuation?.Invoke();
else
// Continue....
callback = continuation;
}
}
}

View File

@ -1,105 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Core
{
public class AsyncBag<T>: AsyncReply<T[]>
{
//Dictionary<AsyncReply, T> results = new Dictionary<AsyncReply, T>();
List<IAsyncReply<T>> replies = new List<IAsyncReply<T>>();
List<T> results = new List<T>();
int count = 0;
bool sealedBag = false;
/*
public AsyncBag<T> Then(Action<T[]> callback)
{
base.Then(new Action<object>(o => callback((T[])o)));
return this;
}
*/
public void Seal()
{
if (sealedBag)
return;
sealedBag = true;
if (results.Count == 0)
Trigger(new T[0]);
for (var i = 0; i < results.Count; i++)
//foreach(var reply in results.Keys)
{
var k = replies[i];// results.Keys.ElementAt(i);
var index = i;
k.Then((r) =>
{
results[index] = (T)r;
count++;
if (count == results.Count)
Trigger(results.ToArray());
});
}
}
public void Add(IAsyncReply<T> reply)
{
if (!sealedBag)
{
results.Add(default(T));
replies.Add(reply);
}
//results.Add(reply, default(T));
}
public void AddBag(AsyncBag<T> bag)
{
foreach (var r in bag.replies)
Add(r);
}
public AsyncBag()
{
}
public AsyncBag(T[] results)
{
resultReady = true;
base.result = results;
}
}
}

View File

@ -1,52 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Core
{
public class AsyncException: Exception
{
public readonly ErrorType Type;
public readonly ExceptionCode Code;
public AsyncException(ErrorType type, ushort code, string message)
: base(type == ErrorType.Management ? ((ExceptionCode)code).ToString() : message)
{
this.Type = type;
this.Code = (ExceptionCode)code;
}
public override string ToString()
{
return Code.ToString() + ": " + Message;
}
}
}

View File

@ -1,83 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Core
{
public class AsyncQueue<T> : AsyncReply<T>
{
List<AsyncReply<T>> list = new List<AsyncReply<T>>();
//Action<T> callback;
object queueLock = new object();
//public AsyncQueue<T> Then(Action<T> callback)
//{
// base.Then(new Action<object>(o => callback((T)o)));
//return this;
//}
public void Add(AsyncReply<T> reply)
{
lock (queueLock)
list.Add(reply);
resultReady = false;
reply.Then(processQueue);
}
public void Remove(AsyncReply<T> reply)
{
lock (queueLock)
list.Remove(reply);
processQueue(default(T));
}
void processQueue(T o)
{
lock (queueLock)
for (var i = 0; i < list.Count; i++)
if (list[i].Ready)
{
Trigger(list[i].Result);
list.RemoveAt(i);
i--;
}
else
break;
resultReady = (list.Count == 0);
}
public AsyncQueue()
{
}
}
}

View File

@ -1,43 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Esiur.Resource;
using System.Reflection;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Diagnostics;
namespace Esiur.Core
{
[AsyncMethodBuilder(typeof(AsyncReplyBuilder))]
public class AsyncReply : AsyncReply<object>
{
}
}

View File

@ -1,70 +0,0 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
namespace Esiur.Core
{
public class AsyncReplyBuilder
{
AsyncReply reply;
AsyncReplyBuilder(AsyncReply reply)
{
this.reply = reply;
}
public static AsyncReplyBuilder Create()
{
return new AsyncReplyBuilder(new AsyncReply());
}
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
Console.WriteLine("SetStateMachine");
}
public void SetException(Exception exception)
{
reply.TriggerError(exception);
}
public void SetResult()
{
reply.Trigger(null);
}
public void AwaitOnCompleted<TAwaiter, TStateMachine>(
ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
Console.WriteLine("AwaitOnCompleted");
}
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
Console.WriteLine("AwaitUnsafeOnCompleted");
}
public AsyncReply Task
{
get
{
return reply;
}
}
}
}

View File

@ -1,69 +0,0 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
namespace Esiur.Core
{
public class AsyncReplyBuilder<T>
{
AsyncReply<T> reply;
AsyncReplyBuilder(AsyncReply<T> reply)
{
this.reply = reply;
}
public static AsyncReplyBuilder<T> Create()
{
return new AsyncReplyBuilder<T>(new AsyncReply<T>());
}
public void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
stateMachine.MoveNext();
}
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
Console.WriteLine("SetStateMachine");
}
public void SetException(Exception exception)
{
reply.TriggerError(exception);
}
public void SetResult(T result)
{
reply.Trigger(result);
}
public void AwaitOnCompleted<TAwaiter, TStateMachine>(
ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
Console.WriteLine("AwaitOnCompleted");
}
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
Console.WriteLine("AwaitUnsafeOnCompleted");
}
public AsyncReply<T> Task
{
get {
return reply;
}
}
}
}

View File

@ -1,337 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Esiur.Resource;
using System.Reflection;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Diagnostics;
namespace Esiur.Core
{
[AsyncMethodBuilder(typeof(AsyncReplyBuilder<>))]
public class AsyncReply<T> : IAsyncReply<T>
{
public bool Debug = false;
protected List<Action<T>> callbacks = new List<Action<T>>();
protected T result;
protected List<Action<AsyncException>> errorCallbacks = new List<Action<AsyncException>>();
protected List<Action<ProgressType, int, int>> progressCallbacks = new List<Action<ProgressType, int, int>>();
protected List<Action<T>> chunkCallbacks = new List<Action<T>>();
//List<AsyncAwaiter> awaiters = new List<AsyncAwaiter>();
object asyncLock = new object();
//public Timer timeout;// = new Timer()
protected bool resultReady = false;
AsyncException exception;
// StackTrace trace;
AutoResetEvent mutex = new AutoResetEvent(false);
public static int MaxId;
public int Id;
public bool Ready
{
get { return resultReady; }
}
public T Wait()
{
if (resultReady)
return result;
if (Debug)
Console.WriteLine($"AsyncReply: {Id} Wait");
//mutex = new AutoResetEvent(false);
mutex.WaitOne();
if (Debug)
Console.WriteLine($"AsyncReply: {Id} Wait ended");
return result;
}
public object Result
{
get { return result; }
}
public IAsyncReply<T> Then(Action<T> callback)
{
//lock (callbacksLock)
//{
lock (asyncLock)
{
// trace = new StackTrace();
if (resultReady)
{
if (Debug)
Console.WriteLine($"AsyncReply: {Id} Then ready");
callback(result);
return this;
}
//timeout = new Timer(x =>
//{
// // Get calling method name
// Console.WriteLine(trace.GetFrame(1).GetMethod().Name);
// var tr = String.Join("\r\n", trace.GetFrames().Select(f => f.GetMethod().Name));
// timeout.Dispose();
// tr = trace.ToString();
// throw new Exception("Request timeout " + Id);
//}, null, 15000, 0);
if (Debug)
Console.WriteLine($"AsyncReply: {Id} Then pending");
callbacks.Add(callback);
return this;
}
}
public IAsyncReply<T> Error(Action<AsyncException> callback)
{
// lock (callbacksLock)
// {
errorCallbacks.Add(callback);
if (exception != null)
callback(exception);
return this;
//}
}
public IAsyncReply<T> Progress(Action<ProgressType, int, int> callback)
{
//lock (callbacksLock)
//{
progressCallbacks.Add(callback);
return this;
//}
}
public IAsyncReply<T> Chunk(Action<T> callback)
{
// lock (callbacksLock)
// {
chunkCallbacks.Add(callback);
return this;
// }
}
public void Trigger(object result)
{
lock (asyncLock)
{
//timeout?.Dispose();
if (Debug)
Console.WriteLine($"AsyncReply: {Id} Trigger");
if (resultReady)
return;
this.result = (T)result;
resultReady = true;
//if (mutex != null)
mutex.Set();
foreach (var cb in callbacks)
cb((T)result);
if (Debug)
Console.WriteLine($"AsyncReply: {Id} Trigger ended");
}
}
public void TriggerError(Exception exception)
{
//timeout?.Dispose();
if (resultReady)
return;
if (exception is AsyncException)
this.exception = exception as AsyncException;
else
this.exception = new AsyncException(ErrorType.Management, 0, exception.Message);
// lock (callbacksLock)
// {
foreach (var cb in errorCallbacks)
cb(this.exception);
// }
mutex?.Set();
}
public void TriggerProgress(ProgressType type, int value, int max)
{
//timeout?.Dispose();
if (resultReady)
return;
//lock (callbacksLock)
//{
foreach (var cb in progressCallbacks)
cb(type, value, max);
//}
}
public void TriggerChunk(object value)
{
//timeout?.Dispose();
if (resultReady)
return;
//lock (callbacksLock)
//{
foreach (var cb in chunkCallbacks)
cb((T)value);
//}
}
public AsyncAwaiter<T> GetAwaiter()
{
return new AsyncAwaiter<T>(this);
}
public AsyncReply()
{
// this.Debug = true;
Id = MaxId++;
}
public AsyncReply(T result)
{
// this.Debug = true;
resultReady = true;
this.result = result;
Id = MaxId++;
}
/*
public AsyncReply<T> Then(Action<T> callback)
{
base.Then(new Action<object>(o => callback((T)o)));
return this;
}
public void Trigger(T result)
{
Trigger((object)result);
}
public Task<bool> MoveNext(CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public void Dispose()
{
}
public AsyncReply()
{
}
public new Task<T> Task
{
get
{
return base.Task.ContinueWith<T>((t) =>
{
#if NETSTANDARD
return (T)t.GetType().GetTypeInfo().GetProperty("Result").GetValue(t);
#else
return (T)t.GetType().GetProperty("Result").GetValue(t);
#endif
});
}
}
public T Current => throw new NotImplementedException();
public AsyncReply(T result)
: base(result)
{
}
*/
}
}

View File

@ -1,185 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Core
{
public class AsyncReply
{
protected List<Action<object>> callbacks = new List<Action<object>>();
protected object result;
protected List<Action<AsyncException>> errorCallbacks = new List<Action<AsyncException>>();
protected List<Action<ProgressType, int, int>> progressCallbacks = new List<Action<ProgressType, int, int>>();
protected List<Action<object>> chunkCallbacks = new List<Action<object>>();
object callbacksLock = new object();
protected bool resultReady = false;
AsyncException exception;
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
public bool Ready
{
get { return resultReady; }
}
public object Result
{
get { return result; }
}
public AsyncReply Then(Action<object> callback)
{
callbacks.Add(callback);
if (resultReady)
callback(result);
return this;
}
public AsyncReply Error(Action<AsyncException> callback)
{
errorCallbacks.Add(callback);
if (exception != null)
{
callback(exception);
tcs.SetException(exception);
}
return this;
}
public AsyncReply Progress(Action<ProgressType, int, int> callback)
{
progressCallbacks.Add(callback);
return this;
}
public AsyncReply Chunk(Action<object> callback)
{
chunkCallbacks.Add(callback);
return this;
}
public void Trigger(object result)
{
lock (callbacksLock)
{
if (resultReady)
return;
this.result = result;
resultReady = true;
foreach (var cb in callbacks)
cb(result);
tcs.TrySetResult(result);
}
}
public void TriggerError(AsyncException exception)
{
if (resultReady)
return;
this.exception = exception;
lock (callbacksLock)
{
foreach (var cb in errorCallbacks)
cb(exception);
}
tcs.TrySetException(exception);
}
public void TriggerProgress(ProgressType type, int value, int max)
{
if (resultReady)
return;
lock (callbacksLock)
{
foreach (var cb in progressCallbacks)
cb(type, value, max);
}
}
public void TriggerChunk(object value)
{
if (resultReady)
return;
lock (callbacksLock)
{
foreach (var cb in chunkCallbacks)
cb(value);
}
}
public Task Task
{
get
{
return tcs.Task;
}
}
public AsyncReply()
{
}
public AsyncReply(object result)
{
resultReady = true;
tcs.SetResult(result);
this.result = result;
}
}
}

View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Core
{
public enum ErrorType
{
Management,
Exception
}
}

View File

@ -1,37 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Core
{
public enum ExceptionCode : ushort
{
HostNotReachable,
AccessDenied,
ResourceNotFound,
AttachDenied,
InvalidMethod,
InvokeDenied,
CreateDenied,
AddParentDenied,
AddChildDenied,
ViewAttributeDenied,
UpdateAttributeDenied,
StoreNotFound,
ParentNotFound,
ChildNotFound,
ResourceIsNotStore,
DeleteDenied,
DeleteFailed,
UpdateAttributeFailed,
GetAttributesFailed,
ClearAttributesFailed,
TemplateNotFound,
RenameDenied,
ClassNotFound,
MethodNotFound,
PropertyNotFound,
SetPropertyDenied,
ReadOnlyProperty
}
}

View File

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
namespace Esiur.Core
{
public interface IAsyncReply<out T>//IAsyncEnumerator<T>
{
IAsyncReply<T> Then(Action<T> callback);
IAsyncReply<T> Error(Action<AsyncException> callback);
IAsyncReply<T> Progress(Action<ProgressType, int, int> callback);
IAsyncReply<T> Chunk(Action<T> callback);
void Trigger(object result);
void TriggerError(Exception exception);
void TriggerProgress(ProgressType type, int value, int max);
void TriggerChunk(object value);
T Wait();
}
}

View File

@ -1,39 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Core
{
public delegate void DestroyedEvent(object sender);
public interface IDestructible
{
event DestroyedEvent OnDestroy;
void Destroy();
}
}

View File

@ -1,40 +0,0 @@

/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Core
{
public enum LogType
{
Debug,
Warning,
Error,
}
}

View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Core
{
public enum ProgressType
{
Execution,
Network,
}
}

View File

@ -1,286 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using Esiur.Core;
using System.Reflection;
namespace Esiur.Data
{
public class AutoList<T, ST> : IEnumerable<T>
{
private readonly object syncRoot = new object();
private List<T> list = new List<T>();
public delegate void Modified(ST sender, int index, T oldValue, T newValue);
public delegate void Added(ST sender, T value);
public delegate void Removed(ST sender, T value);
public delegate void Cleared(ST sender);
public event Modified OnModified;
public event Removed OnRemoved;
public event Cleared OnCleared;
public event Added OnAdd;
ST state;
bool removableList;
/*
IOrderedEnumerable<T> OrderBy<T, TK>(Func<T, TK> keySelector)
{
return list.OrderBy<T,TK>(keySelector);
}
*/
public void Sort()
{
list.Sort();
}
public void Sort(IComparer<T> comparer)
{
list.Sort(comparer);
}
public void Sort(Comparison<T> comparison)
{
list.Sort(comparison);
}
public IEnumerable<T> Where(Func<T, bool> predicate)
{
return list.Where(predicate);
}
/// <summary>
/// Convert AutoList to array
/// </summary>
/// <returns>Array</returns>
public T[] ToArray()
{
// list.OrderBy()
return list.ToArray();
}
/// <summary>
/// Create a new instance of AutoList
/// </summary>
/// <param name="state">State object to be included when an event is raised.</param>
public AutoList(ST state)
{
this.state = state;
#if NETSTANDARD
removableList = (typeof(IDestructible).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()));
#else
removableList = (typeof(IDestructible).IsAssignableFrom(typeof(T)));
#endif
}
/// <summary>
/// Create a new instance of AutoList
/// </summary>
/// <param name="values">Populate the list with items</param>
/// <returns></returns>
public AutoList(ST state, T[] values)
{
this.state = state;
#if NETSTANDARD
removableList = (typeof(IDestructible).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()));
#else
removableList = (typeof(IDestructible).IsAssignableFrom(typeof(T)));
#endif
AddRange(values);
}
/// <summary>
/// Synchronization lock of the list
/// </summary>
public object SyncRoot
{
get
{
return syncRoot;
}
}
/// <summary>
/// First item in the list
/// </summary>
public T First()
{
return list.First();
}
/// <summary>
/// Get an item at a specified index
/// </summary>
public T this[int index]
{
get
{
return list[index];
}
set
{
var oldValue = list[index];
if (removableList)
{
if (oldValue != null)
((IDestructible)oldValue).OnDestroy -= ItemDestroyed;
if (value != null)
((IDestructible)value).OnDestroy += ItemDestroyed;
}
lock (syncRoot)
list[index] = value;
OnModified?.Invoke(state, index, oldValue, value);
}
}
/// <summary>
/// Add item to the list
/// </summary>
public void Add(T value)
{
if (removableList)
if (value != null)
((IDestructible)value).OnDestroy += ItemDestroyed;
lock (syncRoot)
list.Add(value);
OnAdd?.Invoke(state, value);
}
/// <summary>
/// Add an array of items to the list
/// </summary>
public void AddRange(T[] values)
{
foreach (var v in values)
Add(v);
}
private void ItemDestroyed(object sender)
{
Remove((T)sender);
}
/// <summary>
/// Clear the list
/// </summary>
public void Clear()
{
if (removableList)
foreach(IDestructible v in list)
if (v!=null)
v.OnDestroy -= ItemDestroyed;
lock (syncRoot)
list.Clear();
OnCleared?.Invoke(state);
}
/// <summary>
/// Remove an item from the list
/// <param name="value">Item to remove</param>
/// </summary>
public void Remove(T value)
{
if (!list.Contains(value))
return;
if (removableList)
if (value != null)
((IDestructible)value).OnDestroy -= ItemDestroyed;
lock (syncRoot)
list.Remove(value);
OnRemoved?.Invoke(state, value);
}
/// <summary>
/// Number of items in the list
/// </summary>
public int Count
{
get { return list.Count; }
}
/// <summary>
/// Check if an item exists in the list
/// </summary>
/// <param name="value">Item to check if exists</param>
public bool Contains(T value)
{
return list.Contains(value);
}
/// <summary>
/// Check if any item of the given array is in the list
/// </summary>
/// <param name="values">Array of items</param>
public bool ContainsAny(T[] values)
{
foreach (var v in values)
if (list.Contains(v))
return true;
return false;
}
/// <summary>
/// Check if any item of the given list is in the list
/// </summary>
/// <param name="values">List of items</param>
public bool ContainsAny(AutoList<T, ST> values)
{
foreach (var v in values)
if (list.Contains((T)v))
return true;
return false;
}
public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>)list).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<T>)list).GetEnumerator();
}
}
}

View File

@ -1,714 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Misc;
using System.Reflection;
using Esiur.Core;
namespace Esiur.Data
{
/// <summary>
/// BinaryList holds a list of items to be converted to binary for storage and transmission
/// </summary>
public class BinaryList
{
private List<byte> list = new List<byte>();
/// <summary>
/// Create an instance of BinaryList
/// </summary>
public BinaryList()
{
}
/*
/// <summary>
/// Converts parameters to binary in same order
/// </summary>
/// <param name="values">Variables to convert</param>
public static byte[] ToBytes(params object[] values)
{
var list = new List<byte>();
foreach (var i in values)
{
if (i is byte)
list.Add((byte)i);
else
{
#if NETSTANDARD
MethodInfo mi = typeof(DC).GetTypeInfo().GetMethod("ToBytes", new Type[] { i.GetType() });
#else
MethodInfo mi = typeof(DC).GetMethod("ToBytes", new Type[] { i.GetType() });
#endif
if (mi != null)
{
var b = (byte[])mi.Invoke(null, new object[] { i });
list.AddRange(b);
}
}
}
return list.ToArray();
}
/// <summary>
/// Create a new instance of BinaryList
/// </summary>
/// <param name="values">Populate the list items</param>
public BinaryList(params object[] values)
{
AddRange(values);
}
/// <summary>
/// Add an array of items at the end of the list
/// </summary>
/// <param name="values">Array of items</param>
public void AddRange(object[] values)
{
foreach (var i in values)
{
if (i is byte)
list.Add((byte)i);
else
{
#if NETSTANDARD
MethodInfo mi = typeof(DC).GetTypeInfo().GetMethod("ToBytes", new Type[] { i.GetType() });
#else
MethodInfo mi = typeof(DC).GetMethod("ToBytes", new Type[] { i.GetType() });
#endif
if (mi != null)
{
var b = (byte[])mi.Invoke(null, new object[] {i});
list.AddRange(b);
}
}
}
}
/// <summary>
/// Add multiple items at the end of the list
/// </summary>
/// <param name="values">Parameters of items</param>
public void Append(params object[] values)
{
AddRange(values);
}
/// <summary>
/// Insert new items to the list at a specified index
/// </summary>
/// <param name="offset">Position in the list</param>
/// <param name="values">Items to insert</param>
public void Insert(int offset, params object[] values)
{
foreach (var i in values)
{
if (i is byte)
{
list.Insert(offset++, (byte)i);
}
else
{
#if NETSTANDARD
MethodInfo mi = typeof(DC).GetTypeInfo().GetMethod("ToBytes", new Type[] { i.GetType() });
#else
MethodInfo mi = typeof(DC).GetMethod("ToBytes", new Type[] { i.GetType() });
#endif
if (mi != null)
{
var b = (byte[])mi.Invoke(null, new object[] { i });
list.InsertRange(offset, b);
offset += b.Length;
}
}
}
}
/// <summary>
/// Number of the items in the list
/// </summary>
public int Length
{
get
{
return list.Count;
}
}
/*
public void Append(byte data)
{
list.Add(data);
}
public void Append(byte[] data)
{
list.AddRange(data);
}
public void Append(int data)
{
list.AddRange(DC.ToBytes(data));
}
public void Append(uint data)
{
list.AddRange(DC.ToBytes(data));
}
public void Append(float data)
{
list.AddRange(DC.ToBytes(data));
}
public void Append(short data)
{
list.AddRange(DC.ToBytes(data));
}
public void Append(ushort data)
{
list.AddRange(DC.ToBytes(data));
}
public void Append(double data)
{
list.AddRange(DC.ToBytes(data));
}
public void Append(sbyte data)
{
list.Add((byte)data);
}
*/
public int Length => list.Count;
public BinaryList AddDateTime(DateTime value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertDateTime(int position, DateTime value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddDateTimeArray(DateTime[] value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertDateTimeArray(int position, DateTime[] value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddGuid(Guid value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertGuid(int position, Guid value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddGuidArray(Guid[] value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertGuidArray(int position, Guid[] value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddUInt8Array(byte[] value)
{
list.AddRange(value);
return this;
}
public BinaryList InsertUInt8Array(int position, byte[] value)
{
list.InsertRange(position, value);
return this;
}
public BinaryList AddHex(string value)
{
return this.AddUInt8Array(DC.FromHex(value, null));
}
public BinaryList InsertHex(int position, string value)
{
return this.InsertUInt8Array(position, DC.FromHex(value, null));
}
public BinaryList AddString(string value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertString(int position, string value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddStringArray(string[] value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertStringArray(int position, string[] value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList InsertUInt8(int position, byte value)
{
list.Insert(position, value);
return this;
}
public BinaryList AddUInt8(byte value)
{
list.Add(value);
return this;
}
public BinaryList AddInt8(sbyte value)
{
list.Add((byte)value);
return this;
}
public BinaryList InsertInt8(int position, sbyte value)
{
list.Insert(position, (byte)value);
return this;
}
public BinaryList AddInt8Array(sbyte[] value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertInt8Array(int position, sbyte[] value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddChar(char value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertChar(int position, char value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddCharArray(char[] value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertCharArray(int position, char[] value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddBoolean(bool value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertBoolean(int position, bool value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddBooleanArray(bool[] value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertBooleanArray(int position, bool[] value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddUInt16(ushort value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertUInt16(int position, ushort value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddUInt16Array(ushort[] value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertUInt16Array(int position, ushort[] value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddInt16(short value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertInt16(int position, short value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddInt16Array(short[] value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertInt16Array(int position, short[] value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddUInt32(uint value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertUInt32(int position, uint value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddUInt32Array(uint[] value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertUInt32Array(int position, uint[] value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddInt32(int value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertInt32(int position, int value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddInt32Array(int[] value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertInt32Array(int position, int[] value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddUInt64(ulong value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertUInt64(int position, ulong value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddUInt64Array(ulong[] value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertUInt64Array(int position, ulong[] value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddInt64(long value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertInt64(int position, long value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddInt64Array(long[] value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertInt64Array(int position, long[] value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddFloat32(float value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertFloat32(int position, float value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddFloat32Array(float[] value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertFloat32Array(int position, float[] value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddFloat64(double value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertFloat64(int position, double value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList AddFloat64Array(double[] value)
{
list.AddRange(DC.ToBytes(value));
return this;
}
public BinaryList InsertFloat64Array(int position, double[] value)
{
list.InsertRange(position, DC.ToBytes(value));
return this;
}
public BinaryList Add(DataType type, object value)
{
switch (type)
{
case DataType.Bool:
AddBoolean((bool)value);
return this;
case DataType.BoolArray:
AddBooleanArray((bool[])value);
return this;
case DataType.UInt8:
AddUInt8((byte)value);
return this;
case DataType.UInt8Array:
AddUInt8Array((byte[])value);
return this;
case DataType.Int8:
AddInt8((sbyte)value);
return this;
case DataType.Int8Array:
AddInt8Array((sbyte[])value);
return this;
case DataType.Char:
AddChar((char)value);
return this;
case DataType.CharArray:
AddCharArray((char[])value);
return this;
case DataType.UInt16:
AddUInt16((ushort)value);
return this;
case DataType.UInt16Array:
AddUInt16Array((ushort[])value);
return this;
case DataType.Int16:
AddInt16((short)value);
return this;
case DataType.Int16Array:
AddInt16Array((short[])value);
return this;
case DataType.UInt32:
AddUInt32((uint)value);
return this;
case DataType.UInt32Array:
AddUInt32Array((uint[])value);
return this;
case DataType.Int32:
AddInt32((int)value);
return this;
case DataType.Int32Array:
AddInt32Array((int[])value);
return this;
case DataType.UInt64:
AddUInt64((ulong)value);
return this;
case DataType.UInt64Array:
AddUInt64Array((ulong[])value);
return this;
case DataType.Int64:
AddInt64((long)value);
return this;
case DataType.Int64Array:
AddInt64Array((long[])value);
return this;
case DataType.Float32:
AddFloat32((float)value);
return this;
case DataType.Float32Array:
AddFloat32Array((float[])value);
return this;
case DataType.Float64:
AddFloat64((double)value);
return this;
case DataType.Float64Array:
AddFloat64Array((double[])value);
return this;
case DataType.String:
AddString((string)value);
return this;
case DataType.StringArray:
AddStringArray((string[])value);
return this;
case DataType.DateTime:
AddDateTime((DateTime)value);
return this;
case DataType.DateTimeArray:
AddDateTimeArray((DateTime[])value);
return this;
default:
throw new Exception("Not Implemented " + type.ToString());
//return this;
}
}
/// <summary>
/// Convert the list to an array of bytes
/// </summary>
/// <returns>Bytes array</returns>
public byte[] ToArray()
{
return list.ToArray();
}
public virtual IAsyncReply<object[]> Done()
{
return null;
//
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,119 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Data
{
public enum DataType : byte
{
Void = 0x0,
//Variant,
Bool,
Int8,
UInt8,
Char,
Int16,
UInt16,
Int32,
UInt32,
Int64,
UInt64,
Float32,
Float64,
Decimal,
DateTime,
Resource,
DistributedResource,
ResourceLink,
String,
Structure,
//Stream,
//Array = 0x80,
VarArray = 0x80,
BoolArray,
UInt8Array,
Int8Array,
CharArray,
Int16Array,
UInt16Array,
Int32Array,
UInt32Array,
Int64Array,
UInt64Array,
Float32Array,
Float64Array,
DecimalArray,
DateTimeArray,
ResourceArray,
DistributedResourceArray,
ResourceLinkArray,
StringArray,
StructureArray,
NotModified = 0x7f,
Unspecified = 0xff,
}
public static class DataTypeExpansions
{
public static int Size(this DataType t)
{
switch (t)
{
case DataType.Void:
case DataType.NotModified:
return 0;
case DataType.Bool:
case DataType.UInt8:
case DataType.Int8:
return 1;
case DataType.Char:
case DataType.UInt16:
case DataType.Int16:
return 2;
case DataType.Int32:
case DataType.UInt32:
case DataType.Float32:
case DataType.Resource:
return 4;
case DataType.Int64:
case DataType.UInt64:
case DataType.Float64:
case DataType.DateTime:
return 8;
case DataType.DistributedResource:
return 4;
default:
return -1;
}
}
}
}

View File

@ -1,237 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.IO;
using System.Collections;
using System.Security.Cryptography;
using System.Text;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Esiur.Core;
namespace Esiur.Data
{
public class KeyList<KT, T> : IEnumerable
{
private readonly object syncRoot = new object();
private Dictionary<KT, T> dic;
public delegate void Modified(KT key, T oldValue, T newValue, KeyList<KT, T> sender);
public delegate void Added(T value, KeyList<KT, T> sender);
public delegate void Removed(KT key, T value, KeyList<KT, T> sender);
public delegate void Cleared(KeyList<KT, T> sender);
public event Modified OnModified;
public event Removed OnRemoved;
public event Cleared OnCleared;
public event Added OnAdd;
bool removableList;
public object SyncRoot
{
get
{
return syncRoot;
}
}
public T Take(KT key)
{
if (dic.ContainsKey(key))
{
var v = dic[key];
Remove(key);
return v;
}
else
return default(T);
}
public void Sort(Func<KeyValuePair<KT, T>, object> keySelector)
{
dic = dic.OrderBy(keySelector).ToDictionary(x => x.Key, x => x.Value);
}
public T[] ToArray()
{
var a = new T[Count];
dic.Values.CopyTo(a, 0);
return a;
}
public void Add(KT key, T value)
{
lock (syncRoot)
{
if (removableList)
if (value != null)
((IDestructible)value).OnDestroy += ItemDestroyed;
if (dic.ContainsKey(key))
{
var oldValue = dic[key];
if (removableList)
if (oldValue != null)
((IDestructible)oldValue).OnDestroy -= ItemDestroyed;
dic[key] = value;
if (OnModified != null)
OnModified(key, oldValue, value, this);
}
else
{
dic.Add(key, value);
if (OnAdd != null)
OnAdd(value, this);
}
}
}
private void ItemDestroyed(object sender)
{
RemoveValue((T)sender);
}
public void RemoveValue(T value)
{
var toRemove = new List<KT>();
foreach (var kv in dic)
if (kv.Value.Equals(value))
toRemove.Add(kv.Key);
foreach (var k in toRemove)
Remove(k);
}
public T this[KT key]
{
get
{
if (dic.ContainsKey(key))
return dic[key];
else
return default(T);
}
set
{
Add(key, value);
}
}
public IEnumerator GetEnumerator()
{
return dic.GetEnumerator();
}
public void Clear()
{
if (removableList)
foreach (IDestructible v in dic.Values)
if (v != null)
v.OnDestroy -= ItemDestroyed;
lock (syncRoot)
dic.Clear();
if (OnCleared != null)
OnCleared(this);
}
public Dictionary<KT, T>.KeyCollection Keys
{
get { return dic.Keys; }
}
public Dictionary<KT, T>.ValueCollection Values
{
get
{
return dic.Values;
}
}
public void Remove(KT key)
{
if (!dic.ContainsKey(key))
return;
var value = dic[key];
if (removableList)
if (value != null)
((IDestructible)value).OnDestroy -= ItemDestroyed;
lock (syncRoot)
dic.Remove(key);
if (OnRemoved != null)
OnRemoved(key, value, this);
}
public object Owner
{
get;
set;
}
public int Count
{
get { return dic.Count; }
}
public bool Contains(KT Key)
{
return dic.ContainsKey(Key);
}
public bool ContainsKey(KT Key)
{
return dic.ContainsKey(Key);
}
public bool ContainsValue(T Value)
{
return dic.ContainsValue(Value);
}
public KeyList(object owner = null)
{
#if NETSTANDARD
removableList = (typeof(IDestructible).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()));
#else
removableList = (typeof(IDestructible).IsAssignableFrom(typeof(T)));
#endif
this.Owner = owner;
if (typeof(KT) == typeof(string))
dic = (Dictionary<KT, T>)(object)new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase);
else
dic = new Dictionary<KT, T>();
}
}
}

View File

@ -1,37 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Data
{
public class NotModified
{
}
}

View File

@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Data
{
public class PropertyValue
{
/// <summary>
/// Get or set the value.
/// </summary>
public object Value { get; set; }
/// <summary>
/// Get or set date of modification or occurrence.
/// </summary>
public DateTime Date { get; set; }
/// <summary>
/// Get or set property age.
/// </summary>
public ulong Age { get; set; }
/// <summary>
/// Create an instance of PropertyValue.
/// </summary>
/// <param name="value">Value.</param>
/// <param name="age">Age.</param>
/// <param name="date">Date.</param>
public PropertyValue(object value, ulong age, DateTime date)
{
Value = value;
Age = age;
Date = date;
}
}
}

View File

@ -1,220 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Reflection;
using System.Linq;
namespace Esiur.Data
{
public class StringKeyList : IEnumerable<KeyValuePair<string, string>>
{
//private List<string> m_keys = new List<string>();
//private List<string> m_values = new List<string>();
private List<KeyValuePair<string, string>> m_Variables = new List<KeyValuePair<string, string>>();
private bool allowMultiple;
public delegate void Modified(string Key, string NewValue);
public event Modified OnModified;
public StringKeyList(bool AllowMultipleValues = false)
{
allowMultiple = AllowMultipleValues;
}
public void Add(string Key, string Value)
{
if (OnModified != null)
OnModified(Key, Value);
var key = Key.ToLower();
if (!allowMultiple)
{
foreach(var kv in m_Variables)
{
if (kv.Key.ToLower() == key)
{
m_Variables.Remove(kv);
break;
}
}
}
m_Variables.Add(new KeyValuePair<string, string>(Key, Value));
}
public string this[string Key]
{
get
{
var key = Key.ToLower();
foreach (var kv in m_Variables)
if (kv.Key.ToLower() == key)
return kv.Value;
return null;
}
set
{
var key = Key.ToLower();
var toRemove = m_Variables.Where(x => x.Key.ToLower() == key).ToArray();
foreach (var item in toRemove)
m_Variables.Remove(item);
m_Variables.Add(new KeyValuePair<string, string>(Key, value));
OnModified?.Invoke(Key, value);
}
}
IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator()
{
//return m_keys.GetEnumerator();
return m_Variables.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return m_Variables.GetEnumerator();
}
public void Clear()
{
if (OnModified != null)
OnModified(null, null);
m_Variables.Clear();
}
/*
public string[] Keys
{
get
{
return m_keys.ToArray();
}
}
//public Dictionary<string, string>.ValueCollection Values
public string[] Values
{
get
{
//return m_Variables.Values;
return m_values.ToArray();
}
}
*/
public List<string> GetValues(string Key)
{
var key = Key.ToLower();
List<string> values = new List<string>();
foreach (var kv in m_Variables)
if (kv.Key.ToLower() == key)
values.Add(kv.Value);
return values;
}
public void RemoveAll(string Key)
{
while (Remove(Key)){}
}
public bool Remove(string Key)
{
var key = Key.ToLower();
foreach(var kv in m_Variables)
{
if (kv.Key.ToLower() == key)
{
if (OnModified != null)
OnModified(Key, null);
m_Variables.Remove(kv);
return true;
}
}
return false;
}
public int Count
{
get { return m_Variables.Count; }
}
public bool ContainsKey(string Key)
{
var key = Key.ToLower();
foreach (var kv in m_Variables)
if (kv.Key.ToLower() == key)
return true;
return false;
}
/*
public bool ContainsKey(string Key)
{
//return m_Variables.ContainsKey(Key);
return m_keys.Contains(Key.ToLower());
}
*/
public bool ContainsValue(string Value)
{
var value = Value.ToLower();
foreach (var kv in m_Variables)
if (kv.Value.ToLower() == value)
return true;
return false;
}
//internal KeyList()
//{
// m_Session = Session;
// m_Server = Server;
//}
}
}

View File

@ -1,134 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Esiur.Data;
using Esiur.Misc;
using Esiur.Core;
using System.Reflection;
namespace Esiur.Data
{
public class Structure : IEnumerable<KeyValuePair<string, object>>
{
public struct StructureMetadata
{
public string[] Keys;
public DataType[] Types;
}
private Dictionary<string, object> dic = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
private object syncRoot = new object();
public bool ContainsKey(string key)
{
return dic.ContainsKey(key);
}
public override string ToString()
{
var rt = "";
foreach (var kv in dic)
rt += kv.Key + ": " + kv.Value.ToString() + "\r\n";
return rt.TrimEnd('\r', '\n');
}
public static Structure FromObject(object obj)
{
var type = obj.GetType();
if (obj is Structure)
return obj as Structure;
else if (Codec.IsAnonymous(type))
{
var st = new Structure();
var pi = type.GetTypeInfo().GetProperties();
foreach (var p in pi)
st[p.Name] = p.GetValue(obj);
return st;
}
else
return null;
}
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
return dic.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return dic.GetEnumerator();
}
public int Length
{
get { return dic.Count; }
}
public KeyValuePair<string, object> At(int index)
{
return dic.ElementAt(index);
}
public object SyncRoot
{
get { return syncRoot; }
}
public string[] GetKeys() => dic.Keys.ToArray();//GetKeys()
//{
// return dic.Keys.ToArray();
//}
public object this[string index]
{
get
{
if (dic.ContainsKey(index))
return dic[index];
else
return null;
}
set
{
if (dic.ContainsKey(index))
dic[index] = value;
else
dic.Add(index, value);
}
}
}
}

View File

@ -1,52 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Description>Distributed Resources Platform</Description>
<Copyright>Ahmed Kh. Zamil</Copyright>
<PackageLicenseUrl>https://github.com/esiur/esiur-dotnet/blob/master/LICENSE</PackageLicenseUrl>
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>1.4.1</Version>
<RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl>
<Authors>Ahmed Kh. Zamil</Authors>
<AssemblyVersion>1.3.1.0</AssemblyVersion>
<Company>Esiur Foundation</Company>
<FileVersion>1.3.1.0</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<DefineConstants>TRACE;DEBUG;NETSTANDARD</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Core\AsyncReplyNon.cs" />
<Compile Remove="Net\UDP\UDPServer.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Net\DataLink\Sources\" />
</ItemGroup>
<ItemGroup>
<None Include="Core\AsyncReplyNon.cs" />
<None Include="Net\UDP\UDPServer.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Diagnostics.StackTrace" Version="4.3.0" />
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
<PackageReference Include="System.Interactive.Async" Version="3.2.0" />
<PackageReference Include="System.Net.NameResolution" Version="4.3.0" />
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
<PackageReference Include="System.Net.Security" Version="4.3.1" />
<PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.3" />
</ItemGroup>
</Project>

View File

@ -1,458 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.IO;
using System.Collections;
using System.Xml;
using System.Security.Cryptography;
using System.Text;
using System.Reflection;
using Esiur.Data;
using System.Collections.Generic;
//using Esiur.Net.Packets;
using System.Text.RegularExpressions;
using System.Net.NetworkInformation;
using System.Linq;
using Esiur.Core;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Esiur.Misc
{
public static class Global
{
private static KeyList<string, object> variables = new KeyList<string, object>();
// private static Hashtable m_Cached = new Hashtable();
//internal static bool SystemIsWorking = false;
private static Random rand = new Random(System.Environment.TickCount);
//public static Encoding DefaultEncoding = Encoding.GetEncoding(1252);// .GetEncoding("windows-1252");
public static KeyList<string, long> Counters = new KeyList<string, long>();
public delegate void LogEvent(string service, LogType type, string message);
public static event LogEvent SystemLog;
static Random random = new Random();
/*
public static char GetDirectorySeparator()
{
return System.IO.Path.DirectorySeparatorChar;
}
*/
public static void Log(Exception ex, params object[] arguments)
{
try
{
var stack = new StackTrace(ex, true);
var frame = stack.GetFrames().First();
var method = frame.GetMethod();
var parameters = method.GetParameters();
var service = method.DeclaringType.Name;
var message = "";
if (arguments.Length > 0 && parameters.Length > 0)
{
message = "Arguments ( ";
for (int i = 0; i < parameters.Length && i < arguments.Length; i++)
{
message += parameters[i].Name + ": " + arguments[i].ToString() + " ";
}
message += ")" + Environment.NewLine + "------------------------------------------------";
}
message += ex.ToString();
Log(service, LogType.Error, message);
Log(service, LogType.Error, ex.ToString());
}
catch
{
}
}
public static void Log(string service, LogType type, string message, bool appendHeader = true)
{
//if (type != LogType.Debug)
Console.WriteLine(service + " " + message);
SystemLog?.Invoke(service, type, message);
}
/*
public static string GetTempPath()
{
return System.IO.Path.GetTempPath();
}
*/
public static string RemoveControlCharacters(string inString)
{
if (inString == null) return null;
StringBuilder newString = new StringBuilder();
char ch;
for (int i = 0; i < inString.Length; i++)
{
ch = inString[i];
if (!char.IsControl(ch))
{
newString.Append(ch);
}
}
return newString.ToString();
}
public static void PrintCounters()
{
string[] keys = new string[Counters.Keys.Count];
Counters.Keys.CopyTo(keys, 0);
foreach (string k in keys)
{
Console.WriteLine(k + ":" + Counters[k]);
}
}
// Encoding ANSI = Encoding.GetEncoding(1252);
/*
public static Hashtable Cached
{
get
{
return m_Cached;
}
}*/
/*
public static string ByteArrayToMAC(byte[] array)
{
string rt="";
if (array == null)
return "00:00:00:00:00:00";
else
{
//for (int i = 0; i < array.Length - 1; i++)
// rt += Convert.ToString(array[i], 16) + ":";
//rt += Convert.ToString(array[array.Length - 1], 16);
rt = BitConverter.ToString(array);
rt = rt.Replace('-', ':');
return rt;
}
}
*/
/*
public static string IPAddressFromInt32(UInt32 IP)
{
//var dIP = DC.ToBytes(IP);
return (IP >> 24) + "." + ((IP >> 16) & 0xFF) + "." + ((IP >> 8) & 0xFF) + "." + (IP & 0xFF);
}
*/
public static KeyList<string, object> Variables
{
get
{
return variables;
}
}
public static uint CurrentUnixTime()
{
return (uint)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
}
public static void SetConsoleColors(ConsoleColor ForegroundColor, ConsoleColor BackgroundColor)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
switch (ForegroundColor)
{
case ConsoleColor.Black:
Console.Write("\u001B[30m");
break;
case ConsoleColor.Blue:
Console.Write("\u001B[1;34m");
break;
case ConsoleColor.Cyan:
Console.Write("\u001B[1;36m");
break;
case ConsoleColor.Gray:
case ConsoleColor.DarkGray:
Console.Write("\u001B[1;30m");
break;
case ConsoleColor.Green:
Console.Write("\u001B[1;32m");
break;
case ConsoleColor.Magenta:
Console.Write("\u001B[1;35m");
break;
case ConsoleColor.Red:
Console.Write("\u001B[1;31m");
break;
case ConsoleColor.White:
Console.Write("\u001B[1;37m");
break;
case ConsoleColor.Yellow:
Console.Write("\u001B[1;33m");
break;
case ConsoleColor.DarkBlue:
Console.Write("\u001B[34m");
break;
case ConsoleColor.DarkCyan:
Console.Write("\u001B[36m");
break;
case ConsoleColor.DarkGreen:
Console.Write("\u001B[32m");
break;
case ConsoleColor.DarkMagenta:
Console.Write("\u001B[35m");
break;
case ConsoleColor.DarkRed:
Console.Write("\u001B[31m");
break;
case ConsoleColor.DarkYellow:
Console.Write("\u001B[33m");
break;
}
switch (BackgroundColor)
{
case ConsoleColor.Black:
Console.Write("\u001B[40m");
break;
case ConsoleColor.Blue:
Console.Write("\u001B[1;44m");
break;
case ConsoleColor.Cyan:
Console.Write("\u001B[1;46m");
break;
case ConsoleColor.Gray:
case ConsoleColor.DarkGray:
Console.Write("\u001B[1;40m");
break;
case ConsoleColor.Green:
Console.Write("\u001B[1;42m");
break;
case ConsoleColor.Magenta:
Console.Write("\u001B[1;45m");
break;
case ConsoleColor.Red:
Console.Write("\u001B[1;41m");
break;
case ConsoleColor.White:
Console.Write("\u001B[1;47m");
break;
case ConsoleColor.Yellow:
Console.Write("\u001B[1;43m");
break;
case ConsoleColor.DarkBlue:
Console.Write("\u001B[44m");
break;
case ConsoleColor.DarkCyan:
Console.Write("\u001B[46m");
break;
case ConsoleColor.DarkGreen:
Console.Write("\u001B[42m");
break;
case ConsoleColor.DarkMagenta:
Console.Write("\u001B[45m");
break;
case ConsoleColor.DarkRed:
Console.Write("\u001B[41m");
break;
case ConsoleColor.DarkYellow:
Console.Write("\u001B[43m");
break;
}
}
else
{
Console.ForegroundColor = ForegroundColor;
Console.BackgroundColor = BackgroundColor;
}
}
public static string GetUserPart(string strAddress)
{
return strAddress.Substring(0, strAddress.IndexOf("@", 0));
}
public static byte[][] GetBytesFromChunk(byte[] Data, int ChunkSize)
{
if (ChunkSize == 1)
{
byte[][] ar = new byte[0][];
int ptr = 0;
while (ptr < Data.Length)
{
Array.Resize<byte[]>(ref ar, ar.Length + 1);
ar[ar.Length - 1] = new byte[Data[ptr]];
Buffer.BlockCopy(Data, ++ptr, ar[ar.Length - 1], 0, Data[ptr]);
ptr += Data[ptr] + 1;
}
return ar;
}
return null;
}
public static string GetFileTitle(string Filename)
{
string[] s = Filename.Split(Path.DirectorySeparatorChar);
return s[s.Length - 1];
}
public static string GetNewFileName(string FileDir)
{
string tempGetNewFileName = null;
short i = 0;
string NewFile = null;
NewFile = FileDir;
Begin:
FileInfo FF = new FileInfo(NewFile);
if (FF.Exists)
{
//If FSO.FileExists(NewFile) Then
i++; //= i + 1;
NewFile = FileDir.Substring(0, FileDir.Length - 4) + "_" + i + "." + FileDir.Substring(FileDir.Length - 3);
goto Begin;
}
else
{
tempGetNewFileName = NewFile;
}
return tempGetNewFileName;
}
/////////////////////////////////////
public static string TrimEx(string strIn)
{
return strIn.Replace("\r", "").Replace("\n", "");
}
/*
public static bool IsUnix()
{
// Linux OSs under Mono 1.2 uses unknown integer numbers so this should identify all non windows as unix
return (Environment.OSVersion.Platform != PlatformID.Win32NT
&& Environment.OSVersion.Platform != PlatformID.Win32Windows); // || Environment.OSVersion.Platform == PlatformID.Linux;
}
*/
public static string GenerateCode()
{
return GenerateCode(16);
}
public static byte[] GenerateBytes(int Length)
{
var b = new byte[Length];
rand.NextBytes(b);
return b;
}
public static string GenerateCode(int length)
{
return GenerateCode(length, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&*()_-+=\\?/");
}
public static string GenerateCode(int length, string chars)
//public static string GenerateCode(int Length)
{
//var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&*()_-+=\\?/";
var result = new string(
Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)])
.ToArray());
//if (result.Length < length)
// Console.WriteLine();
return result;
/*
int len = 0;
string code = "";
while(len < Length)
{
var c = Convert.ToChar((byte)(rand.NextDouble() * 255));
if (Char.IsLetterOrDigit(c))
{
code += c;
len++;
}
}
return code;
*/
}
public static string ReplaceOnce(string Expression, string Find, string Replacement)
{
int pos = Expression.IndexOf(Find);
if (pos != -1)
return Expression.Substring(0, pos) + Replacement + Expression.Substring(pos + Find.Length);
else
return Expression;
}
//public void Replace(string Expression, string Find, string Replacement, int Start, int Count)
//{
// Expression.IndexOf(
//}
}
}

View File

@ -1,56 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Core;
using Esiur.Data;
using Esiur.Net.Packets;
using Esiur.Resource;
namespace Esiur.Net.DataLink
{
public abstract class PacketFilter : IResource
{
public Instance Instance
{
get;
set;
}
public event DestroyedEvent OnDestroy;
public abstract AsyncReply<bool> Trigger(ResourceTrigger trigger);
public abstract bool Execute(Packet packet);
public void Destroy()
{
}
}
}

View File

@ -1,123 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Core;
using Esiur.Data;
using System.Runtime.InteropServices;
using Esiur.Net.Packets;
using Esiur.Resource;
namespace Esiur.Net.DataLink
{
public class PacketServer:IResource
{
List<PacketSource> sources = new List<PacketSource>();
List<PacketFilter> filters = new List<PacketFilter>();
[Storable]
public string Mode
{
get;
set;
}
public Instance Instance
{
get;
set;
}
public List<PacketSource> Sources
{
get
{
return sources;
}
}
public event DestroyedEvent OnDestroy;
public void Destroy()
{
throw new NotImplementedException();
}
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
{
if (trigger == ResourceTrigger.Initialize)
{
/*
foreach (var resource in Instance.Children<IResource>())
{
if (resource is PacketFilter)
{
filters.Add(resource as PacketFilter);
}
else if (resource is PacketSource)
{
sources.Add(resource as PacketSource);
}
}
*/
foreach (var src in sources)
{
src.OnNewPacket += PacketReceived;
src.Open();
}
}
else if (trigger == ResourceTrigger.Terminate)
{
// foreach (var src in sources)
// src.Close();
}
else if (trigger == ResourceTrigger.SystemReload)
{
foreach (var src in sources)
{
src.Close();
src.Open();
}
}
return new AsyncReply<bool>( true);
}
void PacketReceived(Packet Packet)
{
foreach (var f in filters)
{
if (f.Execute(Packet))
{
break;
}
}
}
}
}

View File

@ -1,95 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using Esiur.Net.Packets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Core;
using Esiur.Resource;
namespace Esiur.Net.DataLink
{
public abstract class PacketSource: IResource
{
public delegate void NewPacket(Packet Packet);
public abstract event NewPacket OnNewPacket;
public event DestroyedEvent OnDestroy;
public Instance Instance
{
get;
set;
}
public abstract AsyncReply<bool> Trigger(ResourceTrigger trigger);
public abstract bool RawMode
{
set;
get;
}
//public PacketSource(PacketServer Server, bool RawMode)
//{
// this.RawMode = RawMode;
//}
public abstract bool Open();
public abstract bool Close();
public abstract bool Write(Packet packet);
public void Destroy()
{
throw new NotImplementedException();
}
/*
public virtual string TypeName
{
get
{
return "Raw";
}
}
*/
public abstract byte[] Address
{
get;
}
public abstract string DeviceId
{
get;
}
}
}

View File

@ -1,320 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Net;
using System.Collections;
using System.Collections.Generic;
using Esiur.Net.Sockets;
using Esiur.Data;
using Esiur.Net.Packets;
using Esiur.Misc;
using System.Security.Cryptography;
namespace Esiur.Net.HTTP
{
public class HTTPConnection : NetworkConnection
{
public void SetParent(HTTPServer Parent)
{
Server = Parent;
}
public bool WSMode { get; internal set; }
private HTTPServer Server;
public WebsocketPacket WSRequest { get; set; }
public HTTPRequestPacket Request { get; set; }
public HTTPResponsePacket Response { get; } = new HTTPResponsePacket();
HTTPSession session;
public KeyList<string, object> Variables { get; } = new KeyList<string, object>();
internal long Parse(byte[] data)
{
if (WSMode)
{
// now parse WS protocol
WebsocketPacket ws = new WebsocketPacket();
var pSize = ws.Parse(data, 0, (uint)data.Length);
if (pSize > 0)
{
WSRequest = ws;
return 0;
}
else
{
return pSize;
}
}
else
{
var rp = new HTTPRequestPacket();
var pSize = rp.Parse(data, 0, (uint)data.Length);
if (pSize > 0)
{
Request = rp;
return 0;
}
else
{
return pSize;
}
}
}
public void Flush()
{
// close the connection
if (Request.Headers["connection"].ToLower() != "keep-alive" & Connected)
Close();
}
public bool Upgrade()
{
if (IsWebsocketRequest())
{
string magicString = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
string ret = Request.Headers["Sec-WebSocket-Key"] + magicString;
// Compute the SHA1 hash
SHA1 sha = SHA1.Create();
byte[] sha1Hash = sha.ComputeHash(Encoding.UTF8.GetBytes(ret));
Response.Headers["Upgrade"] = Request.Headers["Upgrade"];
Response.Headers["Connection"] = Request.Headers["Connection"];// "Upgrade";
Response.Headers["Sec-WebSocket-Accept"] = Convert.ToBase64String(sha1Hash);
if (Request.Headers.ContainsKey("Sec-WebSocket-Protocol"))
Response.Headers["Sec-WebSocket-Protocol"] = Request.Headers["Sec-WebSocket-Protocol"];
Response.Number = HTTPResponsePacket.ResponseCode.HTTP_SWITCHING;
Response.Text = "Switching Protocols";
WSMode = true;
Send();
return true;
}
return false;
}
public HTTPServer Parent
{
get
{
return Server;
}
}
public override void Send(string data)
{
Response.Message = Encoding.UTF8.GetBytes(data);
Send();
}
public override void Send(byte[] msg, int offset, int length)
{
Response.Message = DC.Clip(msg, (uint)offset, (uint)length);
Send();
}
public override void Send(byte[] message)
{
Response.Message = message;
Send();
}
public void Send(HTTPResponsePacket.ComposeOptions Options = HTTPResponsePacket.ComposeOptions.AllCalculateLength)
{
if (Response.Handled)
return;
try
{
Response.Compose(Options);
base.Send(Response.Data);
// Refresh the current session
if (session != null)
session.Refresh();
}
catch
{
try
{
Close();
}
finally { }
}
finally
{
}
}
public void CreateNewSession()
{
if (session == null)
{
// Create a new one
session = Server.CreateSession(Global.GenerateCode(12), 60 * 20);
HTTPResponsePacket.HTTPCookie cookie = new HTTPResponsePacket.HTTPCookie("SID", session.Id);
cookie.Expires = DateTime.MaxValue;
cookie.Path = "/";
cookie.HttpOnly = true;
Response.Cookies.Add(cookie);
}
}
public bool IsWebsocketRequest()
{
if (Request.Headers.ContainsKey("connection")
&& Request.Headers["connection"].ToLower().Contains("upgrade")
&& Request.Headers.ContainsKey("upgrade")
&& Request.Headers["upgrade"].ToLower() == "websocket"
&& Request.Headers.ContainsKey("Sec-WebSocket-Version")
&& Request.Headers["Sec-WebSocket-Version"] == "13"
&& Request.Headers.ContainsKey("Sec-WebSocket-Key"))
//&& Request.Headers.ContainsKey("Sec-WebSocket-Protocol"))
{
return true;
}
else
{
return false;
}
}
bool bb;
public void SendFile(string filename)
{
if (Response.Handled == true)
return;
try
{
//HTTP/1.1 200 OK
//Server: Microsoft-IIS/5.0
//Content-Location: http://127.0.0.1/index.html
//Date: Wed, 10 Dec 2003 19:10:25 GMT
//Content-Type: text/html
//Accept-Ranges: bytes
//Last-Modified: Mon, 22 Sep 2003 22:36:56 GMT
//Content-Length: 1957
if (!File.Exists(filename))
{
Response.Number = HTTPResponsePacket.ResponseCode.HTTP_NOTFOUND;
Send("File Not Found");
return;
}
var fileEditTime = File.GetLastWriteTime(filename).ToUniversalTime();
if (Request.Headers.ContainsKey("if-modified-since"))
{
try
{
var ims = DateTime.Parse(Request.Headers["if-modified-since"]);
if (Math.Abs((fileEditTime - ims).TotalSeconds) < 0)
{
Response.Number = HTTPResponsePacket.ResponseCode.HTTP_NOTMODIFIED;
Response.Text = "Not Modified";
Send((byte[])null);
}
}
catch
{
}
}
Response.Number = HTTPResponsePacket.ResponseCode.HTTP_OK;
// Fri, 30 Oct 2007 14:19:41 GMT
Response.Headers["Last-Modified"] = fileEditTime.ToString("ddd, dd MMM yyyy HH:mm:ss");
FileInfo fi = new FileInfo(filename);
Response.Headers["Content-Length"] = fi.Length.ToString();
Send(HTTPResponsePacket.ComposeOptions.SpecifiedHeadersOnly);
//var fd = File.ReadAllBytes(filename);
//base.Send(fd);
using (var fs = new FileStream(filename, FileMode.Open))
{
var buffer = new byte[5000];
while (true)
{
var n = fs.Read(buffer, 0, 5000);
if (n <= 0)
break;
base.Send(buffer, 0, n);
}
}
}
catch
{
try
{
Close();
}
finally { }
}
}
}
}

View File

@ -1,82 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Net;
using System.Collections;
using System.Collections.Generic;
using Esiur.Data;
using Esiur.Core;
using Esiur.Resource;
namespace Esiur.Net.HTTP
{
public abstract class HTTPFilter : IResource
{
public Instance Instance
{
get;
set;
}
public event DestroyedEvent OnDestroy;
public abstract AsyncReply<bool> Trigger(ResourceTrigger trigger);
/*
public virtual void SessionModified(HTTPSession session, string key, object oldValue, object newValue)
{
}
public virtual void SessionExpired(HTTPSession session)
{
}
*/
public abstract bool Execute(HTTPConnection sender);
public virtual void ClientConnected(HTTPConnection HTTP)
{
//return false;
}
public virtual void ClientDisconnected(HTTPConnection HTTP)
{
//return false;
}
public void Destroy()
{
throw new NotImplementedException();
}
}
}

View File

@ -1,423 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Net;
using System.Collections;
using System.Collections.Generic;
using Esiur.Net.Sockets;
using Esiur.Data;
using Esiur.Misc;
using Esiur.Core;
using Esiur.Net.Packets;
using System.Security.Cryptography.X509Certificates;
using Esiur.Resource;
namespace Esiur.Net.HTTP
{
public class HTTPServer : NetworkServer<HTTPConnection>, IResource
{
Dictionary<string, HTTPSession> sessions= new Dictionary<string, HTTPSession>();
HTTPFilter[] filters = null;
public Instance Instance
{
get;
set;
}
[Storable]
string ip
{
get;
set;
}
[Storable]
ushort port
{
get;
set;
}
[Storable]
uint timeout
{
get;
set;
}
[Storable]
uint clock
{
get;
set;
}
[Storable]
uint maxPost
{
get;
set;
}
[Storable]
bool ssl
{
get;
set;
}
[Storable]
string certificate
{
get;
set;
}
//public override void ClientConnected(TClient Sender)
//{
//}
/*
public DStringDictionary Configurations
{
get { return config; }
}
*/
public enum ResponseCodes : int
{
HTTP_OK = 200,
HTTP_NOTFOUND = 404,
HTTP_SERVERERROR = 500,
HTTP_MOVED = 301,
HTTP_NOTMODIFIED = 304,
HTTP_REDIRECT = 307
}
public HTTPSession CreateSession(string id, int timeout)
{
var s = new HTTPSession();
s.Set(id, timeout);
sessions.Add(id, s);
return s;
}
/*
protected override void SessionModified(NetworkSession session, string key, object oldValue, object newValue)
{
foreach (var instance in Instance.Children)
{
var f = (HTTPFilter)instance;
f.SessionModified(session as HTTPSession, key, oldValue, newValue);
}
}
*/
//public override object InitializeLifetimeService()
//{
// return null;
//}
public static string MakeCookie(string Item, string Value, DateTime Expires, string Domain, string Path, bool HttpOnly)
{
//Set-Cookie: ckGeneric=CookieBody; expires=Sun, 30-Dec-2001 21:00:00 GMT; domain=.com.au; path=/
//Set-Cookie: SessionID=another; expires=Fri, 29 Jun 2006 20:47:11 UTC; path=/
string Cookie = Item + "=" + Value;
if (Expires.Ticks != 0)
{
Cookie += "; expires=" + Expires.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss") + " GMT";
}
if (Domain != null)
{
Cookie += "; domain=" + Domain;
}
if (Path != null)
{
Cookie += "; path=" + Path;
}
if (HttpOnly)
{
Cookie += "; HttpOnly";
}
return Cookie;
}
protected override void ClientDisconnected(HTTPConnection sender)
{
//Console.WriteLine("OUT: " + this.Connections.Count);
foreach (var filter in filters)
filter.ClientDisconnected(sender);
}
protected override void DataReceived(HTTPConnection sender, NetworkBuffer data)
{
byte[] msg = data.Read();
var BL = sender.Parse(msg);
if (BL == 0)
{
if (sender.Request.Method == HTTPRequestPacket.HTTPMethod.UNKNOWN)
{
sender.Close();
return;
}
if (sender.Request.URL == "")
{
sender.Close();
return;
}
}
else if (BL == -1)
{
data.HoldForNextWrite(msg);
return;
}
else if (BL < 0)
{
data.HoldFor(msg, (uint) (msg.Length - BL));
return;
}
else if (BL > 0)
{
if (BL > maxPost)
{
sender.Send(
"<html><body>POST method content is larger than "
+ maxPost
+ " bytes.</body></html>");
sender.Close();
}
else
{
data.HoldFor(msg, (uint)(msg.Length + BL));
}
return;
}
else if (BL < 0) // for security
{
sender.Close();
return;
}
if (sender.IsWebsocketRequest() & !sender.WSMode)
{
sender.Upgrade();
//return;
}
//return;
try
{
foreach (var resource in filters)
if (resource.Execute(sender))
return;
sender.Send("Bad Request");
sender.Close();
}
catch (Exception ex)
{
if (ex.Message != "Thread was being aborted.")
{
Global.Log("HTTPServer", LogType.Error, ex.ToString());
//Console.WriteLine(ex.ToString());
//EventLog.WriteEntry("HttpServer", ex.ToString(), EventLogEntryType.Error);
sender.Send(Error500(ex.Message));
}
}
}
private string Error500(string msg)
{
return "<html><head><title>500 Internal Server Error</title></head><br>\r\n"
+ "<body><br>\r\n"
+ "<b>500</b> Internal Server Error<br>" + msg + "\r\n"
+ "</body><br>\r\n"
+ "</html><br>\r\n";
}
/*
protected override void SessionEnded(NetworkSession session)
{
// verify wether there are no active connections related to the session
foreach (HTTPConnection c in Connections)//.Values)
{
if (c.Session == session)
{
session.Refresh();
return;
}
}
foreach (Instance instance in Instance.Children)
{
var f = (HTTPFilter)instance.Resource;
f.SessionExpired((HTTPSession)session);
}
base.SessionEnded((HTTPSession)session);
//Sessions.Remove(Session.ID);
//Session.Dispose();
}
*/
/*
public int TTL
{
get
{
return Timeout;// mTimeout;
}
}
*/
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
{
if (trigger == ResourceTrigger.Initialize)
{
//var ip = (IPAddress)Instance.Attributes["ip"];
//var port = (int)Instance.Attributes["port"];
//var ssl = (bool)Instance.Attributes["ssl"];
//var cert = (string)Instance.Attributes["certificate"];
//if (ip == null) ip = IPAddress.Any;
ISocket listener;
IPAddress ipAdd;
if (ip == null)
ipAdd = IPAddress.Any;
else
ipAdd = IPAddress.Parse(ip);
// if (ssl)
// listener = new SSLSocket(new IPEndPoint(ipAdd, port), new X509Certificate2(certificate));
// else
listener = new TCPSocket(new IPEndPoint(ipAdd, port));
Start(listener,
timeout,
clock);
}
else if (trigger == ResourceTrigger.Terminate)
{
Stop();
}
else if (trigger == ResourceTrigger.SystemReload)
{
Trigger(ResourceTrigger.Terminate);
Trigger(ResourceTrigger.Initialize);
}
else if (trigger == ResourceTrigger.SystemInitialized)
{
Instance.Children<HTTPFilter>().Then(x => filters = x);
}
return new AsyncReply<bool>(true);
}
protected override void ClientConnected(HTTPConnection sender)
{
//sender.SessionModified += SessionModified;
//sender.SessionEnded += SessionExpired;
sender.SetParent(this);
//Console.WriteLine("IN: " + this.Connections.Count);
foreach (var resource in filters)
{
resource.ClientConnected(sender);
}
}
public void Destroy()
{
}
/*
public int LocalPort
{
get
{
return cServer.LocalPort;
}
}
*/
/*
public HTTPServer(int Port)
{
cServer = new TServer();
cServer.LocalPort = Port;
cServer.StartServer();
cServer.ClientConnected += new TServer.eClientConnected(ClientConnected);
cServer.ClientDisConnected += new TServer.eClientDisConnected(ClientDisConnected);
cServer.ClientIsSwitching += new TServer.eClientIsSwitching(ClientIsSwitching);
cServer.DataReceived += new TServer.eDataReceived(DataReceived);
}*/
//~HTTPServer()
//{
// cServer.StopServer();
//}
}
}

View File

@ -1,130 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Net;
using System.Collections;
using System.Collections.Generic;
using Esiur.Data;
using Esiur.Misc;
using Esiur.Core;
namespace Esiur.Net.HTTP
{
public class HTTPSession : IDestructible //<T> where T : TClient
{
public delegate void SessionModifiedEvent(HTTPSession session, string key, object oldValue, object newValue);
public delegate void SessionEndedEvent(HTTPSession session);
private string id;
private Timer timer;
private int timeout;
DateTime creation;
DateTime lastAction;
private KeyList<string, object> variables;
public event SessionEndedEvent OnEnd;
public event SessionModifiedEvent OnModify;
public event DestroyedEvent OnDestroy;
public KeyList<string, object> Variables
{
get { return variables; }
}
public HTTPSession()
{
variables = new KeyList<string, object>();
variables.OnModified += new KeyList<string, object>.Modified(VariablesModified);
creation = DateTime.Now;
}
internal void Set(string id, int timeout)
{
//modified = sessionModifiedEvent;
//ended = sessionEndEvent;
this.id = id;
if (this.timeout != 0)
{
this.timeout = timeout;
timer = new Timer(OnSessionEndTimerCallback, null, TimeSpan.FromSeconds(timeout), TimeSpan.FromSeconds(0));
creation = DateTime.Now;
}
}
private void OnSessionEndTimerCallback(object o)
{
OnEnd?.Invoke(this);
}
void VariablesModified(string key, object oldValue, object newValue, KeyList<string, object> sender)
{
OnModify?.Invoke(this, key, oldValue, newValue);
}
public void Destroy()
{
OnDestroy?.Invoke(this);
timer.Dispose();
timer = null;
}
internal void Refresh()
{
lastAction = DateTime.Now;
timer.Change(TimeSpan.FromSeconds(timeout), TimeSpan.FromSeconds(0));
}
public int Timeout // Seconds
{
get
{
return timeout;
}
set
{
timeout = value;
Refresh();
}
}
public string Id
{
get { return id; }
}
public DateTime LastAction
{
get { return lastAction; }
}
}
}

View File

@ -1,125 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Esiur.Resource;
using Esiur.Net.IIP;
using Esiur.Net.Sockets;
using Esiur.Core;
namespace Esiur.Net.HTTP
{
public class IIPoWS: HTTPFilter
{
[ResourceProperty]
public DistributedServer DistributedServer
{
get;
set;
}
public override bool Execute(HTTPConnection sender)
{
if (sender.IsWebsocketRequest())
{
if (DistributedServer == null)
return false;
var tcpSocket = sender.Unassign();
if (tcpSocket == null)
return false;
var httpServer = sender.Parent;
var wsSocket = new WSSocket(tcpSocket);
httpServer.RemoveConnection(sender);
var iipConnection = new DistributedConnection();
DistributedServer.AddConnection(iipConnection);
iipConnection.Assign(wsSocket);
wsSocket.Begin();
return true;
}
return false;
/*
if (sender.Request.Filename.StartsWith("/iip/"))
{
// find the service
var path = sender.Request.Filename.Substring(5);// sender.Request.Query["path"];
Warehouse.Get(path).Then((r) =>
{
if (r is DistributedServer)
{
var httpServer = sender.Parent;
var iipServer = r as DistributedServer;
var tcpSocket = sender.Unassign();
if (tcpSocket == null)
return;
var wsSocket = new WSSocket(tcpSocket);
httpServer.RemoveConnection(sender);
//httpServer.Connections.Remove(sender);
var iipConnection = new DistributedConnection();
// iipConnection.OnReady += IipConnection_OnReady;
// iipConnection.Server = iipServer;
// iipConnection.Assign(wsSocket);
iipServer.AddConnection(iipConnection);
iipConnection.Assign(wsSocket);
wsSocket.Begin();
}
});
return true;
}
return false;
*/
}
private void IipConnection_OnReady(DistributedConnection sender)
{
Warehouse.Put(sender, sender.RemoteUsername, null, sender.Server);
}
public override AsyncReply<bool> Trigger(ResourceTrigger trigger)
{
return new AsyncReply<bool>(true);
}
}
}

View File

@ -1,922 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using Esiur.Net.Sockets;
using Esiur.Data;
using Esiur.Misc;
using Esiur.Core;
using Esiur.Net.Packets;
using Esiur.Resource;
using Esiur.Security.Authority;
using Esiur.Resource.Template;
using System.Linq;
using System.Diagnostics;
using static Esiur.Net.Packets.IIPPacket;
namespace Esiur.Net.IIP
{
public partial class DistributedConnection : NetworkConnection, IStore
{
public delegate void ReadyEvent(DistributedConnection sender);
public delegate void ErrorEvent(DistributedConnection sender, byte errorCode, string errorMessage);
/// <summary>
/// Ready event is raised when the connection is fully established.
/// </summary>
public event ReadyEvent OnReady;
/// <summary>
/// Error event
/// </summary>
public event ErrorEvent OnError;
IIPPacket packet = new IIPPacket();
IIPAuthPacket authPacket = new IIPAuthPacket();
Session session;
List<IResource> attachedResources = new List<IResource>();
AsyncReply<bool> openReply;
byte[] localPassword;
byte[] localNonce, remoteNonce;
bool ready, readyToEstablish;
DateTime loginDate;
/// <summary>
/// Local username to authenticate ourselves.
/// </summary>
public string LocalUsername => session.LocalAuthentication.Username;// { get; set; }
/// <summary>
/// Peer's username.
/// </summary>
public string RemoteUsername => session.RemoteAuthentication.Username;// { get; set; }
/// <summary>
/// Working domain.
/// </summary>
//public string Domain { get { return domain; } }
/// <summary>
/// The session related to this connection.
/// </summary>
public Session Session => session;
/// <summary>
/// Distributed server responsible for this connection, usually for incoming connections.
/// </summary>
public DistributedServer Server
{
get;
set;
}
public bool Remove(IResource resource)
{
// nothing to do
return true;
}
/// <summary>
/// Send data to the other end as parameters
/// </summary>
/// <param name="values">Values will be converted to bytes then sent.</param>
internal SendList SendParams(IAsyncReply<object[]> reply = null)//params object[] values)
{
return new SendList(this, reply);
/*
var data = BinaryList.ToBytes(values);
if (ready)
{
var cmd = (IIPPacketCommand)(data[0] >> 6);
if (cmd == IIPPacketCommand.Event)
{
var evt = (IIPPacketEvent)(data[0] & 0x3f);
//Console.Write("Sent: " + cmd.ToString() + " " + evt.ToString());
}
else if (cmd == IIPPacketCommand.Report)
{
var r = (IIPPacketReport)(data[0] & 0x3f);
//Console.Write("Sent: " + cmd.ToString() + " " + r.ToString());
}
else
{
var act = (IIPPacketAction)(data[0] & 0x3f);
//Console.Write("Sent: " + cmd.ToString() + " " + act.ToString());
}
//foreach (var param in values)
// Console.Write(", " + param);
//Console.WriteLine();
}
Send(data);
//StackTrace stackTrace = new StackTrace(;
// Get calling method name
//Console.WriteLine("TX " + hostType + " " + ar.Length + " " + stackTrace.GetFrame(1).GetMethod().ToString());
*/
}
/// <summary>
/// Send raw data through the connection.
/// </summary>
/// <param name="data">Data to send.</param>
public override void Send(byte[] data)
{
//Console.WriteLine("Client: {0}", Data.Length);
Global.Counters["IIP Sent Packets"]++;
base.Send(data);
}
/// <summary>
/// KeyList to store user variables related to this connection.
/// </summary>
public KeyList<string, object> Variables { get; } = new KeyList<string, object>();
/// <summary>
/// IResource interface.
/// </summary>
public Instance Instance
{
get;
set;
}
/// <summary>
/// Assign a socket to the connection.
/// </summary>
/// <param name="socket">Any socket that implements ISocket.</param>
public override void Assign(ISocket socket)
{
base.Assign(socket);
session.RemoteAuthentication.Source.Attributes.Add(SourceAttributeType.IPv4, socket.RemoteEndPoint.Address);
session.RemoteAuthentication.Source.Attributes.Add(SourceAttributeType.Port, socket.RemoteEndPoint.Port);
session.LocalAuthentication.Source.Attributes.Add(SourceAttributeType.IPv4, socket.LocalEndPoint.Address);
session.LocalAuthentication.Source.Attributes.Add(SourceAttributeType.Port, socket.LocalEndPoint.Port);
if (session.LocalAuthentication.Type == AuthenticationType.Client)
{
// declare (Credentials -> No Auth, No Enctypt)
var un = DC.ToBytes(session.LocalAuthentication.Username);
var dmn = DC.ToBytes(session.LocalAuthentication.Domain);// domain);
if (socket.State == SocketState.Established)
{
SendParams()
.AddUInt8(0x60)
.AddUInt8((byte)dmn.Length)
.AddUInt8Array(dmn)
.AddUInt8Array(localNonce)
.AddUInt8((byte)un.Length)
.AddUInt8Array(un)
.Done();//, dmn, localNonce, (byte)un.Length, un);
}
else
{
socket.OnConnect += () =>
{ // declare (Credentials -> No Auth, No Enctypt)
//SendParams((byte)0x60, (byte)dmn.Length, dmn, localNonce, (byte)un.Length, un);
SendParams()
.AddUInt8(0x60)
.AddUInt8((byte)dmn.Length)
.AddUInt8Array(dmn)
.AddUInt8Array(localNonce)
.AddUInt8((byte)un.Length)
.AddUInt8Array(un)
.Done();
};
}
}
}
/// <summary>
/// Create a new distributed connection.
/// </summary>
/// <param name="socket">Socket to transfer data through.</param>
/// <param name="domain">Working domain.</param>
/// <param name="username">Username.</param>
/// <param name="password">Password.</param>
public DistributedConnection(ISocket socket, string domain, string username, string password)
{
this.session = new Session( new ClientAuthentication()
, new HostAuthentication());
//Instance.Name = Global.GenerateCode(12);
//this.hostType = AuthenticationType.Client;
//this.domain = domain;
//this.localUsername = username;
session.LocalAuthentication.Domain = domain;
session.LocalAuthentication.Username = username;
this.localPassword = DC.ToBytes(password);
init();
Assign(socket);
}
/// <summary>
/// Create a new instance of a distributed connection
/// </summary>
public DistributedConnection()
{
//myId = Global.GenerateCode(12);
// localParams.Host = DistributedParameters.HostType.Host;
session = new Session(new HostAuthentication(), new ClientAuthentication());
init();
}
public string Link(IResource resource)
{
if (resource is DistributedResource)
{
var r = resource as DistributedResource;
if (r.Instance.Store == this)
return this.Instance.Name + "/" + r.Id;
}
return null;
}
void init()
{
var q = queue;
q.Then((x) =>
{
if (x.Type == DistributedResourceQueueItem.DistributedResourceQueueItemType.Event)
x.Resource._EmitEventByIndex(x.Index, (object[])x.Value);
else
x.Resource._UpdatePropertyByIndex(x.Index, x.Value);
});
//q.timeout?.Dispose();
var r = new Random();
localNonce = new byte[32];
r.NextBytes(localNonce);
}
private uint processPacket(byte[] msg, uint offset, uint ends, NetworkBuffer data, int chunkId)
{
//var packet = new IIPPacket();
// packets++;
if (ready)
{
var rt = packet.Parse(msg, offset, ends);
//Console.WriteLine("Rec: " + chunkId + " " + packet.ToString());
/*
if (packet.Command == IIPPacketCommand.Event)
Console.WriteLine("Rec: " + packet.Command.ToString() + " " + packet.Event.ToString());
else if (packet.Command == IIPPacketCommand.Report)
Console.WriteLine("Rec: " + packet.Command.ToString() + " " + packet.Report.ToString());
else
Console.WriteLine("Rec: " + packet.Command.ToString() + " " + packet.Action.ToString() + " " + packet.ResourceId + " " + offset + "/" + ends);
*/
//packs.Add(packet.Command.ToString() + " " + packet.Action.ToString() + " " + packet.Event.ToString());
//if (packs.Count > 1)
// Console.WriteLine("P2");
//Console.WriteLine("");
if (rt <= 0)
{
//Console.WriteLine("Hold");
var size = ends - offset;
data.HoldFor(msg, offset, size, size + (uint)(-rt));
return ends;
}
else
{
//Console.WriteLine($"CMD {packet.Command} {offset} {ends}");
offset += (uint)rt;
if (packet.Command == IIPPacket.IIPPacketCommand.Event)
{
switch (packet.Event)
{
case IIPPacket.IIPPacketEvent.ResourceReassigned:
IIPEventResourceReassigned(packet.ResourceId, packet.NewResourceId);
break;
case IIPPacket.IIPPacketEvent.ResourceDestroyed:
IIPEventResourceDestroyed(packet.ResourceId);
break;
case IIPPacket.IIPPacketEvent.PropertyUpdated:
IIPEventPropertyUpdated(packet.ResourceId, packet.MethodIndex, packet.Content);
break;
case IIPPacket.IIPPacketEvent.EventOccurred:
IIPEventEventOccurred(packet.ResourceId, packet.MethodIndex, packet.Content);
break;
case IIPPacketEvent.ChildAdded:
IIPEventChildAdded(packet.ResourceId, packet.ChildId);
break;
case IIPPacketEvent.ChildRemoved:
IIPEventChildRemoved(packet.ResourceId, packet.ChildId);
break;
case IIPPacketEvent.Renamed:
IIPEventRenamed(packet.ResourceId, packet.Content);
break;
case IIPPacketEvent.AttributesUpdated:
IIPEventAttributesUpdated(packet.ResourceId, packet.Content);
break;
}
}
else if (packet.Command == IIPPacket.IIPPacketCommand.Request)
{
switch (packet.Action)
{
// Manage
case IIPPacket.IIPPacketAction.AttachResource:
IIPRequestAttachResource(packet.CallbackId, packet.ResourceId);
break;
case IIPPacket.IIPPacketAction.ReattachResource:
IIPRequestReattachResource(packet.CallbackId, packet.ResourceId, packet.ResourceAge);
break;
case IIPPacket.IIPPacketAction.DetachResource:
IIPRequestDetachResource(packet.CallbackId, packet.ResourceId);
break;
case IIPPacket.IIPPacketAction.CreateResource:
IIPRequestCreateResource(packet.CallbackId, packet.StoreId, packet.ResourceId, packet.Content);
break;
case IIPPacket.IIPPacketAction.DeleteResource:
IIPRequestDeleteResource(packet.CallbackId, packet.ResourceId);
break;
case IIPPacketAction.AddChild:
IIPRequestAddChild(packet.CallbackId, packet.ResourceId, packet.ChildId);
break;
case IIPPacketAction.RemoveChild:
IIPRequestRemoveChild(packet.CallbackId, packet.ResourceId, packet.ChildId);
break;
case IIPPacketAction.RenameResource:
IIPRequestRenameResource(packet.CallbackId, packet.ResourceId, packet.Content);
break;
// Inquire
case IIPPacket.IIPPacketAction.TemplateFromClassName:
IIPRequestTemplateFromClassName(packet.CallbackId, packet.ClassName);
break;
case IIPPacket.IIPPacketAction.TemplateFromClassId:
IIPRequestTemplateFromClassId(packet.CallbackId, packet.ClassId);
break;
case IIPPacket.IIPPacketAction.TemplateFromResourceId:
IIPRequestTemplateFromResourceId(packet.CallbackId, packet.ResourceId);
break;
case IIPPacketAction.QueryLink:
IIPRequestQueryResources(packet.CallbackId, packet.ResourceLink);
break;
case IIPPacketAction.ResourceChildren:
IIPRequestResourceChildren(packet.CallbackId, packet.ResourceId);
break;
case IIPPacketAction.ResourceParents:
IIPRequestResourceParents(packet.CallbackId, packet.ResourceId);
break;
case IIPPacket.IIPPacketAction.ResourceHistory:
IIPRequestInquireResourceHistory(packet.CallbackId, packet.ResourceId, packet.FromDate, packet.ToDate);
break;
// Invoke
case IIPPacket.IIPPacketAction.InvokeFunctionArrayArguments:
IIPRequestInvokeFunctionArrayArguments(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.Content);
break;
case IIPPacket.IIPPacketAction.InvokeFunctionNamedArguments:
IIPRequestInvokeFunctionNamedArguments(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.Content);
break;
case IIPPacket.IIPPacketAction.GetProperty:
IIPRequestGetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex);
break;
case IIPPacket.IIPPacketAction.GetPropertyIfModified:
IIPRequestGetPropertyIfModifiedSince(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.ResourceAge);
break;
case IIPPacket.IIPPacketAction.SetProperty:
IIPRequestSetProperty(packet.CallbackId, packet.ResourceId, packet.MethodIndex, packet.Content);
break;
// Attribute
case IIPPacketAction.GetAllAttributes:
IIPRequestGetAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
break;
case IIPPacketAction.UpdateAllAttributes:
IIPRequestUpdateAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
break;
case IIPPacketAction.ClearAllAttributes:
IIPRequestClearAttributes(packet.CallbackId, packet.ResourceId, packet.Content, true);
break;
case IIPPacketAction.GetAttributes:
IIPRequestGetAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
break;
case IIPPacketAction.UpdateAttributes:
IIPRequestUpdateAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
break;
case IIPPacketAction.ClearAttributes:
IIPRequestClearAttributes(packet.CallbackId, packet.ResourceId, packet.Content, false);
break;
}
}
else if (packet.Command == IIPPacket.IIPPacketCommand.Reply)
{
switch (packet.Action)
{
// Manage
case IIPPacket.IIPPacketAction.AttachResource:
IIPReply(packet.CallbackId, packet.ClassId, packet.ResourceAge, packet.ResourceLink, packet.Content);
break;
case IIPPacket.IIPPacketAction.ReattachResource:
IIPReply(packet.CallbackId, packet.ResourceAge, packet.Content);
break;
case IIPPacket.IIPPacketAction.DetachResource:
IIPReply(packet.CallbackId);
break;
case IIPPacket.IIPPacketAction.CreateResource:
IIPReply(packet.CallbackId, packet.ResourceId);
break;
case IIPPacket.IIPPacketAction.DeleteResource:
case IIPPacketAction.AddChild:
case IIPPacketAction.RemoveChild:
case IIPPacketAction.RenameResource:
IIPReply(packet.CallbackId);
break;
// Inquire
case IIPPacket.IIPPacketAction.TemplateFromClassName:
case IIPPacket.IIPPacketAction.TemplateFromClassId:
case IIPPacket.IIPPacketAction.TemplateFromResourceId:
IIPReply(packet.CallbackId, ResourceTemplate.Parse(packet.Content));
break;
case IIPPacketAction.QueryLink:
case IIPPacketAction.ResourceChildren:
case IIPPacketAction.ResourceParents:
case IIPPacketAction.ResourceHistory:
IIPReply(packet.CallbackId, packet.Content);
break;
// Invoke
case IIPPacket.IIPPacketAction.InvokeFunctionArrayArguments:
case IIPPacket.IIPPacketAction.InvokeFunctionNamedArguments:
IIPReplyInvoke(packet.CallbackId, packet.Content);
break;
case IIPPacket.IIPPacketAction.GetProperty:
IIPReply(packet.CallbackId, packet.Content);
break;
case IIPPacket.IIPPacketAction.GetPropertyIfModified:
IIPReply(packet.CallbackId, packet.Content);
break;
case IIPPacket.IIPPacketAction.SetProperty:
IIPReply(packet.CallbackId);
break;
// Attribute
case IIPPacketAction.GetAllAttributes:
case IIPPacketAction.GetAttributes:
IIPReply(packet.CallbackId, packet.Content);
break;
case IIPPacketAction.UpdateAllAttributes:
case IIPPacketAction.UpdateAttributes:
case IIPPacketAction.ClearAllAttributes:
case IIPPacketAction.ClearAttributes:
IIPReply(packet.CallbackId);
break;
}
}
else if (packet.Command == IIPPacketCommand.Report)
{
switch (packet.Report)
{
case IIPPacketReport.ManagementError:
IIPReportError(packet.CallbackId, ErrorType.Management, packet.ErrorCode, null);
break;
case IIPPacketReport.ExecutionError:
IIPReportError(packet.CallbackId, ErrorType.Exception, packet.ErrorCode, packet.ErrorMessage);
break;
case IIPPacketReport.ProgressReport:
IIPReportProgress(packet.CallbackId, ProgressType.Execution, packet.ProgressValue, packet.ProgressMax);
break;
case IIPPacketReport.ChunkStream:
IIPReportChunk(packet.CallbackId, packet.Content);
break;
}
}
}
}
else
{
var rt = authPacket.Parse(msg, offset, ends);
//Console.WriteLine(session.LocalAuthentication.Type.ToString() + " " + offset + " " + ends + " " + rt + " " + authPacket.ToString());
if (rt <= 0)
{
data.HoldFor(msg, ends + (uint)(-rt));
return ends;
}
else
{
offset += (uint)rt;
if (session.LocalAuthentication.Type == AuthenticationType.Host)
{
if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Declare)
{
if (authPacket.RemoteMethod == IIPAuthPacket.IIPAuthPacketMethod.Credentials && authPacket.LocalMethod == IIPAuthPacket.IIPAuthPacketMethod.None)
{
Server.Membership.UserExists(authPacket.RemoteUsername, authPacket.Domain).Then(x =>
{
if (x)
{
session.RemoteAuthentication.Username = authPacket.RemoteUsername;
remoteNonce = authPacket.RemoteNonce;
session.RemoteAuthentication.Domain = authPacket.Domain;
SendParams()
.AddUInt8(0xa0)
.AddUInt8Array(localNonce)
.Done();
//SendParams((byte)0xa0, localNonce);
}
else
{
//Console.WriteLine("User not found");
//SendParams((byte)0xc0, (byte)1, (ushort)14, DC.ToBytes("User not found"));
SendParams().AddUInt8(0xc0).AddUInt8(1).AddUInt16(14).AddString("User not found").Done();
}
});
}
}
else if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Action)
{
if (authPacket.Action == IIPAuthPacket.IIPAuthPacketAction.AuthenticateHash)
{
var remoteHash = authPacket.Hash;
Server.Membership.GetPassword(session.RemoteAuthentication.Username,
session.RemoteAuthentication.Domain).Then((pw) =>
{
if (pw != null)
{
var hashFunc = SHA256.Create();
//var hash = hashFunc.ComputeHash(BinaryList.ToBytes(pw, remoteNonce, localNonce));
var hash = hashFunc.ComputeHash((new BinaryList())
.AddUInt8Array(pw)
.AddUInt8Array( remoteNonce)
.AddUInt8Array(localNonce)
.ToArray());
if (hash.SequenceEqual(remoteHash))
{
// send our hash
//var localHash = hashFunc.ComputeHash(BinaryList.ToBytes(localNonce, remoteNonce, pw));
//SendParams((byte)0, localHash);
var localHash = hashFunc.ComputeHash((new BinaryList()).AddUInt8Array(localNonce).AddUInt8Array(remoteNonce).AddUInt8Array(pw).ToArray());
SendParams().AddUInt8(0).AddUInt8Array(localHash).Done();
readyToEstablish = true;
}
else
{
//Global.Log("auth", LogType.Warning, "U:" + RemoteUsername + " IP:" + Socket.RemoteEndPoint.Address.ToString() + " S:DENIED");
//Console.WriteLine("Incorrect password");
//SendParams((byte)0xc0, (byte)1, (ushort)5, DC.ToBytes("Error"));
SendParams().AddUInt8(0xc0).AddUInt8(1).AddUInt16(5).AddString("Error").Done();
}
}
});
}
else if (authPacket.Action == IIPAuthPacket.IIPAuthPacketAction.NewConnection)
{
if (readyToEstablish)
{
var r = new Random();
session.Id = new byte[32];
r.NextBytes(session.Id);
//SendParams((byte)0x28, session.Id);
SendParams()
.AddUInt8(0x28)
.AddUInt8Array(session.Id)
.Done();
ready = true;
openReply?.Trigger(true);
OnReady?.Invoke(this);
Server.Membership.Login(session);
//Global.Log("auth", LogType.Warning, "U:" + RemoteUsername + " IP:" + Socket.RemoteEndPoint.Address.ToString() + " S:AUTH");
}
}
}
}
else if (session.LocalAuthentication.Type == AuthenticationType.Client)
{
if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Acknowledge)
{
remoteNonce = authPacket.RemoteNonce;
// send our hash
var hashFunc = SHA256.Create();
//var localHash = hashFunc.ComputeHash(BinaryList.ToBytes(localPassword, localNonce, remoteNonce));
var localHash = hashFunc.ComputeHash(new BinaryList()
.AddUInt8Array(localPassword)
.AddUInt8Array(localNonce)
.AddUInt8Array(remoteNonce)
.ToArray());
SendParams()
.AddUInt8(0)
.AddUInt8Array(localHash)
.Done();
//SendParams((byte)0, localHash);
}
else if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Action)
{
if (authPacket.Action == IIPAuthPacket.IIPAuthPacketAction.AuthenticateHash)
{
// check if the server knows my password
var hashFunc = SHA256.Create();
//var remoteHash = hashFunc.ComputeHash(BinaryList.ToBytes(remoteNonce, localNonce, localPassword));
var remoteHash = hashFunc.ComputeHash(new BinaryList()
.AddUInt8Array(remoteNonce)
.AddUInt8Array(localNonce)
.AddUInt8Array(localPassword)
.ToArray());
if (remoteHash.SequenceEqual(authPacket.Hash))
{
// send establish request
//SendParams((byte)0x20, (ushort)0);
SendParams()
.AddUInt8(0x20)
.AddUInt16(0)
.Done();
}
else
{
SendParams()
.AddUInt8(0xc0)
.AddUInt8(1)
.AddUInt16(5)
.AddString("Error")
.Done();
//SendParams((byte)0xc0, 1, (ushort)5, DC.ToBytes("Error"));
}
}
else if (authPacket.Action == IIPAuthPacket.IIPAuthPacketAction.ConnectionEstablished)
{
session.Id = authPacket.SessionId;
ready = true;
openReply?.Trigger(true);
OnReady?.Invoke(this);
}
}
else if (authPacket.Command == IIPAuthPacket.IIPAuthPacketCommand.Error)
{
openReply?.TriggerError(new AsyncException(ErrorType.Management, authPacket.ErrorCode, authPacket.ErrorMessage));
OnError?.Invoke(this, authPacket.ErrorCode, authPacket.ErrorMessage);
Close();
}
}
}
}
return offset;
//if (offset < ends)
// processPacket(msg, offset, ends, data, chunkId);
}
protected override void DataReceived(NetworkBuffer data)
{
// Console.WriteLine("DR " + hostType + " " + data.Available + " " + RemoteEndPoint.ToString());
var msg = data.Read();
uint offset = 0;
uint ends = (uint)msg.Length;
var packs = new List<string>();
var chunkId = (new Random()).Next(1000, 1000000);
var list = new List<Structure>();// double, IIPPacketCommand>();
this.Socket.Hold();
while (offset < ends)
{
offset = processPacket(msg, offset, ends, data, chunkId);
}
this.Socket.Unhold();
}
/// <summary>
/// Resource interface
/// </summary>
/// <param name="trigger">Resource trigger.</param>
/// <returns></returns>
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
{
if (trigger == ResourceTrigger.Open)
{
if (Instance.Attributes.ContainsKey("username")
&& Instance.Attributes.ContainsKey("password"))
{
//var hostname = String.Join("://", Instance.Name.Split(new string[] { "://" }, StringSplitOptions.None).Skip(1)).Split('/')[0];
// assign domain from hostname if not provided
var host = Instance.Name.Split(':');
var address = host[0];// hostname.Split(':')[0];
var port = ushort.Parse(host[1]);// hostname.Split(':')[1]);
var username = Instance.Attributes["username"].ToString();
var domain = Instance.Attributes.ContainsKey("domain") ? Instance.Attributes["domain"].ToString() : address;
session = new Session(new ClientAuthentication()
, new HostAuthentication());
session.LocalAuthentication.Domain = domain;
session.LocalAuthentication.Username = username;
localPassword = DC.ToBytes(Instance.Attributes["password"].ToString());
openReply = new AsyncReply<bool>();
var sock = new TCPSocket();
sock.Connect(domain, port).Then((x)=> {
Assign(sock);
//rt.trigger(true);
}).Error((x) =>
openReply.TriggerError(x)
);
return openReply;
}
}
return new AsyncReply<bool>();
}
/// <summary>
/// Store interface.
/// </summary>
/// <param name="resource">Resource.</param>
/// <returns></returns>
public bool Put(IResource resource)
{
if (Codec.IsLocalResource(resource, this))
resources.Add((resource as DistributedResource).Id, (DistributedResource)resource);
// else ... send it to the peer
return true;
}
public bool Record(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
{
// nothing to do
return true;
}
public bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime)
{
// nothing to do
return true;
}
AsyncReply<bool> IStore.AddChild(IResource parent, IResource child)
{
// not implemented
throw new NotImplementedException();
}
AsyncReply<bool> IStore.RemoveChild(IResource parent, IResource child)
{
// not implemeneted
throw new NotImplementedException();
}
public AsyncReply<bool> AddParent(IResource child, IResource parent)
{
throw new NotImplementedException();
}
public AsyncReply<bool> RemoveParent(IResource child, IResource parent)
{
throw new NotImplementedException();
}
public AsyncBag<T> Children<T>(IResource resource, string name) where T : IResource
{
throw new Exception("SS");
//if (Codec.IsLocalResource(resource, this))
// return new AsyncBag<T>((resource as DistributedResource).children.Where(x => x.GetType() == typeof(T)).Select(x => (T)x));
return null;
}
public AsyncBag<T> Parents<T>(IResource resource, string name) where T : IResource
{
throw new Exception("SS");
//if (Codec.IsLocalResource(resource, this))
// return (resource as DistributedResource).parents.Where(x => x.GetType() == typeof(T)).Select(x => (T)x);
return null;
}
/*
public AsyncBag<T> Children<T>(IResource resource)
{
if (Codec.IsLocalResource(resource, this))
return (resource as DistributedResource).children.Where(x => x.GetType() == typeof(T)).Select(x => (T)x);
return null;
}
public AsyncBag<T> Parents<T>(IResource resource)
{
if (Codec.IsLocalResource(resource, this))
return (resource as DistributedResource).parents.Where(x => x.GetType() == typeof(T)).Select(x => (T)x);
return null;
}
*/
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.IIP
{
public class DistributedPropertyContext
{
public object Value { get; private set; }
public DistributedConnection Connection { get; private set; }
public Func<DistributedConnection, object> Method { get; private set; }
public DistributedPropertyContext(DistributedConnection connection, object value)
{
this.Value = value;
this.Connection = connection;
}
public DistributedPropertyContext(Func<DistributedConnection, object> method)
{
this.Method = method;
}
}
}

View File

@ -1,476 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.IO;
using System.Collections;
using System.ComponentModel;
using Esiur.Misc;
using Esiur.Data;
using System.Dynamic;
using System.Security.Cryptography;
using Esiur.Core;
using System.Runtime.CompilerServices;
using System.Reflection.Emit;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Esiur.Resource;
using Esiur.Resource.Template;
namespace Esiur.Net.IIP
{
//[System.Runtime.InteropServices.ComVisible(true)]
public class DistributedResource : DynamicObject, IResource
{
/// <summary>
/// Raised when the distributed resource is destroyed.
/// </summary>
public event DestroyedEvent OnDestroy;
public event Instance.ResourceModifiedEvent OnModified;
uint instanceId;
DistributedConnection connection;
bool isAttached = false;
bool isReady = false;
//Structure properties = new Structure();
string link;
//ulong age;
//ulong[] ages;
object[] properties;
internal List<DistributedResource> parents = new List<DistributedResource>();
internal List<DistributedResource> children = new List<DistributedResource>();
DistributedResourceEvent[] events;
//ResourceTemplate template;
//DistributedResourceStack stack;
bool destroyed;
/*
Dictionary<AsyncReply, object> afterAttachmentTriggers = new Dictionary<AsyncReply, object>();
internal void AddAfterAttachement(AsyncReply trigger, object value)
{
afterAttachmentTriggers.Add(trigger, value);
}
*/
/// <summary>
/// Resource template for the remotely located resource.
/// </summary>
//public ResourceTemplate Template
//{
// get { return template; }
//}
/// <summary>
/// Connection responsible for the distributed resource.
/// </summary>
public DistributedConnection Connection
{
get { return connection; }
}
/// <summary>
/// Resource link
/// </summary>
public string Link
{
get { return link; }
}
/// <summary>
/// Instance Id given by the other end.
/// </summary>
public uint Id
{
get { return instanceId; }
}
/// <summary>
/// IDestructible interface.
/// </summary>
public void Destroy()
{
destroyed = true;
OnDestroy?.Invoke(this);
}
/// <summary>
/// Resource is ready when all its properties are attached.
/// </summary>
internal bool IsReady
{
get
{
return isReady;
}
}
/// <summary>
/// Resource is attached when all its properties are received.
/// </summary>
internal bool IsAttached
{
get
{
return isAttached;
}
}
// public DistributedResourceStack Stack
//{
// get { return stack; }
//}
/// <summary>
/// Create a new distributed resource.
/// </summary>
/// <param name="connection">Connection responsible for the distributed resource.</param>
/// <param name="template">Resource template.</param>
/// <param name="instanceId">Instance Id given by the other end.</param>
/// <param name="age">Resource age.</param>
public DistributedResource(DistributedConnection connection, uint instanceId, ulong age, string link)
{
this.link = link;
this.connection = connection;
this.instanceId = instanceId;
//this.Instance.Template = template;
//this.Instance.Age = age;
//this.template = template;
//this.age = age;
}
internal void _Ready()
{
isReady = true;
}
/// <summary>
/// Export all properties with ResourceProperty attributed as bytes array.
/// </summary>
/// <returns></returns>
internal PropertyValue[] _Serialize()
{
var props = new PropertyValue[properties.Length];
for (byte i = 0; i < properties.Length; i++)
props[i] = new PropertyValue(properties[i], Instance.GetAge(i), Instance.GetModificationDate(i));
return props;
}
internal bool _Attached(PropertyValue[] properties)
{
if (isAttached)
return false;
else
{
this.properties = new object[properties.Length];
this.events = new DistributedResourceEvent[Instance.Template.Events.Length];
for (byte i = 0; i < properties.Length; i++)
{
Instance.SetAge(i, properties[i].Age);
Instance.SetModificationDate(i, properties[i].Date);
this.properties[i] = properties[i].Value;
}
// trigger holded events/property updates.
//foreach (var r in afterAttachmentTriggers)
// r.Key.Trigger(r.Value);
//afterAttachmentTriggers.Clear();
isAttached = true;
}
return true;
}
internal void _EmitEventByIndex(byte index, object[] args)
{
var et = Instance.Template.GetEventTemplateByIndex(index);
events[index]?.Invoke(this, args);
Instance.EmitResourceEvent(null, null, et.Name, args);
}
public AsyncReply<object> _InvokeByNamedArguments(byte index, Structure namedArgs)
{
if (destroyed)
throw new Exception("Trying to access destroyed object");
if (index >= Instance.Template.Functions.Length)
throw new Exception("Function index is incorrect");
return connection.SendInvokeByNamedArguments(instanceId, index, namedArgs);
}
public AsyncReply<object> _InvokeByArrayArguments(byte index, object[] args)
{
if (destroyed)
throw new Exception("Trying to access destroyed object");
if (index >= Instance.Template.Functions.Length)
throw new Exception("Function index is incorrect");
return connection.SendInvokeByArrayArguments(instanceId, index, args);
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
var ft = Instance.Template.GetFunctionTemplateByName(binder.Name);
var reply = new AsyncReply<object>();
if (isAttached && ft!=null)
{
if (args.Length == 1)
{
// Detect anonymous types
var type = args[0].GetType();
if (Codec.IsAnonymous(type))
{
var namedArgs = new Structure();
var pi = type.GetTypeInfo().GetProperties();
foreach (var p in pi)
namedArgs[p.Name] = p.GetValue(args[0]);
result = _InvokeByNamedArguments(ft.Index, namedArgs);
}
else
{
result = _InvokeByArrayArguments(ft.Index, args);
}
}
else
{
result = _InvokeByArrayArguments(ft.Index, args);
}
return true;
}
else
{
result = null;
return false;
}
}
/// <summary>
/// Get a property value.
/// </summary>
/// <param name="index">Zero-based property index.</param>
/// <returns>Value</returns>
internal object _Get(byte index)
{
if (index >= properties.Length)
return null;
return properties[index];
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (destroyed)
throw new Exception("Trying to access destroyed object");
result = null;
if (!isAttached)
return false;
var pt = Instance.Template.GetPropertyTemplateByName(binder.Name);
if (pt != null)
{
result = properties[pt.Index];
return true;
}
else
{
var et = Instance.Template.GetEventTemplateByName(binder.Name);
if (et == null)
return false;
result = events[et.Index];
return true;
}
}
internal void _UpdatePropertyByIndex(byte index, object value)
{
var pt = Instance.Template.GetPropertyTemplateByIndex(index);
properties[index] = value;
Instance.EmitModification(pt, value);
}
/// <summary>
/// Set property value.
/// </summary>
/// <param name="index">Zero-based property index.</param>
/// <param name="value">Value</param>
/// <returns>Indicator when the property is set.</returns>
internal AsyncReply<object> _Set(byte index, object value)
{
if (index >= properties.Length)
return null;
var reply = new AsyncReply<object>();
var parameters = Codec.Compose(value, connection);
connection.SendRequest(Packets.IIPPacket.IIPPacketAction.SetProperty)
.AddUInt32(instanceId)
.AddUInt8(index)
.AddUInt8Array(parameters)
.Done()
.Then((res) =>
{
// not really needed, server will always send property modified,
// this only happens if the programmer forgot to emit in property setter
properties[index] = value;
reply.Trigger(null);
});
return reply;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (destroyed)
throw new Exception("Trying to access destroyed object");
if (!isAttached)
return false;
var pt = Instance.Template.GetPropertyTemplateByName(binder.Name);
if (pt != null)
{
_Set(pt.Index, value);
return true;
}
else
{
var et = Instance.Template.GetEventTemplateByName(binder.Name);
if (et == null)
return false;
events[et.Index] = (DistributedResourceEvent)value;
return true;
}
}
/*
public async void InvokeMethod(byte index, object[] arguments, DistributedConnection sender)
{
// get function parameters
Type t = this.GetType();
MethodInfo mi = t.GetMethod(GetFunctionName(index), BindingFlags.DeclaredOnly |
BindingFlags.Public |
BindingFlags.Instance | BindingFlags.InvokeMethod);
if (mi != null)
{
try
{
var res = await invokeMethod(mi, arguments, sender);
object rt = Codec.Compose(res);
sender.SendParams((byte)0x80, instanceId, index, rt);
}
catch(Exception ex)
{
var msg = ex.InnerException != null ? ex.InnerException.Message : ex.Message;
sender.SendParams((byte)0x8E, instanceId, index, Codec.Compose(msg));
}
}
}
*/
/// <summary>
/// Resource interface.
/// </summary>
public Instance Instance
{
get;
set;
}
/// <summary>
/// Create a new instance of distributed resource.
/// </summary>
public DistributedResource()
{
//stack = new DistributedResourceStack(this);
//this.Instance.ResourceModified += this.OnModified;
}
/// <summary>
/// Resource interface.
/// </summary>
/// <param name="trigger"></param>
/// <returns></returns>
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
{
if (trigger == ResourceTrigger.Initialize)
this.Instance.ResourceModified += this.OnModified;
// do nothing.
return new AsyncReply<bool>(true);
}
}
}

View File

@ -1,34 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Net.IIP
{
public delegate void DistributedResourceEvent(DistributedResource sender, params object[] arguments);
}

View File

@ -1,73 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Net.IIP
{
public class DistributedResourceQueueItem
{
public enum DistributedResourceQueueItemType
{
Propery,
Event
}
DistributedResourceQueueItemType type;
byte index;
object value;
DistributedResource resource;
public DistributedResourceQueueItem(DistributedResource resource, DistributedResourceQueueItemType type, object value, byte index)
{
this.resource = resource;
this.index = index;
this.type = type;
this.value = value;
}
public DistributedResource Resource
{
get { return resource; }
}
public DistributedResourceQueueItemType Type
{
get { return type; }
}
public byte Index
{
get { return index; }
}
public object Value
{
get { return value; }
}
}
}

View File

@ -1,168 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Net.Sockets;
using Esiur.Misc;
using System.Threading;
using Esiur.Data;
using Esiur.Core;
using System.Net;
using Esiur.Resource;
using Esiur.Security.Membership;
namespace Esiur.Net.IIP
{
public class DistributedServer : NetworkServer<DistributedConnection>, IResource
{
//[Storable]
//[ResourceProperty]
public string ip
{
get;
set;
}
//[Storable]
//[ResourceProperty]
public IMembership Membership
{
get;
set;
}
public EntryPoint EntryPoint
{
get;
set;
}
//[Storable]
//[ResourceProperty]
public ushort port
{
get;
set;
}
//[Storable]
//[ResourceProperty]
public uint timeout
{
get;
set;
}
//[Storable]
//[ResourceProperty]
public uint clock
{
get;
set;
}
public Instance Instance
{
get;
set;
}
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
{
if (trigger == ResourceTrigger.Initialize)
{
TCPSocket listener;
if (ip != null)
listener = new TCPSocket(new IPEndPoint(IPAddress.Parse(ip), port));
else
listener = new TCPSocket(new IPEndPoint(IPAddress.Any, port));
Start(listener, timeout, clock);
}
else if (trigger == ResourceTrigger.Terminate)
{
Stop();
}
else if (trigger == ResourceTrigger.SystemReload)
{
Trigger(ResourceTrigger.Terminate);
Trigger(ResourceTrigger.Initialize);
}
return new AsyncReply<bool>(true);
}
protected override void DataReceived(DistributedConnection sender, NetworkBuffer data)
{
//throw new NotImplementedException();
}
private void SessionModified(DistributedConnection session, string key, object newValue)
{
}
protected override void ClientConnected(DistributedConnection sender)
{
//Console.WriteLine("DistributedConnection Client Connected");
}
private void Sender_OnReady(DistributedConnection sender)
{
Warehouse.Put(sender, sender.LocalUsername, null, this);
}
public override void RemoveConnection(DistributedConnection connection)
{
connection.OnReady -= Sender_OnReady;
//connection.Server = null;
base.RemoveConnection(connection);
}
public override void AddConnection(DistributedConnection connection)
{
connection.OnReady += Sender_OnReady;
connection.Server = this;
base.AddConnection(connection);
}
protected override void ClientDisconnected(DistributedConnection sender)
{
sender.Destroy();
Warehouse.Remove(sender);
//Console.WriteLine("DistributedConnection Client Disconnected");
}
}
}

View File

@ -1,38 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Esiur.Net.Sockets;
using Esiur.Security.Authority;
namespace Esiur.Net.IIP
{
public class DistributedSession : NetworkSession
{
Source Source { get; }
Authentication Authentication;
}
}

View File

@ -1,40 +0,0 @@
/*
Copyright (c) 2019 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Esiur.Core;
using Esiur.Data;
using Esiur.Resource;
using Esiur.Resource.Template;
namespace Esiur.Net.IIP
{
public abstract class EntryPoint : Esiur.Resource.Resource
{
public abstract AsyncReply<IResource[]> Query(string path, DistributedConnection sender);
public abstract override bool Create();
}
}

View File

@ -1,208 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Data;
using Esiur.Misc;
namespace Esiur.Net
{
public class NetworkBuffer
{
byte[] data;
uint neededDataLength = 0;
//bool trim;
object syncLock = new object();
//public object SyncLock
//{
// get { return syncLock; }
//}
public NetworkBuffer()
{
data = new byte[0];
}
public bool Protected
{
get
{
return neededDataLength > data.Length;
}
}
public uint Available
{
get
{
return (uint)data.Length;
}
}
//public void HoldForAtLeast(byte[] src, uint offset, uint size, uint needed)
//{
// HoldFor(src, offset, size, needed);
// //trim = false;
//}
//public void HoldForAtLeast(byte[] src, uint needed)
//{
// HoldForAtLeast(src, 0, (uint)src.Length, needed);
//}
public void HoldForNextWrite(byte[] src)
{
//HoldForAtLeast(src, (uint)src.Length + 1);
HoldFor(src, (uint)src.Length + 1);
}
public void HoldForNextWrite(byte[] src, uint offset, uint size)
{
//HoldForAtLeast(src, offset, size, size + 1);
HoldFor(src, offset, size, size + 1);
}
public void HoldFor(byte[] src, uint offset, uint size, uint needed)
{
lock (syncLock)
{
if (size >= needed)
throw new Exception("Size >= Needed !");
//trim = true;
data = DC.Combine(src, offset, size, data, 0, (uint)data.Length);
neededDataLength = needed;
// Console.WriteLine("Hold StackTrace: '{0}'", Environment.StackTrace);
//Console.WriteLine("Holded {0} {1} {2} {3} - {4}", offset, size, needed, data.Length, GetHashCode());
}
}
public void HoldFor(byte[] src, uint needed)
{
HoldFor(src, 0, (uint)src.Length, needed);
}
public bool Protect(byte[] data, uint offset, uint needed)//, bool exact = false)
{
uint dataLength = (uint)data.Length - offset;
// protection
if (dataLength < needed)
{
//if (exact)
// HoldFor(data, offset, dataLength, needed);
//else
//HoldForAtLeast(data, offset, dataLength, needed);
HoldFor(data, offset, dataLength, needed);
return true;
}
else
return false;
}
public void Write(byte[] src)
{
Write(src, 0, (uint)src.Length);
}
public void Write(byte[] src, uint offset, uint length)
{
//if (data.Length > 0)
// Console.WriteLine();
lock(syncLock)
DC.Append(ref data, src, offset, length);
}
public bool CanRead
{
get
{
if (data.Length == 0)
return false;
if (data.Length < neededDataLength)
return false;
return true;
}
}
public byte[] Read()
{
lock (syncLock)
{
if (data.Length == 0)
return null;
byte[] rt = null;
if (neededDataLength == 0)
{
rt = data;
data = new byte[0];
}
else
{
//Console.WriteLine("P STATE:" + data.Length + " " + neededDataLength);
if (data.Length >= neededDataLength)
{
//Console.WriteLine("data.Length >= neededDataLength " + data.Length + " >= " + neededDataLength + " " + trim);
//if (trim)
//{
// rt = DC.Clip(data, 0, neededDataLength);
// data = DC.Clip(data, neededDataLength, (uint)data.Length - neededDataLength);
//}
//else
//{
// return all data
rt = data;
data = new byte[0];
//}
neededDataLength = 0;
return rt;
}
else
{
return null;
}
}
return rt;
}
}
}
}

View File

@ -1,297 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Net;
using System.Collections;
using System.Collections.Generic;
using Esiur.Misc;
using Esiur.Core;
using Esiur.Data;
using Esiur.Net.Sockets;
using Esiur.Resource;
namespace Esiur.Net
{
public class NetworkConnection: IDestructible// <TS>: IResource where TS : NetworkSession
{
private ISocket sock;
// private bool connected;
private DateTime lastAction;
public delegate void DataReceivedEvent(NetworkConnection sender, NetworkBuffer data);
public delegate void ConnectionClosedEvent(NetworkConnection sender);
public delegate void ConnectionEstablishedEvent(NetworkConnection sender);
public event ConnectionEstablishedEvent OnConnect;
public event DataReceivedEvent OnDataReceived;
public event ConnectionClosedEvent OnClose;
public event DestroyedEvent OnDestroy;
object receivingLock = new object();
bool processing = false;
public void Destroy()
{
// if (connected)
Close();
OnDestroy?.Invoke(this);
}
public NetworkConnection()
{
}
public ISocket Socket
{
get
{
return sock;
}
}
public virtual void Assign(ISocket socket)
{
lastAction = DateTime.Now;
sock = socket;
//connected = true;
socket.OnReceive += Socket_OnReceive;
socket.OnClose += Socket_OnClose;
socket.OnConnect += Socket_OnConnect;
//if (socket.State == SocketState.Established)
// socket.Begin();
}
private void Socket_OnConnect()
{
OnConnect?.Invoke(this);
}
private void Socket_OnClose()
{
OnClose?.Invoke(this);
}
private void Socket_OnReceive(NetworkBuffer buffer)
{
try
{
// Unassigned ?
if (sock == null)
return;
// Closed ?
if (sock.State == SocketState.Closed || sock.State == SocketState.Terminated) // || !connected)
return;
lastAction = DateTime.Now;
if (!processing)
{
processing = true;
try
{
//lock(buffer.SyncLock)
while (buffer.Available > 0 && !buffer.Protected)
DataReceived(buffer);
}
catch
{
}
processing = false;
}
}
catch (Exception ex)
{
Global.Log("NetworkConnection", LogType.Warning, ex.ToString());
}
}
public ISocket Unassign()
{
if (sock != null)
{
// connected = false;
sock.OnClose -= Socket_OnClose;
sock.OnConnect -= Socket_OnConnect;
sock.OnReceive -= Socket_OnReceive;
var rt = sock;
sock = null;
return rt;
}
else
return null;
}
protected virtual void DataReceived(NetworkBuffer data)
{
if (OnDataReceived != null)
{
try
{
OnDataReceived?.Invoke(this, data);
}
catch (Exception ex)
{
Global.Log("NetworkConenction:DataReceived", LogType.Error, ex.ToString());
}
}
}
public void Close()
{
//if (!connected)
// return;
try
{
if (sock != null)
sock.Close();
}
catch(Exception ex)
{
Global.Log("NetworkConenction:Close", LogType.Error, ex.ToString());
}
//finally
//{
//connected = false;
//}
}
public DateTime LastAction
{
get { return lastAction; }
}
public IPEndPoint RemoteEndPoint
{
get
{
if (sock != null)
return (IPEndPoint)sock.RemoteEndPoint;
else
return null;
}
}
public IPEndPoint LocalEndPoint
{
get
{
if (sock != null)
return (IPEndPoint)sock.LocalEndPoint;
else
return null;
}
}
public bool Connected
{
get
{
return sock.State == SocketState.Established;// connected;
}
}
/*
public void CloseAndWait()
{
try
{
if (!connected)
return;
if (sock != null)
sock.Close();
while (connected)
{
Thread.Sleep(100);
}
}
finally
{
}
}
*/
public virtual void Send(byte[] msg)
{
try
{
if (sock != null)
{
lastAction = DateTime.Now;
sock.Send(msg);
}
}
catch
{
}
}
public virtual void Send(byte[] msg, int offset, int length)
{
try
{
if (sock != null)
{
lastAction = DateTime.Now;
sock.Send(msg, offset, length);
}
}
catch
{
}
}
public virtual void Send(string data)
{
Send(Encoding.UTF8.GetBytes(data));
}
}
}

View File

@ -1,390 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Threading;
using System.Collections.Generic;
using Esiur.Data;
using Esiur.Misc;
using Esiur.Core;
using Esiur.Net.Sockets;
using Esiur.Resource;
using System.Threading.Tasks;
namespace Esiur.Net
{
public abstract class NetworkServer<TConnection>: IDestructible where TConnection : NetworkConnection, new()
{
//private bool isRunning;
uint clock;
private ISocket listener;
private AutoList<TConnection, NetworkServer<TConnection>> connections;
//private Thread thread;
protected abstract void DataReceived(TConnection sender, NetworkBuffer data);
protected abstract void ClientConnected(TConnection sender);
protected abstract void ClientDisconnected(TConnection sender);
private uint timeout;
private Timer timer;
//public KeyList<string, TSession> Sessions = new KeyList<string, TSession>();
public event DestroyedEvent OnDestroy;
public AutoList<TConnection, NetworkServer<TConnection>> Connections
{
get
{
return connections;
}
}
/*
public void RemoveSession(string ID)
{
Sessions.Remove(ID);
}
public void RemoveSession(TSession Session)
{
if (Session != null)
Sessions.Remove(Session.Id);
}
*/
/*
public TSession CreateSession(string ID, int Timeout)
{
TSession s = new TSession();
s.SetSession(ID, Timeout, new NetworkSession.SessionModifiedEvent(SessionModified)
, new NetworkSession.SessionEndedEvent(SessionEnded));
Sessions.Add(ID, s);
return s;
}
*/
/*
private void pSessionModified(TSession session, string key, object oldValue, object newValue)
{
SessionModified((TSession)session, key, oldValue, newValue);
}
private void pSessionEnded(NetworkSession session)
{
SessionEnded((TSession)session);
}
*/
/*
protected virtual void SessionModified(NetworkSession session, string key, object oldValue, object newValue)
{
}
protected virtual void SessionEnded(NetworkSession session)
{
Sessions.Remove(session.Id);
session.Destroy();
}
*/
private void MinuteThread(object state)
{
List<TConnection> ToBeClosed = null;
lock (connections.SyncRoot)
{
foreach (TConnection c in connections)
{
if (DateTime.Now.Subtract(c.LastAction).TotalSeconds >= timeout)
{
if (ToBeClosed == null)
ToBeClosed = new List<TConnection>();
ToBeClosed.Add(c);
}
}
}
//Console.WriteLine("UnLock MinuteThread");
if (ToBeClosed != null)
{
//Console.WriteLine("Term: " + ToBeClosed.Count + " " + this.listener.LocalEndPoint.ToString());
foreach (TConnection c in ToBeClosed)
c.Close();// CloseAndWait();
ToBeClosed.Clear();
ToBeClosed = null;
}
}
public void Start(ISocket socket, uint timeout, uint clock)
{
if (listener != null)
return;
//if (socket.State == SocketState.Listening)
// return;
//if (isRunning)
// return;
connections = new AutoList<TConnection, NetworkServer<TConnection>>(this);
if (timeout > 0 & clock > 0)
{
timer = new Timer(MinuteThread, null, TimeSpan.FromMinutes(0), TimeSpan.FromSeconds(clock));
this.timeout = timeout;
}
//this.ip = ip;
//this.port = port;
this.clock = clock;
// start a new thread for the server to live on
//isRunning = true;
listener = socket;
// Start accepting
var r = listener.Accept();
r.Then(NewConnection);
//r.timeout?.Dispose();
//var rt = listener.Accept().Then()
//thread = new Thread(new System.Threading.ThreadStart(ListenForConnections));
//thread.Start();
}
/*
public int LocalPort
{
get
{
return port;
}
}
*/
public uint Clock
{
get { return clock; }
}
public void Stop()
{
var port = 0;
try
{
if (listener != null)
{
port = listener.LocalEndPoint.Port;
listener.Close();
}
// wait until the listener stops
//while (isRunning)
//{
// Thread.Sleep(100);
//}
//Console.WriteLine("Listener stopped");
var cons = connections.ToArray();
//lock (connections.SyncRoot)
//{
foreach (TConnection con in cons)
con.Close();
//}
//Console.WriteLine("Sockets Closed");
//while (connections.Count > 0)
//{
// Console.WriteLine("Waiting... " + connections.Count);
// Thread.Sleep(1000);
//}
}
finally
{
Console.WriteLine("Server@{0} is down", port);
}
}
public virtual void RemoveConnection(TConnection connection)
{
connection.OnDataReceived -= OnDataReceived;
connection.OnConnect -= OnClientConnect;
connection.OnClose -= OnClientClose;
connections.Remove(connection);
}
public virtual void AddConnection(TConnection connection)
{
connection.OnDataReceived += OnDataReceived;
connection.OnConnect += OnClientConnect;
connection.OnClose += OnClientClose;
connections.Add(connection);
}
private void NewConnection(ISocket sock)
{
try
{
/*
if (listener.State == SocketState.Closed || listener.State == SocketState.Terminated)
{
Console.WriteLine("Listen socket break ");
Console.WriteLine(listener.LocalEndPoint.Port);
break;
}
*/
if (sock == null)
{
//Console.Write("sock == null");
return;
}
//sock.ReceiveBufferSize = 102400;
//sock.SendBufferSize = 102400;
TConnection c = new TConnection();
AddConnection(c);
c.Assign(sock);
try
{
ClientConnected(c);
}
catch
{
// something wrong with the child.
}
// Accept more
listener.Accept().Then(NewConnection);
//l.timeout?.Dispose();
sock.Begin();
}
catch (Exception ex)
{
//Console.WriteLine("TSERVER " + ex.ToString());
Global.Log("NetworkServer", LogType.Error, ex.ToString());
}
//isRunning = false;
}
public bool IsRunning
{
get
{
return listener.State == SocketState.Listening;
//isRunning;
}
}
public void OnDataReceived(NetworkConnection sender, NetworkBuffer data)
{
DataReceived((TConnection)sender, data);
}
public void OnClientConnect(NetworkConnection sender)
{
if (sender == null)
return;
if (sender.RemoteEndPoint == null || sender.LocalEndPoint == null)
{ }
//Console.WriteLine("NULL");
else
Global.Log("Connections", LogType.Debug, sender.RemoteEndPoint.Address.ToString()
+ "->" + sender.LocalEndPoint.Port + " at " + DateTime.UtcNow.ToString("d")
+ " " + DateTime.UtcNow.ToString("d"), false);
// Console.WriteLine("Connected " + sender.RemoteEndPoint.ToString());
ClientConnected((TConnection)sender);
}
public void OnClientClose(NetworkConnection sender)
{
try
{
sender.Destroy();
RemoveConnection((TConnection)sender);
ClientDisconnected((TConnection)sender);
}
catch (Exception ex)
{
Global.Log("NetworkServer:OnClientDisconnect", LogType.Error, ex.ToString());
}
sender = null;
GC.Collect();
}
public void Destroy()
{
Stop();
OnDestroy?.Invoke(this);
}
~NetworkServer()
{
Stop();
//Connections = null;
listener = null;
}
}
}

View File

@ -1,130 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Net;
using System.Collections;
using System.Collections.Generic;
using Esiur.Data;
using Esiur.Misc;
using Esiur.Core;
namespace Esiur.Net
{
public class NetworkSession:IDestructible //<T> where T : TClient
{
public delegate void SessionModifiedEvent(NetworkSession session, string key, object oldValue, object newValue);
public delegate void SessionEndedEvent(NetworkSession session);
private string id;
private Timer timer;
private int timeout;
DateTime creation;
DateTime lastAction;
private KeyList<string, object> variables;
public event SessionEndedEvent OnEnd;
public event SessionModifiedEvent OnModify;
public event DestroyedEvent OnDestroy;
public KeyList<string, object> Variables
{
get { return variables; }
}
public NetworkSession()
{
variables = new KeyList<string, object>();
variables.OnModified += new KeyList<string, object>.Modified(VariablesModified);
creation = DateTime.Now;
}
internal void Set(string id, int timeout )
{
//modified = sessionModifiedEvent;
//ended = sessionEndEvent;
this.id = id;
if (this.timeout != 0)
{
this.timeout = timeout;
timer = new Timer(OnSessionEndTimerCallback, null, TimeSpan.FromSeconds(timeout), TimeSpan.FromSeconds(0));
creation = DateTime.Now;
}
}
private void OnSessionEndTimerCallback(object o)
{
OnEnd?.Invoke(this);
}
void VariablesModified(string key, object oldValue, object newValue, KeyList<string, object> sender)
{
OnModify?.Invoke(this, key, oldValue, newValue);
}
public void Destroy()
{
OnDestroy?.Invoke(this);
timer.Dispose();
timer = null;
}
internal void Refresh()
{
lastAction = DateTime.Now;
timer.Change(TimeSpan.FromSeconds(timeout), TimeSpan.FromSeconds(0));
}
public int Timeout // Seconds
{
get
{
return timeout;
}
set
{
timeout = value;
Refresh();
}
}
public string Id
{
get { return id; }
}
public DateTime LastAction
{
get { return lastAction; }
}
}
}

View File

@ -1,312 +0,0 @@

/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Misc;
using Esiur.Data;
using System.Net;
namespace Esiur.Net.Packets
{
public class HTTPRequestPacket : Packet
{
public enum HTTPMethod:byte
{
GET,
POST,
HEAD,
PUT,
DELETE,
OPTIONS,
TRACE,
CONNECT,
UNKNOWN
}
public StringKeyList Query;
public HTTPMethod Method;
public StringKeyList Headers;
public bool WSMode;
public string Version;
public StringKeyList Cookies; // String
public string URL; /// With query
public string Filename; /// Without query
//public byte[] PostContents;
public KeyList<string, object> PostForms;
public byte[] Message;
private HTTPMethod getMethod(string method)
{
switch (method.ToLower())
{
case "get":
return HTTPMethod.GET;
case "post":
return HTTPMethod.POST;
case "head":
return HTTPMethod.HEAD;
case "put":
return HTTPMethod.PUT;
case "delete":
return HTTPMethod.DELETE;
case "options":
return HTTPMethod.OPTIONS;
case "trace":
return HTTPMethod.TRACE;
case "connect":
return HTTPMethod.CONNECT;
default:
return HTTPMethod.UNKNOWN;
}
}
public override string ToString()
{
return "HTTPRequestPacket"
+ "\n\tVersion: " + Version
+ "\n\tMethod: " + Method
+ "\n\tURL: " + URL
+ "\n\tMessage: " + (Message != null ? Message.Length.ToString() : "NULL");
}
public override long Parse(byte[] data, uint offset, uint ends)
{
string[] sMethod = null;
string[] sLines = null;
uint headerSize = 0;
for (uint i = offset; i < ends - 3; i++)
{
if (data[i] == '\r' && data[i + 1] == '\n'
&& data[i + 2] == '\r' && data[i + 3] == '\n')
{
sLines = Encoding.ASCII.GetString(data, (int)offset,(int)( i - offset)).Split(new string[] { "\r\n" },
StringSplitOptions.None);
headerSize = i + 4;
break;
}
}
if (headerSize == 0)
return -1;
Cookies = new StringKeyList();
PostForms = new KeyList<string, object>();
Query = new StringKeyList();
Headers = new StringKeyList();
sMethod = sLines[0].Split(' ');
Method = getMethod(sMethod[0].Trim());
if (sMethod.Length == 3)
{
sMethod[1] = WebUtility.UrlDecode(sMethod[1]);
if (sMethod[1].Length >= 7)
{
if (sMethod[1].Substring(0, 7) == "http://")
{
sMethod[1] = sMethod[1].Substring(sMethod[1].IndexOf("/", 7));
}
}
URL = sMethod[1].Trim();
if (URL.IndexOf("?", 0) != -1)
{
Filename = URL.Split(new char[] { '?' }, 2)[0];
}
else
{
Filename = URL;
}
if (Filename.IndexOf("%", 0) != -1)
{
Filename = WebUtility.UrlDecode(Filename);
}
Version = sMethod[2].Trim();
}
// Read all headers
for (int i = 1; i < sLines.Length; i++)
{
if (sLines[i] == String.Empty)
{
// Invalid header
return 0;
}
if (sLines[i].IndexOf(':') == -1)
{
// Invalid header
return 0;
}
string[] header = sLines[i].Split(new char[] { ':' }, 2);
header[0] = header[0].ToLower();
Headers[header[0]] = header[1].Trim();
if (header[0] == "cookie")
{
string[] cookies = header[1].Split(';');
foreach (string cookie in cookies)
{
if (cookie.IndexOf('=') != -1)
{
string[] splitCookie = cookie.Split('=');
splitCookie[0] = splitCookie[0].Trim();
splitCookie[1] = splitCookie[1].Trim();
if (!(Cookies.ContainsKey(splitCookie[0].Trim())))
Cookies.Add(splitCookie[0], splitCookie[1]);
}
else
{
if (!(Cookies.ContainsKey(cookie.Trim())))
{
Cookies.Add(cookie.Trim(), String.Empty);
}
}
}
}
}
// Query String
if (URL.IndexOf("?", 0) != -1)
{
string[] SQ = URL.Split(new char[] { '?' }, 2)[1].Split('&');
foreach (string S in SQ)
{
if (S.IndexOf("=", 0) != -1)
{
string[] qp = S.Split(new char[] { '=' }, 2);
if (!Query.ContainsKey(WebUtility.UrlDecode(qp[0])))
{
Query.Add(WebUtility.UrlDecode(qp[0]), WebUtility.UrlDecode(qp[1]));
}
}
else
{
if (!(Query.ContainsKey(WebUtility.UrlDecode(S))))
{
Query.Add(WebUtility.UrlDecode(S), null);
}
}
}
}
// Post Content-Length
if (Method == HTTPMethod.POST)
{
try
{
uint postSize = uint.Parse((string)Headers["content-length"]);
// check limit
if (postSize > data.Length - headerSize)
return postSize - (data.Length - headerSize);
if (Headers["content-type"].StartsWith("application/x-www-form-urlencoded")
|| Headers["content-type"] == ""
|| Headers["content-type"] == null)
{
string[] PostVars = null;
PostVars = Encoding.UTF8.GetString(data, (int)headerSize, (int)postSize).Split('&');
for (int J = 0; J < PostVars.Length; J++)
{
if (PostVars[J].IndexOf("=") != -1)
{
string key = WebUtility.HtmlDecode(
WebUtility.UrlDecode(PostVars[J].Split(new char[] { '=' }, 2)[0]));
if (PostForms.Contains(key))
PostForms[key] = WebUtility.HtmlDecode(
WebUtility.UrlDecode(PostVars[J].Split(new char[] { '=' }, 2)[1]));
else
PostForms.Add(key, WebUtility.HtmlDecode(
WebUtility.UrlDecode(PostVars[J].Split(new char[] { '=' }, 2)[1])));
}
else
if (PostForms.Contains("unknown"))
PostForms["unknown"] = PostForms["unknown"]
+ "&" + WebUtility.HtmlDecode(WebUtility.UrlDecode(PostVars[J]));
else
PostForms.Add("unknown", WebUtility.HtmlDecode(WebUtility.UrlDecode(PostVars[J])));
}
}
else if (Headers["content-type"].StartsWith("multipart/form-data"))
{
int st = 1;
int ed = 0;
string strBoundry = "--" + Headers["content-type"].Substring(
Headers["content-type"].IndexOf("boundary=", 0) + 9);
string[] sc = Encoding.UTF8.GetString(data, (int)headerSize, (int)postSize).Split(
new string[] { strBoundry }, StringSplitOptions.None);
for (int j = 1; j < sc.Length - 1; j++)
{
string[] ps = sc[j].Split(new string[] { "\r\n\r\n" }, 2, StringSplitOptions.None);
ps[1] = ps[1].Substring(0, ps[1].Length - 2); // remove the empty line
st = ps[0].IndexOf("name=", 0) + 6;
ed = ps[0].IndexOf("\"", st);
PostForms.Add(ps[0].Substring(st, ed - st), ps[1]);
}
}
else
{
//PostForms.Add(Headers["content-type"], Encoding.Default.GetString( ));
Message = DC.Clip(data, headerSize, postSize);
}
return headerSize + postSize;
}
catch
{
return 0;
}
}
return headerSize;
}
}
}

View File

@ -1,307 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Misc;
using Esiur.Data;
namespace Esiur.Net.Packets
{
public class HTTPResponsePacket : Packet
{
public enum ComposeOptions : int
{
AllCalculateLength,
AllDontCalculateLength,
SpecifiedHeadersOnly,
DataOnly
}
public enum ResponseCode : int
{
HTTP_SWITCHING = 101,
HTTP_OK = 200,
HTTP_NOTFOUND = 404,
HTTP_SERVERERROR = 500,
HTTP_MOVED = 301,
HTTP_NOTMODIFIED = 304,
HTTP_REDIRECT = 307
}
public class HTTPCookie
{
public string Name;
public string Value;
public DateTime Expires;
public string Path;
public bool HttpOnly;
public string Domain;
public HTTPCookie(string Name, string Value)
{
this.Name = Name;
this.Value = Value;
}
public HTTPCookie(string Name, string Value, DateTime Expires)
{
this.Name = Name;
this.Value = Value;
this.Expires = Expires;
}
public override string ToString()
{
//Set-Cookie: ckGeneric=CookieBody; expires=Sun, 30-Dec-2001 21:00:00 GMT; domain=.com.au; path=/
//Set-Cookie: SessionID=another; expires=Fri, 29 Jun 2006 20:47:11 UTC; path=/
string Cookie = Name + "=" + Value;
if (Expires.Ticks != 0)
{
Cookie += "; expires=" + Expires.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss") + " GMT";
}
if (Domain != null)
{
Cookie += "; domain=" + Domain;
}
if (Path != null)
{
Cookie += "; path=" + Path;
}
if (HttpOnly)
{
Cookie += "; HttpOnly";
}
return Cookie;
}
}
public StringKeyList Headers = new StringKeyList(true);
public string Version = "HTTP/1.1";
public byte[] Message;
public ResponseCode Number;
public string Text;
//public DStringDictionary Cookies;
public List<HTTPCookie> Cookies = new List<HTTPCookie>();
public bool Handled;
//public bool ResponseHandled; //flag this as true if you are handling it yourself
//private bool createSession;
//private HTTPServer Server;
//public HTTPSession Session;
public override string ToString()
{
return "HTTPResponsePacket"
+ "\n\tVersion: " + Version
//+ "\n\tMethod: " + Method
//+ "\n\tURL: " + URL
+ "\n\tMessage: " + (Message != null ? Message.Length.ToString() : "NULL");
}
private string MakeHeader(ComposeOptions Options)
{
string header = Version + " " + (int)Number + " " + Text + "\r\n"
+ "Server: Delta Web Server\r\n"
//Fri, 30 Oct 2007 14:19:41 GMT"
+ "Date: " + DateTime.Now.ToUniversalTime().ToString("r") + "\r\n";
if (Options == ComposeOptions.AllCalculateLength && Message != null)
{
Headers["Content-Length"] = Message.Length.ToString();
}
foreach (var kv in Headers)
{
header += kv.Key + ": " + kv.Value + "\r\n";
}
// Set-Cookie: ckGeneric=CookieBody; expires=Sun, 30-Dec-2007 21:00:00 GMT; path=/
// Set-Cookie: ASPSESSIONIDQABBDSQA=IPDPMMMALDGFLMICEJIOCIPM; path=/
foreach (var Cookie in Cookies)
{
header += "Set-Cookie: " + Cookie.ToString() + "\r\n";
}
header += "\r\n";
return header;
}
public bool Compose(ComposeOptions options)
{
List<byte> msg = new List<byte>();
if (options != ComposeOptions.DataOnly)
{
msg.AddRange(Encoding.UTF8.GetBytes(MakeHeader(options)));
}
if (options != ComposeOptions.SpecifiedHeadersOnly)
{
if (Message != null)
msg.AddRange(Message);
}
Data = msg.ToArray();
return true;
}
public override bool Compose()
{
return Compose(ComposeOptions.AllDontCalculateLength);
}
public override long Parse(byte[] data, uint offset, uint ends)
{
string[] sMethod = null;
string[] sLines = null;
uint headerSize = 0;
for (uint i = offset; i < ends - 3; i++)
{
if (data[i] == '\r' && data[i + 1] == '\n'
&& data[i + 2] == '\r' && data[i + 3] == '\n')
{
sLines = Encoding.ASCII.GetString(data, (int)offset, (int)(i - offset)).Split(new string[] { "\r\n" },
StringSplitOptions.None);
headerSize = i + 4;
break;
}
}
if (headerSize == 0)
return -1;
//Cookies = new DStringDictionary();
//Headers = new DStringDictionary(true);
sMethod = sLines[0].Split(' ');
if (sMethod.Length == 3)
{
Version = sMethod[0].Trim();
Number = (ResponseCode)(Convert.ToInt32(sMethod[1].Trim()));
Text = sMethod[2];
}
// Read all headers
for (int i = 1; i < sLines.Length; i++)
{
if (sLines[i] == String.Empty)
{
// Invalid header
return 0;
}
if (sLines[i].IndexOf(':') == -1)
{
// Invalid header
return 0;
}
string[] header = sLines[i].Split(new char[] { ':' }, 2);
header[0] = header[0].ToLower();
Headers[header[0]] = header[1].Trim();
//Set-Cookie: NAME=VALUE; expires=DATE;
if (header[0] == "set-cookie")
{
string[] cookie = header[1].Split(';');
if (cookie.Length >= 1)
{
string[] splitCookie = cookie[0].Split('=');
HTTPCookie c = new HTTPCookie(splitCookie[0], splitCookie[1]);
for (int j = 1; j < cookie.Length; j++)
{
splitCookie = cookie[j].Split('=');
switch (splitCookie[0].ToLower())
{
case "domain":
c.Domain = splitCookie[1];
break;
case "path":
c.Path = splitCookie[1];
break;
case "httponly":
c.HttpOnly = true;
break;
case "expires":
// Wed, 13-Jan-2021 22:23:01 GMT
c.Expires = DateTime.Parse(splitCookie[1]);
break;
}
}
}
}
}
// Content-Length
try
{
uint contentLength = uint.Parse((string)Headers["content-length"]);
// check limit
if (contentLength > data.Length - headerSize)
{
return contentLength - (data.Length - headerSize);
}
Message = DC.Clip(data, offset, contentLength);
return headerSize + contentLength;
}
catch
{
return 0;
}
}
}
}

View File

@ -1,406 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using Esiur.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Net.Packets
{
class IIPAuthPacket : Packet
{
public enum IIPAuthPacketCommand: byte
{
Action = 0,
Declare,
Acknowledge,
Error,
}
public enum IIPAuthPacketAction: byte
{
// Authenticate
AuthenticateHash,
//Challenge,
//CertificateRequest,
//CertificateReply,
//EstablishRequest,
//EstablishReply
NewConnection = 0x20,
ResumeConnection,
ConnectionEstablished = 0x28
}
public enum IIPAuthPacketMethod: byte
{
None,
Certificate,
Credentials,
Token
}
public IIPAuthPacketCommand Command
{
get;
set;
}
public IIPAuthPacketAction Action
{
get;
set;
}
public byte ErrorCode { get; set; }
public string ErrorMessage { get; set; }
public IIPAuthPacketMethod LocalMethod
{
get;
set;
}
public byte[] SourceInfo
{
get;
set;
}
public byte[] Hash
{
get;
set;
}
public byte[] SessionId
{
get;
set;
}
public IIPAuthPacketMethod RemoteMethod
{
get;
set;
}
public string Domain
{
get;
set;
}
public long CertificateId
{
get;set;
}
public string LocalUsername
{
get;
set;
}
public string RemoteUsername
{
get;
set;
}
public byte[] LocalPassword
{
get;
set;
}
public byte[] RemotePassword
{
get;
set;
}
public byte[] LocalToken
{
get;
set;
}
public byte[] RemoteToken
{
get;
set;
}
public byte[] AsymetricEncryptionKey
{
get;
set;
}
public byte[] LocalNonce
{
get;
set;
}
public byte[] RemoteNonce
{
get;
set;
}
private uint dataLengthNeeded;
bool NotEnough(uint offset, uint ends, uint needed)
{
if (offset + needed > ends)
{
dataLengthNeeded = needed - (ends - offset);
return true;
}
else
return false;
}
public override string ToString()
{
return Command.ToString() + " " + Action.ToString();
}
public override long Parse(byte[] data, uint offset, uint ends)
{
var oOffset = offset;
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
Command = (IIPAuthPacketCommand)(data[offset] >> 6);
if (Command == IIPAuthPacketCommand.Action)
{
Action = (IIPAuthPacketAction)(data[offset++] & 0x3f);
if (Action == IIPAuthPacketAction.AuthenticateHash)
{
if (NotEnough(offset, ends, 32))
return -dataLengthNeeded;
Hash = data.Clip(offset, 32);
//var hash = new byte[32];
//Buffer.BlockCopy(data, (int)offset, hash, 0, 32);
//Hash = hash;
offset += 32;
}
else if (Action == IIPAuthPacketAction.NewConnection)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var length = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, length))
return -dataLengthNeeded;
SourceInfo = data.Clip(offset, length);
//var sourceInfo = new byte[length];
//Buffer.BlockCopy(data, (int)offset, sourceInfo, 0, length);
//SourceInfo = sourceInfo;
offset += 32;
}
else if (Action == IIPAuthPacketAction.ResumeConnection
|| Action == IIPAuthPacketAction.ConnectionEstablished)
{
//var sessionId = new byte[32];
if (NotEnough(offset, ends, 32))
return -dataLengthNeeded;
SessionId = data.Clip(offset, 32);
//Buffer.BlockCopy(data, (int)offset, sessionId, 0, 32);
//SessionId = sessionId;
offset += 32;
}
}
else if (Command == IIPAuthPacketCommand.Declare)
{
RemoteMethod = (IIPAuthPacketMethod)((data[offset] >> 4) & 0x3);
LocalMethod = (IIPAuthPacketMethod)((data[offset] >> 2) & 0x3);
var encrypt = ((data[offset++] & 0x2) == 0x2);
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
var domainLength = data[offset++];
if (NotEnough(offset, ends, domainLength))
return -dataLengthNeeded;
var domain = data.GetString(offset, domainLength);
Domain = domain;
offset += domainLength;
if (RemoteMethod == IIPAuthPacketMethod.Credentials)
{
if (LocalMethod == IIPAuthPacketMethod.None)
{
if (NotEnough(offset, ends, 33))
return -dataLengthNeeded;
//var remoteNonce = new byte[32];
//Buffer.BlockCopy(data, (int)offset, remoteNonce, 0, 32);
//RemoteNonce = remoteNonce;
RemoteNonce = data.Clip(offset, 32);
offset += 32;
var length = data[offset++];
if (NotEnough(offset, ends, length))
return -dataLengthNeeded;
RemoteUsername = data.GetString(offset, length);
offset += length;
}
}
if (encrypt)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var keyLength = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, keyLength))
return -dataLengthNeeded;
//var key = new byte[keyLength];
//Buffer.BlockCopy(data, (int)offset, key, 0, keyLength);
//AsymetricEncryptionKey = key;
AsymetricEncryptionKey = data.Clip(offset, keyLength);
offset += keyLength;
}
}
else if (Command == IIPAuthPacketCommand.Acknowledge)
{
RemoteMethod = (IIPAuthPacketMethod)((data[offset] >> 4) & 0x3);
LocalMethod = (IIPAuthPacketMethod)((data[offset] >> 2) & 0x3);
var encrypt = ((data[offset++] & 0x2) == 0x2);
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
if (RemoteMethod == IIPAuthPacketMethod.Credentials)
{
if (LocalMethod == IIPAuthPacketMethod.None)
{
if (NotEnough(offset, ends, 32))
return -dataLengthNeeded;
/*
var remoteNonce = new byte[32];
Buffer.BlockCopy(data, (int)offset, remoteNonce, 0, 32);
RemoteNonce = remoteNonce;
*/
RemoteNonce = data.Clip(offset, 32);
offset += 32;
}
}
if (encrypt)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var keyLength = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, keyLength))
return -dataLengthNeeded;
//var key = new byte[keyLength];
//Buffer.BlockCopy(data, (int)offset, key, 0, keyLength);
//AsymetricEncryptionKey = key;
AsymetricEncryptionKey = data.Clip(offset, keyLength);
offset += keyLength;
}
}
else if (Command == IIPAuthPacketCommand.Error)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
offset++;
ErrorCode = data[offset++];
var cl = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ErrorMessage = data.GetString(offset, cl);
offset += cl;
}
return offset - oOffset;
}
}
}

View File

@ -1,820 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using Esiur.Data;
using Esiur.Core;
using Esiur.Misc;
using Esiur.Net.Packets;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Net.Packets
{
class IIPPacket : Packet
{
public override string ToString()
{
var rt = Command.ToString();
if (Command == IIPPacketCommand.Event)
{
rt += " " + Event.ToString();
//if (Event == IIPPacketEvent.AttributesUpdated)
// rt +=
}
else if (Command == IIPPacketCommand.Request)
{
rt += " " + Action.ToString();
if (Action == IIPPacketAction.AttachResource)
{
rt += " CID: " + CallbackId + " RID: " + ResourceId;
}
}
else if (Command == IIPPacketCommand.Reply)
rt += " " + Action.ToString();
else if (Command == IIPPacketCommand.Report)
rt += " " + Report.ToString();
return rt;
}
public enum IIPPacketCommand : byte
{
Event = 0,
Request,
Reply,
Report,
}
public enum IIPPacketEvent : byte
{
// Event Manage
ResourceReassigned = 0,
ResourceDestroyed,
ChildAdded,
ChildRemoved,
Renamed,
// Event Invoke
PropertyUpdated = 0x10,
EventOccurred,
// Attribute
AttributesUpdated = 0x18
}
public enum IIPPacketAction : byte
{
// Request Manage
AttachResource = 0,
ReattachResource,
DetachResource,
CreateResource,
DeleteResource,
AddChild,
RemoveChild,
RenameResource,
// Request Inquire
TemplateFromClassName = 0x8,
TemplateFromClassId,
TemplateFromResourceId,
QueryLink,
ResourceHistory,
ResourceChildren,
ResourceParents,
// Request Invoke
InvokeFunctionArrayArguments = 0x10,
GetProperty,
GetPropertyIfModified,
SetProperty,
InvokeFunctionNamedArguments,
// Request Attribute
GetAllAttributes = 0x18,
UpdateAllAttributes,
ClearAllAttributes,
GetAttributes,
UpdateAttributes,
ClearAttributes
}
public enum IIPPacketReport : byte
{
ManagementError,
ExecutionError,
ProgressReport = 0x8,
ChunkStream = 0x9
}
public IIPPacketReport Report
{
get;
set;
}
public IIPPacketCommand Command
{
get;
set;
}
public IIPPacketAction Action
{
get;
set;
}
public IIPPacketEvent Event
{
get;
set;
}
public IIPPacketCommand PreviousCommand
{
get;
set;
}
public IIPPacketAction PreviousAction
{
get;
set;
}
public IIPPacketEvent PreviousEvent
{
get;
set;
}
public uint ResourceId { get; set; }
public uint NewResourceId { get; set; }
//public uint ParentId { get; set; }
public uint ChildId { get; set; }
public uint StoreId { get; set; }
public ulong ResourceAge { get; set; }
public byte[] Content { get; set; }
public ushort ErrorCode { get; set; }
public string ErrorMessage { get; set; }
public string ClassName { get; set; }
public string ResourceLink { get; set; }
public Guid ClassId { get; set; }
public byte MethodIndex { get; set; }
public string MethodName { get; set; }
public uint CallbackId { get; set; }
public int ProgressValue { get; set; }
public int ProgressMax { get; set; }
public DateTime FromDate { get; set; }
public DateTime ToDate { get; set; }
public ulong FromAge { get; set; }
public ulong ToAge { get; set; }
private uint dataLengthNeeded;
private uint originalOffset;
public override bool Compose()
{
return base.Compose();
}
bool NotEnough(uint offset, uint ends, uint needed)
{
if (offset + needed > ends)
{
dataLengthNeeded = needed - (ends - offset);
//dataLengthNeeded = needed - (ends - originalOffset);
return true;
}
else
return false;
}
public override long Parse(byte[] data, uint offset, uint ends)
{
originalOffset = offset;
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
PreviousCommand = Command;
Command = (IIPPacketCommand)(data[offset] >> 6);
if (Command == IIPPacketCommand.Event)
{
Event = (IIPPacketEvent)(data[offset++] & 0x3f);
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Command == IIPPacketCommand.Report)
{
Report = (IIPPacketReport)(data[offset++] & 0x3f);
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
CallbackId = data.GetUInt32(offset);
offset += 4;
}
else
{
PreviousAction = Action;
Action = (IIPPacketAction)(data[offset++] & 0x3f);
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
CallbackId = data.GetUInt32(offset);
offset += 4;
}
if (Command == IIPPacketCommand.Event)
{
if (Event == IIPPacketEvent.ResourceReassigned)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
NewResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Event == IIPPacketEvent.ResourceDestroyed)
{
// nothing to parse
}
else if (Event == IIPPacketEvent.ChildAdded
|| Event == IIPPacketEvent.ChildRemoved)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ChildId = data.GetUInt32(offset);
offset += 4;
}
else if (Event == IIPPacketEvent.Renamed)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var cl = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset, cl);
offset += cl;
}
else if (Event == IIPPacketEvent.PropertyUpdated)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
MethodIndex = data[offset++];
var dt = (DataType)data[offset++];
var size = dt.Size();// Codec.SizeOf(dt);
if (size < 0)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset - 5, cl + 5);
offset += cl;
}
else
{
if (NotEnough(offset, ends, (uint)size))
return -dataLengthNeeded;
Content = data.Clip(offset - 1, (uint)size + 1);
offset += (uint)size;
}
}
else if (Event == IIPPacketEvent.EventOccurred)
{
if (NotEnough(offset, ends, 5))
return -dataLengthNeeded;
MethodIndex = data[offset++];
var cl = data.GetUInt32(offset);
offset += 4;
Content = data.Clip(offset, cl);
offset += cl;
}
// Attribute
else if (Event == IIPPacketEvent.AttributesUpdated)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset, cl);
offset += cl;
}
}
else if (Command == IIPPacketCommand.Request)
{
if (Action == IIPPacketAction.AttachResource)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.ReattachResource)
{
if (NotEnough(offset, ends, 12))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
ResourceAge = data.GetUInt64(offset);
offset += 8;
}
else if (Action == IIPPacketAction.DetachResource)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.CreateResource)
{
if (NotEnough(offset, ends, 12))
return -dataLengthNeeded;
StoreId = data.GetUInt32(offset);
offset += 4;
ResourceId = data.GetUInt32(offset);
offset += 4;
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
this.Content = data.Clip(offset, cl);
}
else if (Action == IIPPacketAction.DeleteResource)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.AddChild
|| Action == IIPPacketAction.RemoveChild)
{
if (NotEnough(offset, ends, 8))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
ChildId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.RenameResource)
{
if (NotEnough(offset, ends, 6))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
var cl = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.TemplateFromClassName)
{
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
var cl = data[offset++];
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ClassName = data.GetString(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.TemplateFromClassId)
{
if (NotEnough(offset, ends, 16))
return -dataLengthNeeded;
ClassId = data.GetGuid(offset);
offset += 16;
}
else if (Action == IIPPacketAction.TemplateFromResourceId)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.QueryLink)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var cl = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ResourceLink = data.GetString(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.ResourceChildren
|| Action == IIPPacketAction.ResourceParents)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.ResourceHistory)
{
if (NotEnough(offset, ends, 20))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
FromDate = data.GetDateTime(offset);
offset += 8;
ToDate = data.GetDateTime(offset);
offset += 8;
}
else if (Action == IIPPacketAction.InvokeFunctionArrayArguments
|| Action == IIPPacketAction.InvokeFunctionNamedArguments)
{
if (NotEnough(offset, ends, 9))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
MethodIndex = data[offset++];
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.GetProperty)
{
if (NotEnough(offset, ends, 5))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
MethodIndex = data[offset++];
}
else if (Action == IIPPacketAction.GetPropertyIfModified)
{
if (NotEnough(offset, ends, 9))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
MethodIndex = data[offset++];
ResourceAge = data.GetUInt64(offset);
offset += 8;
}
else if (Action == IIPPacketAction.SetProperty)
{
if (NotEnough(offset, ends, 6))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
MethodIndex = data[offset++];
var dt = (DataType)data[offset++];
var size = dt.Size();// Codec.SizeOf(dt);
if (size < 0)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset - 5, cl + 5);
offset += cl;
}
else
{
if (NotEnough(offset, ends, (uint)size))
return -dataLengthNeeded;
Content = data.Clip(offset - 1, (uint)size + 1);
offset += (uint)size;
}
}
// Attributes
else if (Action == IIPPacketAction.UpdateAllAttributes
|| Action == IIPPacketAction.GetAttributes
|| Action == IIPPacketAction.UpdateAttributes
|| Action == IIPPacketAction.ClearAttributes)
{
if (NotEnough(offset, ends, 8))
return -dataLengthNeeded;
ResourceId = data.GetUInt32(offset);
offset += 4;
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset, cl);
offset += cl;
}
}
else if (Command == IIPPacketCommand.Reply)
{
if (Action == IIPPacketAction.AttachResource
|| Action == IIPPacketAction.ReattachResource)
{
if (NotEnough(offset, ends, 26))
return -dataLengthNeeded;
ClassId = data.GetGuid(offset);
offset += 16;
ResourceAge = data.GetUInt64(offset);
offset += 8;
uint cl = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ResourceLink = data.GetString(offset, cl);
offset += cl;
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.DetachResource)
{
// nothing to do
}
else if (Action == IIPPacketAction.CreateResource)
{
if (NotEnough(offset, ends, 20))
return -dataLengthNeeded;
//ClassId = data.GetGuid(offset);
//offset += 16;
ResourceId = data.GetUInt32(offset);
offset += 4;
}
else if (Action == IIPPacketAction.DetachResource)
{
// nothing to do
}
// Inquire
else if (Action == IIPPacketAction.TemplateFromClassName
|| Action == IIPPacketAction.TemplateFromClassId
|| Action == IIPPacketAction.TemplateFromResourceId
|| Action == IIPPacketAction.QueryLink
|| Action == IIPPacketAction.ResourceChildren
|| Action == IIPPacketAction.ResourceParents
|| Action == IIPPacketAction.ResourceHistory
// Attribute
|| Action == IIPPacketAction.GetAllAttributes
|| Action == IIPPacketAction.GetAttributes)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset, cl);
offset += cl;
}
else if (Action == IIPPacketAction.InvokeFunctionArrayArguments
|| Action == IIPPacketAction.InvokeFunctionNamedArguments
|| Action == IIPPacketAction.GetProperty
|| Action == IIPPacketAction.GetPropertyIfModified)
{
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
var dt = (DataType)data[offset++];
var size = dt.Size();// Codec.SizeOf(dt);
if (size < 0)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset - 5, cl + 5);
offset += cl;
}
else
{
if (NotEnough(offset, ends, (uint)size))
return -dataLengthNeeded;
Content = data.Clip(offset - 1, (uint)size + 1);
offset += (uint)size;
}
}
else if (Action == IIPPacketAction.SetProperty)
{
// nothing to do
}
}
else if (Command == IIPPacketCommand.Report)
{
if (Report == IIPPacketReport.ManagementError)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
ErrorCode = data.GetUInt16(offset);
offset += 2;
}
else if (Report == IIPPacketReport.ExecutionError)
{
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
ErrorCode = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, 2))
return -dataLengthNeeded;
var cl = data.GetUInt16(offset);
offset += 2;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
ErrorMessage = data.GetString(offset, cl);
offset += cl;
}
else if (Report == IIPPacketReport.ProgressReport)
{
if (NotEnough(offset, ends, 8))
return -dataLengthNeeded;
ProgressValue = data.GetInt32(offset);
offset += 4;
ProgressMax = data.GetInt32(offset);
offset += 4;
}
else if (Report == IIPPacketReport.ChunkStream)
{
if (NotEnough(offset, ends, 1))
return -dataLengthNeeded;
var dt = (DataType)data[offset++];
var size = dt.Size();// Codec.SizeOf(dt);
if (size < 0)
{
if (NotEnough(offset, ends, 4))
return -dataLengthNeeded;
var cl = data.GetUInt32(offset);
offset += 4;
if (NotEnough(offset, ends, cl))
return -dataLengthNeeded;
Content = data.Clip(offset - 5, cl + 5);
offset += cl;
}
else
{
if (NotEnough(offset, ends, (uint)size))
return -dataLengthNeeded;
Content = data.Clip(offset - 1, (uint)size + 1);
offset += (uint)size;
}
}
}
return offset - originalOffset;
}
}
}

View File

@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net.Packets
{
struct IIPPacketAttachInfo
{
public string Link;
public ulong Age;
public byte[] Content;
public Guid ClassId;
public IIPPacketAttachInfo(Guid classId, ulong age, string link, byte[] content)
{
ClassId = classId;
Age = age;
Content = content;
Link = link;
}
}
}

View File

@ -1,369 +0,0 @@
/********************************************************************************\
* Uruky Project *
* *
* Copyright (C) 2006 Ahmed Zamil - ahmed@dijlh.com *
* http://www.dijlh.com *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy *
* of this software and associated documentation files (the "Software"), to deal *
* in the Software without restriction, including without limitation the rights *
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
* copies of the Software, and to permit persons to whom the Software is *
* furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in all *
* copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
* SOFTWARE. *
* *
* File: Packet.cs *
* Description: Ethernet/ARP/IPv4/TCP/UDP Packet Decoding & Encoding Class *
* Compatibility: .Net Framework 2.0 / Mono 1.1.8 *
* *
\********************************************************************************/
using System;
using System.Text;
using Esiur.Misc;
using Esiur.Net.DataLink;
using System.Net.NetworkInformation;
using Esiur.Data;
namespace Esiur.Net.Packets
{
internal static class Functions
{
public static void AddData(ref byte[] dest, byte[] src)
{
int I = 0;
if (src == null)
{
return;
}
if (dest != null)
{
I = dest.Length;
Array.Resize(ref dest, dest.Length + src.Length);
//dest = (byte[])Resize(dest, dest.Length + src.Length);
}
else
{
dest = new byte[src.Length];
}
Array.Copy(src, 0, dest, I, src.Length);
}
/*
public static Array Resize(Array array, int newSize)
{
Type myType = Type.GetType(array.GetType().FullName.TrimEnd('[', ']'));
Array nA = Array.CreateInstance(myType, newSize);
Array.Copy(array, nA, (newSize > array.Length ? array.Length : newSize));
return nA;
} */
//Computes the checksum used in IP, ARP..., ie the
// "The 16 bit one's complement of the one 's complement sum
//of all 16 bit words" as seen in RFCs
// Returns a 4 characters hex string
// data's lenght must be multiple of 4, else zero padding
public static ushort IP_CRC16(byte[] data)
{
ulong Sum = 0;
bool Padding = false;
/// * Padding if needed
if (data.Length % 2 != 0)
{
Array.Resize(ref data, data.Length + 1);
//data = (byte[])Resize(data, data.Length + 1);
Padding = true;
}
int count = data.Length;
///* add 16-bit words */
while (count > 0) //1)
{
///* this is the inner loop */
Sum += GetInteger(data[count - 2], data[count - 1]);
///* Fold 32-bit sum to 16-bit */
while (Sum >> 16 != 0)
{
Sum = (Sum & 0XFFFF) + (Sum >> 16);
}
count -= 2;
}
/// * reverse padding
if (Padding)
{
Array.Resize(ref data, data.Length - 1);
//data = (byte[])Resize(data, data.Length - 1);
}
///* Return one's compliment of final sum.
//return (ushort)(ushort.MaxValue - (ushort)Sum);
return (ushort)(~Sum);
}
public static ushort GetInteger(byte B1, byte B2)
{
return BitConverter.ToUInt16(new byte[] { B2, B1 }, 0);
//return System.Convert.ToUInt16("&h" + GetHex(B1) + GetHex(B2));
}
public static uint GetLong(byte B1, byte B2, byte B3, byte B4)
{
return BitConverter.ToUInt32(new byte[] { B4, B3, B2, B1 }, 0);
//return System.Convert.ToUInt32("&h" + GetHex(B1) + GetHex(B2) + GetHex(B3) + GetHex(B4));
}
public static string GetHex(byte B)
{
return (((B < 15) ? 0 + System.Convert.ToString(B, 16).ToUpper() : System.Convert.ToString(B, 16).ToUpper()));
}
public static bool GetBit(uint B, byte Pos)
{
//return BitConverter.ToBoolean(BitConverter.GetBytes(B), Pos + 1);
return (B & (uint)(Math.Pow(2, (Pos - 1)))) == (Math.Pow(2, (Pos - 1)));
}
public static ushort RemoveBit(ushort I, byte Pos)
{
return (ushort)RemoveBit((uint)I, Pos);
}
public static uint RemoveBit(uint I, byte Pos)
{
if (GetBit(I, Pos))
{
return I - (uint)(Math.Pow(2, (Pos - 1)));
}
else
{
return I;
}
}
public static void SplitInteger(ushort I, ref byte BLeft, ref byte BRight)
{
byte[] b = BitConverter.GetBytes(I);
BLeft = b[1];
BRight = b[0];
//BLeft = I >> 8;
//BRight = (I << 8) >> 8;
}
public static void SplitLong(uint I, ref byte BLeft, ref byte BLeftMiddle, ref byte BRightMiddle, ref byte BRight)
{
byte[] b = BitConverter.GetBytes(I);
BLeft = b[3];
BLeftMiddle = b[2];
BRightMiddle = b[1];
BRight = b[0];
//BLeft = I >> 24;
//BLeftMiddle = (I << 8) >> 24;
//BRightMiddle = (I << 16) >> 24;
//BRight = (I << 24) >> 24;
}
}
public class PosixTime
{
ulong seconds;
ulong microseconds;
PosixTime(ulong Seconds, ulong Microseconds)
{
seconds = Seconds;
microseconds = Microseconds;
}
public override string ToString()
{
return seconds + "." + microseconds;
}
}
public class Packet
{
//public EtherServer2.EthernetSource Source;
public PacketSource Source;
public DateTime Timestamp;
public enum PPPType : ushort
{
IP = 0x0021, // Internet Protocol version 4 [RFC1332]
SDTP = 0x0049, // Serial Data Transport Protocol (PPP-SDTP) [RFC1963]
IPv6HeaderCompression = 0x004f, // IPv6 Header Compression
IPv6 = 0x0057, // Internet Protocol version 6 [RFC5072]
W8021dHelloPacket = 0x0201, // 802.1d Hello Packets [RFC3518]
IPv6ControlProtocol = 0x8057, // IPv6 Control Protocol [RFC5072]
}
public enum ProtocolType : ushort
{
IP = 0x800, // IPv4
ARP = 0x806, // Address Resolution Protocol
IPv6 = 0x86DD, // IPv6
FrameRelayARP = 0x0808, // Frame Relay ARP [RFC1701]
VINESLoopback = 0x0BAE, // VINES Loopback [RFC1701]
VINESEcho = 0x0BAF, // VINES ECHO [RFC1701]
TransEtherBridging = 0x6558, // TransEther Bridging [RFC1701]
RawFrameRelay = 0x6559, // Raw Frame Relay [RFC1701]
IEE8021QVLAN = 0x8100, // IEEE 802.1Q VLAN-tagged frames (initially Wellfleet)
SNMP = 0x814C, // SNMP [JKR1]
TCPIP_Compression = 0x876B, // TCP/IP Compression [RFC1144]
IPAutonomousSystems = 0x876C, // IP Autonomous Systems [RFC1701]
SecureData = 0x876D, // Secure Data [RFC1701]
PPP = 0x880B, // PPP [IANA]
MPLS = 0x8847, // MPLS [RFC5332]
MPLS_UpstreamAssignedLabel = 0x8848, // MPLS with upstream-assigned label [RFC5332]
PPPoEDiscoveryStage = 0x8863, // PPPoE Discovery Stage [RFC2516]
PPPoESessionStage = 0x8864, // PPPoE Session Stage [RFC2516]
}
/*
public static void GetPacketMACAddresses(Packet packet, out byte[] srcMAC, out byte[] dstMAC)
{
// get the node address
Packet root = packet.RootPacket;
if (root is TZSPPacket)
{
TZSPPacket tp = (TZSPPacket)root;
if (tp.Protocol == TZSPPacket.TZSPEncapsulatedProtocol.Ethernet)
{
EthernetPacket ep = (EthernetPacket)tp.SubPacket;
srcMAC = ep.SourceMAC;
dstMAC = ep.DestinationMAC;
}
else if (tp.Protocol == TZSPPacket.TZSPEncapsulatedProtocol.IEEE802_11)
{
W802_11Packet wp = (W802_11Packet)tp.SubPacket;
srcMAC = wp.SA;
dstMAC = wp.DA;
}
else
{
srcMAC = null;
dstMAC = null;
}
}
else if (root is EthernetPacket)
{
EthernetPacket ep = (EthernetPacket)root;
srcMAC = ep.SourceMAC;
dstMAC = ep.DestinationMAC;
}
else if (root is W802_11Packet)
{
W802_11Packet wp = (W802_11Packet)root;
srcMAC = wp.SA;
dstMAC = wp.DA;
}
else
{
srcMAC = null;
dstMAC = null;
}
}
public static void GetPacketAddresses(Packet packet, ref string srcMAC, ref string dstMAC, ref string srcIP, ref string dstIP)
{
if (packet is TCPv4Packet)
{
if (packet.ParentPacket is IPv4Packet)
{
IPv4Packet ip = (IPv4Packet)packet.ParentPacket;
srcIP = ip.SourceIP.ToString();
dstIP = ip.DestinationIP.ToString();
}
}
// get the node address
Packet root = packet.RootPacket;
if (root is TZSPPacket)
{
TZSPPacket tp = (TZSPPacket)root;
if (tp.Protocol == TZSPPacket.TZSPEncapsulatedProtocol.Ethernet)
{
EthernetPacket ep = (EthernetPacket)tp.SubPacket;
srcMAC = DC.GetPhysicalAddress(ep.SourceMAC, 0).ToString();
dstMAC = DC.GetPhysicalAddress(ep.DestinationMAC, 0).ToString();
}
else if (tp.Protocol == TZSPPacket.TZSPEncapsulatedProtocol.IEEE802_11)
{
W802_11Packet wp = (W802_11Packet)tp.SubPacket;
srcMAC = DC.GetPhysicalAddress(wp.SA, 0).ToString();
dstMAC = DC.GetPhysicalAddress(wp.DA, 0).ToString();
}
}
else if (root is EthernetPacket)
{
EthernetPacket ep = (EthernetPacket)root;
srcMAC = DC.GetPhysicalAddress(ep.SourceMAC, 0).ToString();
dstMAC = DC.GetPhysicalAddress(ep.DestinationMAC, 0).ToString();
}
else if (root is W802_11Packet)
{
W802_11Packet wp = (W802_11Packet)root;
srcMAC = DC.GetPhysicalAddress(wp.SA, 0).ToString();
dstMAC = DC.GetPhysicalAddress(wp.DA, 0).ToString();
}
}
*/
PosixTime Timeval;
public byte[] Header;
public byte[] Preamble;
//public byte[] Payload;
public byte[] Data;
public Packet SubPacket;
public Packet ParentPacket;
public virtual long Parse(byte[] data, uint offset, uint ends) { return 0; }
public virtual bool Compose() { return false; }
public Packet RootPacket
{
get
{
Packet root = this;
while (root.ParentPacket != null)
root = root.ParentPacket;
return root;
}
}
public Packet LeafPacket
{
get
{
Packet leaf = this;
while (leaf.SubPacket != null)
leaf = leaf.SubPacket;
return leaf;
}
}
}
}
/************************************ EOF *************************************/

View File

@ -1,217 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Misc;
using Esiur.Data;
namespace Esiur.Net.Packets
{
public class WebsocketPacket : Packet
{
public enum WSOpcode : byte
{
ContinuationFrame = 0x0, // %x0 denotes a continuation frame
TextFrame = 0x1, // %x1 denotes a text frame
BinaryFrame = 0x2, // %x2 denotes a binary frame
// %x3-7 are reserved for further non-control frames
ConnectionClose = 0x8, // %x8 denotes a connection close
Ping = 0x9, // %x9 denotes a ping
Pong = 0xA, // %xA denotes a pong
//* %xB-F are reserved for further control frames
}
public bool FIN;
public bool RSV1;
public bool RSV2;
public bool RSV3;
public WSOpcode Opcode;
public bool Mask;
public long PayloadLength;
// public UInt32 MaskKey;
public byte[] MaskKey;
public byte[] Message;
public override string ToString()
{
return "WebsocketPacket"
+ "\n\tFIN: " + FIN
+ "\n\tOpcode: " + Opcode
+ "\n\tPayload: " + PayloadLength
+ "\n\tMaskKey: " + MaskKey
+ "\n\tMessage: " + (Message != null ? Message.Length.ToString() : "NULL");
}
public override bool Compose()
{
var pkt = new List<byte>();
pkt.Add((byte)((FIN ? 0x80 : 0x0) |
(RSV1 ? 0x40 : 0x0) |
(RSV2 ? 0x20 : 0x0) |
(RSV3 ? 0x10 : 0x0) |
(byte)Opcode));
// calculate length
if (Message.Length > UInt16.MaxValue)
// 4 bytes
{
pkt.Add((byte)((Mask ? 0x80 : 0x0) | 127));
pkt.AddRange(DC.ToBytes((UInt64)Message.LongCount()));
}
else if (Message.Length > 125)
// 2 bytes
{
pkt.Add((byte)((Mask ? 0x80 : 0x0) | 126));
pkt.AddRange(DC.ToBytes((UInt16)Message.Length));
}
else
{
pkt.Add((byte)((Mask ? 0x80 : 0x0) | Message.Length));
}
if (Mask)
{
pkt.AddRange(MaskKey);
}
pkt.AddRange(Message);
Data = pkt.ToArray();
return true;
}
public override long Parse(byte[] data, uint offset, uint ends)
{
try
{
long needed = 2;
var length = (ends - offset);
if (length < needed)
{
//Console.WriteLine("stage 1 " + needed);
return length - needed;
}
uint oOffset = offset;
FIN = ((data[offset] & 0x80) == 0x80);
RSV1 = ((data[offset] & 0x40) == 0x40);
RSV2 = ((data[offset] & 0x20) == 0x20);
RSV3 = ((data[offset] & 0x10) == 0x10);
Opcode = (WSOpcode)(data[offset++] & 0xF);
Mask = ((data[offset] & 0x80) == 0x80);
PayloadLength = (long)(data[offset++] & 0x7F);
if (Mask)
needed += 4;
if (PayloadLength == 126)
{
needed += 2;
if (length < needed)
{
//Console.WriteLine("stage 2 " + needed);
return length - needed;
}
PayloadLength = DC.GetUInt16(data, offset);
offset += 2;
}
else if (PayloadLength == 127)
{
needed += 8;
if (length < needed)
{
//Console.WriteLine("stage 3 " + needed);
return length - needed;
}
PayloadLength = DC.GetInt64(data, offset);
offset += 8;
}
/*
if (Mask)
{
MaskKey = new byte[4];
MaskKey[0] = data[offset++];
MaskKey[1] = data[offset++];
MaskKey[2] = data[offset++];
MaskKey[3] = data[offset++];
//MaskKey = DC.GetUInt32(data, offset);
//offset += 4;
}
*/
needed += PayloadLength;
if (length < needed)
{
//Console.WriteLine("stage 4");
return length - needed;
}
else
{
if (Mask)
{
MaskKey = new byte[4];
MaskKey[0] = data[offset++];
MaskKey[1] = data[offset++];
MaskKey[2] = data[offset++];
MaskKey[3] = data[offset++];
Message = DC.Clip(data, offset, (uint)PayloadLength);
//var aMask = BitConverter.GetBytes(MaskKey);
for (int i = 0; i < Message.Length; i++)
Message[i] = (byte)(Message[i] ^ MaskKey[i % 4]);
}
else
Message = DC.Clip(data, offset, (uint)PayloadLength);
return (offset - oOffset) + (int)PayloadLength;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.WriteLine(offset + "::" + DC.ToHex(data));
throw ex;
}
}
}
}

View File

@ -1,26 +0,0 @@
using Esiur.Core;
using Esiur.Data;
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Net
{
public class SendList : BinaryList
{
NetworkConnection connection;
IAsyncReply<object[]> reply;
public SendList(NetworkConnection connection, IAsyncReply<object[]> reply)
{
this.reply = reply;
this.connection = connection;
}
public override IAsyncReply<object[]> Done()
{
connection.Send(this.ToArray());
return reply;
}
}
}

View File

@ -1,67 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Net;
using System.Collections;
using System.Collections.Generic;
using Esiur.Data;
using Esiur.Misc;
using System.Collections.Concurrent;
using Esiur.Resource;
using Esiur.Core;
namespace Esiur.Net.Sockets
{
public delegate void ISocketReceiveEvent(NetworkBuffer buffer);
public delegate void ISocketConnectEvent();
public delegate void ISocketCloseEvent();
public interface ISocket: IDestructible
{
SocketState State { get; }
event ISocketReceiveEvent OnReceive;
event ISocketConnectEvent OnConnect;
event ISocketCloseEvent OnClose;
void Send(byte[] message);
void Send(byte[] message, int offset, int size);
void Close();
AsyncReply<bool> Connect(string hostname, ushort port);
bool Begin();
//ISocket Accept();
AsyncReply<ISocket> Accept();
IPEndPoint RemoteEndPoint { get; }
IPEndPoint LocalEndPoint { get; }
void Hold();
void Unhold();
}
}

View File

@ -1,353 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using Esiur.Misc;
using Esiur.Core;
using System.Threading;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Esiur.Resource;
using System.Threading.Tasks;
using Esiur.Data;
namespace Esiur.Net.Sockets
{
public class SSLSocket : ISocket
{
Socket sock;
byte[] receiveBuffer;
NetworkBuffer receiveNetworkBuffer = new NetworkBuffer();
object sendLock = new object();
Queue<byte[]> sendBufferQueue = new Queue<byte[]>();
bool asyncSending;
SocketState state = SocketState.Initial;
public event ISocketReceiveEvent OnReceive;
public event ISocketConnectEvent OnConnect;
public event ISocketCloseEvent OnClose;
public event DestroyedEvent OnDestroy;
SslStream ssl;
X509Certificate2 cert;
bool server;
string hostname;
private void Connected(Task t)
{
if (server)
{
ssl.AuthenticateAsServerAsync(cert).ContinueWith(Authenticated);
}
else
{
ssl.AuthenticateAsClientAsync(hostname).ContinueWith(Authenticated);
}
}
public AsyncReply<bool> Connect(string hostname, ushort port)
{
var rt = new AsyncReply<bool>();
try
{
state = SocketState.Connecting;
sock.ConnectAsync(hostname, port).ContinueWith((x) =>
{
if (x.IsFaulted)
rt.TriggerError(x.Exception);
else
rt.Trigger(true);
Connected(x);
});
}
catch (Exception ex)
{
rt.TriggerError(ex);
}
return rt;
}
private void DataSent(Task task)
{
try
{
if (sendBufferQueue.Count > 0)
{
byte[] data = sendBufferQueue.Dequeue();
lock (sendLock)
ssl.WriteAsync(data, 0, data.Length).ContinueWith(DataSent);
}
else
{
asyncSending = false;
}
}
catch (Exception ex)
{
if (state != SocketState.Closed && !sock.Connected)
{
state = SocketState.Terminated;
Close();
}
asyncSending = false;
Global.Log("SSLSocket", LogType.Error, ex.ToString());
}
}
public IPEndPoint LocalEndPoint
{
get { return (IPEndPoint)sock.LocalEndPoint; }
}
public SSLSocket()
{
sock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
receiveBuffer = new byte[sock.ReceiveBufferSize];
}
public SSLSocket(IPEndPoint localEndPoint, X509Certificate2 certificate)
{
// create the socket
sock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
state = SocketState.Listening;
// bind
sock.Bind(localEndPoint);
// start listening
sock.Listen(UInt16.MaxValue);
cert = certificate;
}
public IPEndPoint RemoteEndPoint
{
get { return (IPEndPoint)sock.RemoteEndPoint; }
}
public SocketState State
{
get
{
return state;
}
}
public SSLSocket(Socket Socket, X509Certificate2 certificate, bool authenticateAsServer)
{
cert = certificate;
sock = Socket;
receiveBuffer = new byte[sock.ReceiveBufferSize];
ssl = new SslStream(new NetworkStream(sock));
server = authenticateAsServer;
}
public void Close()
{
if (state != SocketState.Closed && state != SocketState.Terminated)
state = SocketState.Closed;
if (sock.Connected)
{
try
{
sock.Shutdown(SocketShutdown.Both);
}
catch
{
state = SocketState.Terminated;
}
}
sock.Shutdown(SocketShutdown.Both);
OnClose?.Invoke();
}
public void Send(byte[] message)
{
Send(message, 0, message.Length);
}
public void Send(byte[] message, int offset, int size)
{
lock (sendLock)
{
if (asyncSending)
{
sendBufferQueue.Enqueue(message.Clip((uint)offset, (uint)size));
}
else
{
asyncSending = true;
ssl.WriteAsync(message, offset, size).ContinueWith(DataSent);
}
}
}
void Authenticated(Task task)
{
try
{
state = SocketState.Established;
OnConnect?.Invoke();
if (!server)
Begin();
}
catch (Exception ex)
{
state = SocketState.Terminated;
Close();
Global.Log(ex);
}
}
private void DataReceived(Task<int> task)
{
try
{
// SocketError err;
if (state == SocketState.Closed || state == SocketState.Terminated)
return;
if (task.Result <= 0)
{
Close();
return;
}
receiveNetworkBuffer.Write(receiveBuffer, 0, (uint)task.Result);
OnReceive?.Invoke(receiveNetworkBuffer);
if (state == SocketState.Established)
ssl.ReadAsync(receiveBuffer, 0, receiveBuffer.Length).ContinueWith(DataReceived);
}
catch (Exception ex)
{
if (state != SocketState.Closed && !sock.Connected)
{
state = SocketState.Terminated;
Close();
}
Global.Log("SSLSocket", LogType.Error, ex.ToString());
}
}
public bool Begin()
{
if (state == SocketState.Established)
{
ssl.ReadAsync(receiveBuffer, 0, receiveBuffer.Length).ContinueWith(DataReceived);
return true;
}
else
return false;
}
public bool Trigger(ResourceTrigger trigger)
{
return true;
}
public void Destroy()
{
Close();
OnDestroy?.Invoke(this);
}
public AsyncReply<ISocket> Accept()
{
var reply = new AsyncReply<ISocket>();
try
{
sock.AcceptAsync().ContinueWith((x) =>
{
try
{
reply.Trigger(new SSLSocket(x.Result, cert, true));
}
catch
{
reply.Trigger(null);
}
}, null);
}
catch
{
state = SocketState.Terminated;
return null;
}
return reply;
}
public void Hold()
{
throw new NotImplementedException();
}
public void Unhold()
{
throw new NotImplementedException();
}
}
}

View File

@ -1,42 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Net.Sockets
{
public enum SocketState
{
Initial,
Listening,
Connecting,
Established,
Closed,
Terminated
}
}

View File

@ -1,450 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using Esiur.Misc;
using Esiur.Core;
using System.Threading;
using Esiur.Resource;
using System.Threading.Tasks;
using Esiur.Data;
namespace Esiur.Net.Sockets
{
public class TCPSocket : ISocket
{
Socket sock;
byte[] receiveBuffer;
bool held;
ArraySegment<byte> receiveBufferSegment;
NetworkBuffer receiveNetworkBuffer = new NetworkBuffer();
object sendLock = new object();
Queue<byte[]> sendBufferQueue = new Queue<byte[]>();
bool asyncSending;
bool began = false;
SocketState state = SocketState.Initial;
public event ISocketReceiveEvent OnReceive;
public event ISocketConnectEvent OnConnect;
public event ISocketCloseEvent OnClose;
public event DestroyedEvent OnDestroy;
SocketAsyncEventArgs socketArgs = new SocketAsyncEventArgs();
public bool Begin()
{
if (began)
return false;
began = true;
socketArgs.SetBuffer(receiveBuffer, 0, receiveBuffer.Length);
socketArgs.Completed += SocketArgs_Completed;
if (!sock.ReceiveAsync(socketArgs))
SocketArgs_Completed(null, socketArgs);
//sock.ReceiveAsync(receiveBufferSegment, SocketFlags.None).ContinueWith(DataReceived);
return true;
}
public AsyncReply<bool> Connect(string hostname, ushort port)
{
var rt = new AsyncReply<bool>();
try
{
state = SocketState.Connecting;
sock.ConnectAsync(hostname, port).ContinueWith((x) =>
{
if (x.IsFaulted)
rt.TriggerError(x.Exception);
else
{
state = SocketState.Established;
OnConnect?.Invoke();
Begin();
rt.Trigger(true);
}
});
}
catch (Exception ex)
{
rt.TriggerError(ex);
}
return rt;
}
private void DataReceived(Task<int> task)
{
try
{
// SocketError err;
if (state == SocketState.Closed || state == SocketState.Terminated)
return;
if (task.Result <= 0)
{
Close();
return;
}
//if (receiveNetworkBuffer.Protected)
// Console.WriteLine();
//lock (receiveNetworkBuffer.SyncLock)
receiveNetworkBuffer.Write(receiveBuffer, 0, (uint)task.Result);
//Console.WriteLine("TC IN: " + (uint)task.Result + " " + DC.ToHex(receiveBuffer, 0, (uint)task.Result));
OnReceive?.Invoke(receiveNetworkBuffer);
if (state == SocketState.Established)
{
sock.ReceiveAsync(receiveBufferSegment, SocketFlags.None).ContinueWith(DataReceived);
}
}
catch (Exception ex)
{
if (state != SocketState.Closed && !sock.Connected)
{
state = SocketState.Terminated;
Close();
}
Global.Log("TCPSocket", LogType.Error, ex.ToString());
}
}
private void SocketArgs_Completed(object sender, SocketAsyncEventArgs e)
{
try
{
// SocketError err;
if (state == SocketState.Closed || state == SocketState.Terminated)
return;
if (e.BytesTransferred == 0)
{
Close();
return;
}
//if (receiveNetworkBuffer.Protected)
// Console.WriteLine();
//lock (receiveNetworkBuffer.SyncLock)
receiveNetworkBuffer.Write(receiveBuffer, 0, (uint)e.BytesTransferred);
//Console.WriteLine("TC IN: " + (uint)e.BytesTransferred + " " + DC.ToHex(receiveBuffer, 0, (uint)e.BytesTransferred));
OnReceive?.Invoke(receiveNetworkBuffer);
if (state == SocketState.Established)
{
if (!sock.ReceiveAsync(socketArgs))
{
//Console.WriteLine("Sync");
SocketArgs_Completed(sender, e);
}
}
}
catch (Exception ex)
{
if (state != SocketState.Closed && !sock.Connected)
{
state = SocketState.Terminated;
Close();
}
Global.Log("TCPSocket", LogType.Error, ex.ToString());
}
}
public IPEndPoint LocalEndPoint
{
get { return (IPEndPoint)sock.LocalEndPoint; }
}
public TCPSocket()
{
sock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
receiveBuffer = new byte[sock.ReceiveBufferSize];
receiveBufferSegment = new ArraySegment<byte>(receiveBuffer);
}
public TCPSocket(string hostname, ushort port)
{
// create the socket
sock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
receiveBuffer = new byte[sock.ReceiveBufferSize];
receiveBufferSegment = new ArraySegment<byte>(receiveBuffer);
Connect(hostname, port);
}
private void DataSent(Task<int> task)
{
try
{
lock (sendLock)
{
if (sendBufferQueue.Count > 0)
{
byte[] data = sendBufferQueue.Dequeue();
//Console.WriteLine(Encoding.UTF8.GetString(data));
sock.SendAsync(new ArraySegment<byte>(data), SocketFlags.None).ContinueWith(DataSent);
}
else
{
asyncSending = false;
}
}
}
catch (Exception ex)
{
if (state != SocketState.Closed && !sock.Connected)
{
state = SocketState.Terminated;
Close();
}
asyncSending = false;
Global.Log("TCPSocket", LogType.Error, ex.ToString());
}
}
public TCPSocket(IPEndPoint localEndPoint)
{
// create the socket
sock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
receiveBuffer = new byte[sock.ReceiveBufferSize];
state = SocketState.Listening;
// bind
sock.Bind(localEndPoint);
// start listening
sock.Listen(UInt16.MaxValue);
}
public IPEndPoint RemoteEndPoint
{
get { return (IPEndPoint)sock.RemoteEndPoint; }
}
public SocketState State
{
get
{
return state;
}
}
public TCPSocket(Socket socket)
{
sock = socket;
receiveBuffer = new byte[sock.ReceiveBufferSize];
receiveBufferSegment = new ArraySegment<byte>(receiveBuffer);
if (socket.Connected)
state = SocketState.Established;
}
public void Close()
{
if (state != SocketState.Closed && state != SocketState.Terminated)
{
state = SocketState.Closed;
if (sock.Connected)
{
try
{
sock.Shutdown(SocketShutdown.Both);
}
catch
{
state = SocketState.Terminated;
}
}
OnClose?.Invoke();
}
}
public void Send(byte[] message)
{
Send(message, 0, message.Length);
}
public void Send(byte[] message, int offset, int size)
{
//sock.Blocking =
//sock.Send(message, offset, size, SocketFlags.None);
//return;
if (sock.Connected)
lock (sendLock)
{
if (asyncSending || held)
{
sendBufferQueue.Enqueue(message.Clip((uint)offset, (uint)size));
}
else
{
asyncSending = true;
sock.BeginSend(message, offset, size, SocketFlags.None, PacketSent, null);
//sock.SendAsync(new ArraySegment<byte>(msg), SocketFlags.None).ContinueWith(DataSent);
}
}
}
private void PacketSent(IAsyncResult ar)
{
try
{
if (sendBufferQueue.Count > 0)
{
lock (sendLock)
{
byte[] data = sendBufferQueue.Dequeue();
sock.BeginSend(data, 0, data.Length, SocketFlags.None, PacketSent, null);
}
}
else
{
asyncSending = false;
}
}
catch (Exception ex)
{
if (state != SocketState.Closed && !sock.Connected)
{
state = SocketState.Terminated;
Close();
}
asyncSending = false;
Global.Log("TCPSocket", LogType.Error, ex.ToString());
}
}
public bool Trigger(ResourceTrigger trigger)
{
return true;
}
public void Destroy()
{
Close();
OnDestroy?.Invoke(this);
}
public AsyncReply<ISocket> Accept()
{
var reply = new AsyncReply<ISocket>();
try
{
sock.AcceptAsync().ContinueWith((x) =>
{
try
{
reply.Trigger(new TCPSocket(x.Result));
}
catch
{
reply.Trigger(null);
}
});
}
catch
{
state = SocketState.Terminated;
return null;
}
return reply;
}
public void Hold()
{
held = true;
}
public void Unhold()
{
DataSent(null);
held = false;
}
}
}

View File

@ -1,313 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using Esiur.Net.Packets;
using Esiur.Misc;
using System.IO;
using Esiur.Core;
using Esiur.Resource;
using Esiur.Data;
namespace Esiur.Net.Sockets
{
public class WSSocket : ISocket
{
WebsocketPacket pkt_receive = new WebsocketPacket();
WebsocketPacket pkt_send = new WebsocketPacket();
ISocket sock;
NetworkBuffer receiveNetworkBuffer = new NetworkBuffer();
NetworkBuffer sendNetworkBuffer = new NetworkBuffer();
object sendLock = new object();
bool held;
public event ISocketReceiveEvent OnReceive;
public event ISocketConnectEvent OnConnect;
public event ISocketCloseEvent OnClose;
public event DestroyedEvent OnDestroy;
long totalSent, totalReceived;
bool processing = false;
public IPEndPoint LocalEndPoint
{
get { return (IPEndPoint)sock.LocalEndPoint; }
}
public IPEndPoint RemoteEndPoint
{
get { return sock.RemoteEndPoint; }
}
public SocketState State
{
get
{
return sock.State;
}
}
public WSSocket(ISocket socket)
{
pkt_send.FIN = true;
pkt_send.Mask = false;
pkt_send.Opcode = WebsocketPacket.WSOpcode.BinaryFrame;
sock = socket;
sock.OnClose += Sock_OnClose;
sock.OnConnect += Sock_OnConnect;
sock.OnReceive += Sock_OnReceive;
}
private void Sock_OnReceive(NetworkBuffer buffer)
{
if (sock.State == SocketState.Closed || sock.State == SocketState.Terminated)
return;
if (buffer.Protected)
return;
if (processing)
return;
var msg = buffer.Read();
if (msg == null)
return;
var wsPacketLength = pkt_receive.Parse(msg, 0, (uint)msg.Length);
//Console.WriteLine("WSP: " + wsPacketLength);
if (wsPacketLength < 0)
{
buffer.Protect(msg, 0, (uint)msg.Length + (uint)-wsPacketLength);
return;
}
uint offset = 0;
while (wsPacketLength > 0)
{
if (pkt_receive.Opcode == WebsocketPacket.WSOpcode.ConnectionClose)
{
Close();
return;
}
else if (pkt_receive.Opcode == WebsocketPacket.WSOpcode.Ping)
{
var pkt_pong = new WebsocketPacket();
pkt_pong.FIN = true;
pkt_pong.Mask = false;
pkt_pong.Opcode = WebsocketPacket.WSOpcode.Pong;
pkt_pong.Message = pkt_receive.Message;
offset += (uint)wsPacketLength;
Send(pkt_pong);
}
else if (pkt_receive.Opcode == WebsocketPacket.WSOpcode.Pong)
{
offset += (uint)wsPacketLength;
}
else if (pkt_receive.Opcode == WebsocketPacket.WSOpcode.BinaryFrame
|| pkt_receive.Opcode == WebsocketPacket.WSOpcode.TextFrame
|| pkt_receive.Opcode == WebsocketPacket.WSOpcode.ContinuationFrame)
{
totalReceived += pkt_receive.Message.Length;
//Console.WriteLine("RX " + pkt_receive.Message.Length + "/" + totalReceived);// + " " + DC.ToHex(message, 0, (uint)size));
receiveNetworkBuffer.Write(pkt_receive.Message);
offset += (uint)wsPacketLength;
//Console.WriteLine("WS IN: " + pkt_receive.Opcode.ToString() + " " + pkt_receive.Message.Length + " | " + offset + " " + string.Join(" ", pkt_receive.Message));// DC.ToHex(pkt_receive.Message));
}
else
Console.WriteLine("Unknown WS opcode:" + pkt_receive.Opcode);
if (offset == msg.Length)
{
// Console.WriteLine("WS IN: " + receiveNetworkBuffer.Available);
OnReceive?.Invoke(receiveNetworkBuffer);
return;
}
wsPacketLength = pkt_receive.Parse(msg, offset, (uint)msg.Length);
}
if (wsPacketLength < 0)//(offset < msg.Length) && (offset > 0))
{
//receiveNetworkBuffer.HoldFor(msg, offset, (uint)(msg.Length - offset), (uint)msg.Length + (uint)-wsPacketLength);
// save the incomplete packet to the heldBuffer queue
buffer.HoldFor(msg, offset, (uint)(msg.Length - offset), (uint)(msg.Length - offset) + (uint)-wsPacketLength);
}
//Console.WriteLine("WS IN: " + receiveNetworkBuffer.Available);
OnReceive?.Invoke(receiveNetworkBuffer);
processing = false;
if (buffer.Available > 0 && !buffer.Protected)
Sock_OnReceive(buffer);
}
private void Sock_OnConnect()
{
OnConnect?.Invoke();
}
private void Sock_OnClose()
{
OnClose?.Invoke();
}
public void Send(WebsocketPacket packet)
{
lock(sendLock)
if (packet.Compose())
sock.Send(packet.Data);
}
public void Send(byte[] message)
{
lock(sendLock)
{
if (held)
{
sendNetworkBuffer.Write(message);
}
else
{
totalSent += message.Length;
//Console.WriteLine("TX " + message.Length +"/"+totalSent);// + " " + DC.ToHex(message, 0, (uint)size));
pkt_send.Message = message;
if (pkt_send.Compose())
sock.Send(pkt_send.Data);
}
}
}
public void Send(byte[] message, int offset, int size)
{
lock (sendLock)
{
if (held)
{
sendNetworkBuffer.Write(message, (uint)offset, (uint)size);
}
else
{
totalSent += size;
//Console.WriteLine("TX " + size + "/"+totalSent);// + " " + DC.ToHex(message, 0, (uint)size));
pkt_send.Message = new byte[size];
Buffer.BlockCopy(message, offset, pkt_send.Message, 0, size);
if (pkt_send.Compose())
sock.Send(pkt_send.Data);
}
}
}
public void Close()
{
sock.Close();
}
public AsyncReply<bool> Connect(string hostname, ushort port)
{
throw new NotImplementedException();
}
public bool Begin()
{
return sock.Begin();
}
public bool Trigger(ResourceTrigger trigger)
{
return true;
}
public void Destroy()
{
Close();
OnDestroy?.Invoke(this);
}
public AsyncReply<ISocket> Accept()
{
throw new NotImplementedException();
}
public void Hold()
{
//Console.WriteLine("WS Hold ");
held = true;
}
public void Unhold()
{
lock(sendLock)
{
held = false;
var message = sendNetworkBuffer.Read();
//Console.WriteLine("WS Unhold {0}", message == null ? 0 : message.Length);
if (message == null)
return;
totalSent += message.Length;
pkt_send.Message = message;
if (pkt_send.Compose())
sock.Send(pkt_send.Data);
}
}
}
}

View File

@ -1,51 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Net.Sockets;
using System.Net;
using System.Collections;
using Esiur.Misc;
using Esiur.Data;
namespace Esiur.Net.TCP
{
public class TCPConnection: NetworkConnection
{
private KeyList<string, object> variables = new KeyList<string, object>();
public KeyList<string, object> Variables
{
get
{
return variables;
}
}
}
}

View File

@ -1,66 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using Esiur.Data;
using Esiur.Net.Sockets;
using Esiur.Core;
using Esiur.Resource;
namespace Esiur.Net.TCP
{
public abstract class TCPFilter: IResource
{
public Instance Instance
{
get;
set;
}
public event DestroyedEvent OnDestroy;
public abstract AsyncReply<bool> Trigger(ResourceTrigger trigger);
public virtual bool Connected(TCPConnection sender)
{
return false;
}
public virtual bool Disconnected(TCPConnection sender)
{
return false;
}
public abstract bool Execute(byte[] msg, NetworkBuffer data, TCPConnection sender);
public void Destroy()
{
throw new NotImplementedException();
}
}
}

View File

@ -1,140 +0,0 @@
/*
Copyright (c) 2017-2019 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Net.Sockets;
using Esiur.Misc;
using System.Threading;
using Esiur.Data;
using Esiur.Core;
using System.Net;
using Esiur.Resource;
namespace Esiur.Net.TCP
{
public class TCPServer : NetworkServer<TCPConnection>, IResource
{
[Storable]
string ip
{
get;
set;
}
[Storable]
ushort port
{
get;
set;
}
[Storable]
uint timeout
{
get;
set;
}
[Storable]
uint clock
{
get;
set;
}
public Instance Instance { get; set; }
TCPFilter[] filters = null;
public AsyncReply<bool> Trigger(ResourceTrigger trigger)
{
if (trigger == ResourceTrigger.Initialize)
{
TCPSocket listener;
if (ip != null)
listener =new TCPSocket(new IPEndPoint(IPAddress.Parse(ip), port));
else
listener = new TCPSocket(new IPEndPoint(IPAddress.Any, port));
Start(listener, timeout, clock);
}
else if (trigger == ResourceTrigger.Terminate)
{
Stop();
}
else if (trigger == ResourceTrigger.SystemReload)
{
Trigger(ResourceTrigger.Terminate);
Trigger(ResourceTrigger.Initialize);
}
else if (trigger == ResourceTrigger.SystemInitialized)
{
Instance.Children<TCPFilter>().Then(x => filters = x);
}
return new AsyncReply<bool>(true);
}
protected override void DataReceived(TCPConnection sender, NetworkBuffer data)
{
var msg = data.Read();
foreach (var filter in filters)
{
if (filter.Execute(msg, data, sender))
return;
}
}
private void SessionModified(TCPConnection session, string key, object newValue)
{
}
protected override void ClientConnected(TCPConnection sender)
{
foreach (var filter in filters)
{
filter.Connected(sender);
}
}
protected override void ClientDisconnected(TCPConnection sender)
{
foreach (var filter in filters)
{
filter.Disconnected(sender);
}
}
}
}

View File

@ -1,37 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Net.TCP
{
public class TCPSession : NetworkSession
{
}
}

View File

@ -1,57 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Net;
using Esiur.Data;
using Esiur.Core;
using Esiur.Resource;
namespace Esiur.Net.UDP
{
public abstract class UDPFilter : IResource
{
public Instance Instance
{
get;
set;
}
public event DestroyedEvent OnDestroy;
public abstract AsyncReply<bool> Trigger(ResourceTrigger trigger);
public abstract bool Execute(byte[] data, IPEndPoint sender);
public void Destroy()
{
throw new NotImplementedException();
}
}
}

View File

@ -1,197 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using System.Collections;
using Esiur.Data;
using Esiur.Misc;
using Esiur.Engine;
using Esiur.Resource;
namespace Esiur.Net.UDP
{
/* public class IIPConnection
{
public EndPoint SenderPoint;
public
}*/
public class UDPServer : IResource
{
Thread Receiver;
UdpClient Udp;
public event DestroyedEvent OnDestroy;
public Instance Instance
{
get;
set;
}
[Storable]
string ip
{
get;
set;
}
[Storable]
ushort port
{
get;
set;
}
public bool Trigger(ResourceTrigger trigger)
{
if (trigger == ResourceTrigger.Initialize)
{
var address = ip == null ? IPAddress.Any : IPAddress.Parse(ip);
Udp = new UdpClient(new IPEndPoint(address, (int)port));
Receiver = new Thread(Receiving);
Receiver.Start();
}
else if (trigger == ResourceTrigger.Terminate)
{
if (Receiver != null)
Receiver.Abort();
}
return true;
}
private void Receiving()
{
IPEndPoint ep = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
byte[] b = Udp.Receive(ref ep);
foreach(var child in Instance.Children)
{
var f = child as UDPFilter;
try
{
if (f.Execute(b, ep))
{
break;
}
}
catch (Exception ex)
{
Global.Log("UDPServer", LogType.Error, ex.ToString());
//Console.WriteLine(ex.ToString());
}
}
}
}
public bool Send(byte[] Data, int Count, IPEndPoint EP)
{
try
{
Udp.Send(Data, Count, EP);
return true;
}
catch
{
return false;
}
}
public bool Send(byte[] Data, IPEndPoint EP)
{
try
{
Udp.Send(Data, Data.Length, EP);
return true;
}
catch
{
return false;
}
}
public bool Send(byte[] Data, int Count, string Host, int Port)
{
try
{
Udp.Send(Data, Count, Host, Port);
return true;
}
catch
{
return false;
}
}
public bool Send(byte[] Data, string Host, int Port)
{
try
{
Udp.Send(Data, Data.Length, Host, Port);
return true;
}
catch
{
return false;
}
}
public bool Send(string Data, IPEndPoint EP)
{
try
{
Udp.Send(Encoding.Default.GetBytes(Data), Data.Length, EP);
return true;
}
catch
{
return false;
}
}
public bool Send(string Data, string Host, int Port)
{
try
{
Udp.Send(Encoding.Default.GetBytes(Data), Data.Length, Host, Port);
return true;
}
catch
{
return false;
}
}
public void Destroy()
{
Udp.Close();
OnDestroy?.Invoke(this);
}
}
}

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Configuration>Debug</Configuration>
<TargetFramework>netstandard2.0</TargetFramework>
<PublishDir>M:\opt\esiur</PublishDir>
<Platform>Any CPU</Platform>
</PropertyGroup>
</Project>

View File

@ -1,198 +0,0 @@
using Esiur.Resource;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
namespace Esiur.Proxy
{
public static class ResourceProxy
{
static Dictionary<Type, Type> cache = new Dictionary<Type, Type>();
#if NETSTANDARD
static MethodInfo modifyMethod = typeof(Instance).GetTypeInfo().GetMethod("Modified");
static MethodInfo instanceGet = typeof(IResource).GetTypeInfo().GetProperty("Instance").GetGetMethod();
#else
static MethodInfo modifyMethod = typeof(Instance).GetMethod("Modified");
static MethodInfo instanceGet = typeof(IResource).GetProperty("Instance").GetGetMethod();
#endif
public static Type GetBaseType(object resource)
{
return GetBaseType(resource.GetType());
}
public static Type GetBaseType(Type type)
{
if (type.FullName.Contains("Esiur.Proxy.T"))
#if NETSTANDARD
return type.GetTypeInfo().BaseType;
#else
return type.BaseType;
#endif
else
return type;
}
public static Type GetProxy(Type type)
{
if (cache.ContainsKey(type))
return cache[type];
#if NETSTANDARD
var typeInfo = type.GetTypeInfo();
if (typeInfo.IsSealed)
throw new Exception("Sealed class can't be proxied.");
var props = from p in typeInfo.GetProperties()
where p.CanWrite && p.GetSetMethod().IsVirtual &&
p.GetCustomAttributes(typeof(ResourceProperty), false).Count() > 0
select p;
#else
if (type.IsSealed)
throw new Exception("Sealed class can't be proxied.");
var props = from p in type.GetProperties()
where p.CanWrite && p.GetSetMethod().IsVirtual &&
p.GetCustomAttributes(typeof(ResourceProperty), false).Count() > 0
select p;
#endif
var assemblyName = new AssemblyName("Esiur.Proxy.T." + type.Namespace);
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name);
var typeName = Assembly.CreateQualifiedName(assemblyName.FullName, type.Name);
var typeBuilder = moduleBuilder.DefineType(typeName,
TypeAttributes.Public | TypeAttributes.Class, type);
foreach (PropertyInfo propertyInfo in props)
CreateProperty(propertyInfo, typeBuilder, type);
#if NETSTANDARD
var t = typeBuilder.CreateTypeInfo().AsType();
cache.Add(type, t);
return t;
#else
var t = typeBuilder.CreateType();
cache.Add(type, t);
return t;
#endif
}
public static Type GetProxy<T>()
where T : IResource
{
return GetProxy(typeof(T));
}
//private static void C
private static void CreateProperty(PropertyInfo pi, TypeBuilder typeBuilder, Type resourceType)
{
var propertyBuilder = typeBuilder.DefineProperty(pi.Name, PropertyAttributes.None, pi.PropertyType, null);
// Create set method
MethodBuilder builder = typeBuilder.DefineMethod("set_" + pi.Name,
MethodAttributes.Public | MethodAttributes.Virtual, null, new Type[] { pi.PropertyType });
builder.DefineParameter(1, ParameterAttributes.None, "value");
ILGenerator g = builder.GetILGenerator();
var getInstance = resourceType.GetTypeInfo().GetProperty("Instance").GetGetMethod();
g.Emit(OpCodes.Nop);
g.Emit(OpCodes.Ldarg_0);
g.Emit(OpCodes.Call, getInstance);
g.Emit(OpCodes.Ldstr, pi.Name);
g.Emit(OpCodes.Callvirt, modifyMethod);
g.Emit(OpCodes.Nop);
g.Emit(OpCodes.Ldarg_0);
g.Emit(OpCodes.Ldarg_1);
g.Emit(OpCodes.Call, pi.GetSetMethod());
g.Emit(OpCodes.Nop);
g.Emit(OpCodes.Ret);
propertyBuilder.SetSetMethod(builder);
// builder = typeBuilder.DefineMethod("get_" + pi.Name, MethodAttributes.Public | MethodAttributes.Virtual, pi.PropertyType, null);
// g = builder.GetILGenerator();
// g.Emit(OpCodes.Ldarg_0);
// g.Emit(OpCodes.Call, pi.GetGetMethod());
// g.Emit(OpCodes.Ret);
// propertyBuilder.SetGetMethod(builder);
/*
Label callModified = g.DefineLabel();
Label exitMethod = g.DefineLabel();
// IL_0000: ldarg.0
//IL_0001: call instance class [Esiur]Esiur.Resource.Instance [Esiur]Esiur.Resource.Resource::get_Instance()
//// (no C# code)
//IL_0006: dup
//IL_0007: brtrue.s IL_000c
//IL_0009: pop
//// }
//IL_000a: br.s IL_0017
//// (no C# code)
//IL_000c: ldstr "Level3"
//IL_0011: call instance void [Esiur]Esiur.Resource.Instance::Modified(string)
//IL_0016: nop
//IL_0017: ret
// Add IL code for set method
g.Emit(OpCodes.Nop);
g.Emit(OpCodes.Ldarg_0);
g.Emit(OpCodes.Ldarg_1);
g.Emit(OpCodes.Call, pi.GetSetMethod());
// IL_0000: ldarg.0
// IL_0001: call instance class [Esiur]Esiur.Resource.Instance [Esiur]Esiur.Resource.Resource::get_Instance()
// IL_0006: ldstr "Level3"
//IL_000b: callvirt instance void [Esiur]Esiur.Resource.Instance::Modified(string)
//IL_0010: ret
// Call property changed for object
g.Emit(OpCodes.Nop);
g.Emit(OpCodes.Ldarg_0);
g.Emit(OpCodes.Call, instanceGet);
g.Emit(OpCodes.Dup);
g.Emit(OpCodes.Brtrue_S, callModified);
g.Emit(OpCodes.Pop);
g.Emit(OpCodes.Br_S, exitMethod);
g.MarkLabel(callModified);
g.Emit(OpCodes.Ldstr, pi.Name);
g.Emit(OpCodes.Callvirt, modifyMethod);
g.Emit(OpCodes.Nop);
g.MarkLabel(exitMethod);
g.Emit(OpCodes.Ret);
propertyBuilder.SetSetMethod(builder);
// create get method
*/
}
}
}

View File

@ -1,47 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Esiur.Data;
using Esiur.Core;
namespace Esiur.Resource
{
public delegate bool QueryFilter<T>(T value);
public interface IResource : IDestructible
{
AsyncReply<bool> Trigger(ResourceTrigger trigger);
Instance Instance
{
get;
set;
}
}
}

View File

@ -1,67 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using Esiur.Data;
using Esiur.Core;
using Esiur.Resource.Template;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Resource
{
public interface IStore:IResource
{
AsyncReply<IResource> Get(string path);//, Func<IResource, bool> filter = null);
//AsyncReply<IResource> Retrieve(uint iid);
bool Put(IResource resource);
string Link(IResource resource);
bool Record(IResource resource, string propertyName, object value, ulong age, DateTime dateTime);
bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime);
bool Remove(IResource resource);
AsyncReply<bool> AddChild(IResource parent, IResource child);
AsyncReply<bool> RemoveChild(IResource parent, IResource child);
AsyncReply<bool> AddParent(IResource child, IResource parent);
AsyncReply<bool> RemoveParent(IResource child, IResource parent);
AsyncBag<T> Children<T>(IResource resource, string name) where T : IResource;
AsyncBag<T> Parents<T>(IResource resource, string name) where T : IResource;
//AsyncReply<PropertyValue[]> GetPropertyRecord(IResource resource, string propertyName, ulong fromAge, ulong toAge);
//AsyncReply<PropertyValue[]> GetPropertyRecordByDate(IResource resource, string propertyName, DateTime fromDate, DateTime toDate);
//AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> GetRecord(IResource resource, ulong fromAge, ulong toAge);
// AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> GetRecordByDate(IResource resource, DateTime fromDate, DateTime toDate);
AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> GetRecord(IResource resource, DateTime fromDate, DateTime toDate);
}
}

View File

@ -1,919 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Esiur.Data;
using System.Runtime.CompilerServices;
using System.Reflection;
using Esiur.Net.IIP;
using Esiur.Misc;
using Esiur.Security.Permissions;
using Esiur.Resource.Template;
using Esiur.Security.Authority;
using Esiur.Proxy;
using Esiur.Core;
namespace Esiur.Resource
{
public class Instance
{
string name;
//IQueryable<IResource> children;//
//AutoList<IResource, Instance> children;// = new AutoList<IResource, Instance>();
WeakReference<IResource> resource;
IStore store;
//AutoList<IResource, Instance> parents;// = new AutoList<IResource>();
//bool inherit;
ResourceTemplate template;
AutoList<IPermissionsManager, Instance> managers;// = new AutoList<IPermissionManager, Instance>();
public delegate void ResourceModifiedEvent(IResource resource, string propertyName, object newValue);
//public delegate void ResourceEventOccurredEvent(IResource resource, string eventName, string[] users, DistributedConnection[] connections, object[] args);
public delegate void ResourceEventOccurredEvent(IResource resource, object issuer, Session[] receivers, string eventName, object[] args);
public delegate void ResourceDestroyedEvent(IResource resource);
public event ResourceModifiedEvent ResourceModified;
public event ResourceEventOccurredEvent ResourceEventOccurred;
public event ResourceDestroyedEvent ResourceDestroyed;
bool loading = false;
KeyList<string, object> attributes;
List<ulong> ages = new List<ulong>();
List<DateTime> modificationDates = new List<DateTime>();
private ulong instanceAge;
private DateTime instanceModificationDate;
uint id;
/// <summary>
/// Instance attributes are custom properties associated with the instance, a place to store information by IStore.
/// </summary>
public KeyList<string, object> Attributes
{
get
{
return attributes;
}
}
public override string ToString()
{
return name + " (" + Link + ")";
}
public bool RemoveAttributes(string[] attributes = null)
{
if (attributes == null)
this.attributes.Clear();
else
{
foreach (var attr in attributes)
this.attributes.Remove(attr);
}
return true;
}
public Structure GetAttributes(string[] attributes = null)
{
var st = new Structure();
if (attributes == null)
{
var clone = this.attributes.Keys.ToList();
clone.Add("managers");
attributes = clone.ToArray();// this.attributes.Keys.ToList().Add("managers");
}
foreach (var attr in attributes)
{
if (attr == "name")
st["name"] = this.name;
else if (attr == "managers")
{
var mngrs = new List<Structure>();
foreach (var manager in this.managers)
mngrs.Add(new Structure()
{
["type"] = manager.GetType().FullName + "," + manager.GetType().GetTypeInfo().Assembly.GetName().Name,
["settings"] = manager.Settings
});
st["managers"] = mngrs.ToArray();
}
else if (attr == "parents")
{
//st["parents"] = parents.ToArray();
}
else if (attr == "children")
{
//st["children"] = children.ToArray();
}
else if (attr == "childrenCount")
{
//st["childrenCount"] = children.Count;
}
else if (attr == "type")
{
st["type"] = resource.GetType().FullName;
}
else
st[attr] = this.attributes[attr];
}
return st;
}
public bool SetAttributes(Structure attributes, bool clearAttributes = false)
{
try
{
if (clearAttributes)
this.attributes.Clear();
foreach (var attr in attributes)
if (attr.Key == "name")
this.name = attr.Value as string;
else if (attr.Key == "managers")
{
this.managers.Clear();
var mngrs = attr.Value as object[];
foreach (var mngr in mngrs)
{
var m = mngr as Structure;
var type = Type.GetType(m["type"] as string);
if (Codec.ImplementsInterface(type, typeof(IPermissionsManager)))
{
var settings = m["settings"] as Structure;
var manager = Activator.CreateInstance(type) as IPermissionsManager;
IResource res;
if (this.resource.TryGetTarget(out res))
{
manager.Initialize(settings, res);
this.managers.Add(manager);
}
}
else
return false;
}
}
else
{
this.attributes[attr.Key] = attr.Value;
}
}
catch
{
return false;
}
return true;
}
/*
public Structure GetAttributes()
{
var st = new Structure();
foreach (var a in attributes.Keys)
st[a] = attributes[a];
st["name"] = name;
var mngrs = new List<Structure>();
foreach (var manager in managers)
{
var mngr = new Structure();
mngr["settings"] = manager.Settings;
mngr["type"] = manager.GetType().FullName;
mngrs.Add(mngr);
}
st["managers"] = mngrs;
return st;
}*/
/// <summary>
/// Get the age of a given property index.
/// </summary>
/// <param name="index">Zero-based property index.</param>
/// <returns>Age.</returns>
public ulong GetAge(byte index)
{
if (index < ages.Count)
return ages[index];
else
return 0;
}
/// <summary>
/// Set the age of a property.
/// </summary>
/// <param name="index">Zero-based property index.</param>
/// <param name="value">Age.</param>
public void SetAge(byte index, ulong value)
{
if (index < ages.Count)
{
ages[index] = value;
if (value > instanceAge)
instanceAge = value;
}
}
/// <summary>
/// Set the modification date of a property.
/// </summary>
/// <param name="index">Zero-based property index.</param>
/// <param name="value">Modification date.</param>
public void SetModificationDate(byte index, DateTime value)
{
if (index < modificationDates.Count)
{
modificationDates[index] = value;
if (value > instanceModificationDate)
instanceModificationDate = value;
}
}
/// <summary>
/// Get modification date of a specific property.
/// </summary>
/// <param name="index">Zero-based property index</param>
/// <returns>Modification date.</returns>
public DateTime GetModificationDate(byte index)
{
if (index < modificationDates.Count)
return modificationDates[index];
else
return DateTime.MinValue;
}
/// <summary>
/// Load property value (used by stores)
/// </summary>
/// <param name="name">Property name</param>
/// <param name="age">Property age</param>
/// <param name="value">Property value</param>
/// <returns></returns>
public bool LoadProperty(string name, ulong age, DateTime modificationDate, object value)
{
IResource res;
if (!resource.TryGetTarget(out res))
return false;
var pt = template.GetPropertyTemplateByName(name);
if (pt == null)
return false;
/*
#if NETSTANDARD
var pi = resource.GetType().GetTypeInfo().GetProperty(name, new[] { resource.GetType() });
#else
var pi = resource.GetType().GetProperty(pt.Name);
#endif
*/
if (pt.Info.PropertyType == typeof(DistributedPropertyContext))
return false;
if (pt.Info.CanWrite)
{
try
{
loading = true;
pt.Info.SetValue(res, DC.CastConvert(value, pt.Info.PropertyType));
}
catch (Exception ex)
{
//Console.WriteLine(resource.ToString() + " " + name);
Global.Log(ex);
}
loading = false;
}
SetAge(pt.Index, age);
SetModificationDate(pt.Index, modificationDate);
return true;
}
/// <summary>
/// Age of the instance, incremented by 1 in every modification.
/// </summary>
public ulong Age
{
get { return instanceAge; }
internal set { instanceAge = value; }
}
/// <summary>
/// Last modification date.
/// </summary>
public DateTime ModificationDate
{
get
{
return instanceModificationDate;
}
}
/// <summary>
/// Instance Id.
/// </summary>
public uint Id
{
get { return id; }
}
/// <summary>
/// Import properties from bytes array.
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
public bool Deserialize(PropertyValue[] properties)
{
for (byte i = 0; i < properties.Length; i++)
{
var pt = this.template.GetPropertyTemplateByIndex(i);
if (pt != null)
{
var pv = properties[i];
LoadProperty(pt.Name, pv.Age, pv.Date, pv.Value);
}
}
return true;
}
/// <summary>
/// Export all properties with ResourceProperty attributed as bytes array.
/// </summary>
/// <returns></returns>
public PropertyValue[] Serialize()
{
List<PropertyValue> props = new List<PropertyValue>();
foreach (var pt in template.Properties)
{
/*
#if NETSTANDARD
var pi = resource.GetType().GetTypeInfo().GetProperty(pt.Name);
#else
var pi = resource.GetType().GetProperty(pt.Name);
#endif
*/
//if (pt.Serilize)
//{
IResource res;
if (resource.TryGetTarget(out res))
{
var rt = pt.Serilize ? pt.Info.GetValue(res, null) : null;
props.Add(new PropertyValue(rt, ages[pt.Index], modificationDates[pt.Index]));
}
//}
}
return props.ToArray();
}
/*
public bool Deserialize(byte[] data, uint offset, uint length)
{
var props = Codec.ParseValues(data, offset, length);
Deserialize(props);
return true;
}
*/
/*
public byte[] Serialize(bool includeLength = false, DistributedConnection sender = null)
{
//var bl = new BinaryList();
List<object> props = new List<object>();
foreach (var pt in template.Properties)
{
var pi = resource.GetType().GetProperty(pt.Name);
var rt = pi.GetValue(resource, null);
// this is a cool hack to let the property know the sender
if (rt is Func<DistributedConnection, object>)
rt = (rt as Func<DistributedConnection, object>)(sender);
props.Add(rt);
}
if (includeLength)
{
return Codec.Compose(props.ToArray(), false);
}
else
{
var rt = Codec.Compose(props.ToArray(), false);
return DC.Clip(rt, 4, (uint)(rt.Length - 4));
}
}
public byte[] StorageSerialize()
{
var props = new List<object>();
foreach(var pt in template.Properties)
{
if (!pt.Storable)
continue;
var pi = resource.GetType().GetProperty(pt.Name);
if (!pi.CanWrite)
continue;
var rt = pi.GetValue(resource, null);
props.Add(rt);
}
return Codec.Compose(props.ToArray(), false);
}
*/
/// <summary>
/// If True, the instance can be stored to disk.
/// </summary>
/// <returns></returns>
public bool IsStorable()
{
#if NETSTANDARD
var attrs = resource.GetType().GetTypeInfo().GetCustomAttributes(typeof(Storable), true).ToArray();
#else
var attrs = resource.GetType().GetCustomAttributes(typeof(Storable), true);
#endif
return attrs.Length > 0;
}
internal void EmitModification(PropertyTemplate pt, object value)
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
instanceAge++;
var now = DateTime.UtcNow;
ages[pt.Index] = instanceAge;
modificationDates[pt.Index] = now;
if (pt.Storage == StorageMode.NonVolatile)
{
store.Modify(res, pt.Name, value, ages[pt.Index], now);
}
else if (pt.Storage == StorageMode.Recordable)
{
store.Record(res, pt.Name, value, ages[pt.Index], now);
}
ResourceModified?.Invoke(res, pt.Name, value);
}
}
/// <summary>
/// Notify listeners that a property was modified.
/// </summary>
/// <param name="propertyName"></param>
/// <param name="newValue"></param>
/// <param name="oldValue"></param>
public void Modified([CallerMemberName] string propertyName = "")
{
if (loading)
return;
object value;
if (GetPropertyValue(propertyName, out value))
{
var pt = template.GetPropertyTemplateByName(propertyName);
EmitModification(pt, value);
}
}
// internal void EmitResourceEvent(string name, string[] users, DistributedConnection[] connections, object[] args)
internal void EmitResourceEvent(object issuer, Session[] receivers, string name, object[] args)
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
ResourceEventOccurred?.Invoke(res, issuer, receivers, name, args);
}
}
/// <summary>
/// Get the value of a given property by name.
/// </summary>
/// <param name="name">Property name</param>
/// <param name="value">Output value</param>
/// <returns>True, if the resource has the property.</returns>
public bool GetPropertyValue(string name, out object value)
{
/*
#if NETSTANDARD
PropertyInfo pi = resource.GetType().GetTypeInfo().GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
#else
PropertyInfo pi = resource.GetType().GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
#endif
*/
var pt = template.GetPropertyTemplateByName(name);
if (pt != null && pt.Info != null)
{
/*
#if NETSTANDARD
object[] ca = pi.GetCustomAttributes(typeof(ResourceProperty), false).ToArray();
#else
object[] ca = pi.GetCustomAttributes(typeof(ResourceProperty), false);
#endif
if (ca.Length > 0)
{
value = pi.GetValue(resource, null);
//if (value is Func<IManager, object>)
// value = (value as Func<IManager, object>)(sender);
return true;
}
*/
IResource res;
if (resource.TryGetTarget(out res))
value = pt.Info.GetValue(res, null);
else
{
value = null;
return false;
}
return true;
}
value = null;
return false;
}
/*
public bool Inherit
{
get { return inherit; }
}*/
/// <summary>
/// List of parents.
/// </summary>
//public AutoList<IResource, Instance> Parents => parents;
/// <summary>
/// Store responsible for creating and keeping the resource.
/// </summary>
public IStore Store
{
get { return store; }
}
/// <summary>
/// List of children.
/// </summary>
// public AutoList<IResource, Instance> Children => children;
/// <summary>
/// The unique and permanent link to the resource.
/// </summary>
public string Link
{
get
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
if (res == res.Instance.store)
return name; // root store
else
return store.Link(res);
}
else
return null;
}
}
public AsyncBag<T> Children<T>(string name = null) where T : IResource
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
//if (!(store is null))
return store.Children<T>(res, name);
//else
// return (res as IStore).Children<T>(res, name);
}
else
return new AsyncBag<T>(null);
}
public AsyncBag<T> Parents<T>(string name = null) where T : IResource
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
return store.Parents<T>(res, name);
}
else
return new AsyncBag<T>(null);
}
/*
{
get
{
if (this.store != null)
return this.store.Link(this.resource);
else
{
var l = new List<string>();
//l.Add(name);
var p = this.resource; // parents.First();
while (true)
{
l.Insert(0, p.Instance.name);
if (p.Instance.parents.Count == 0)
break;
p = p.Instance.parents.First();
}
return String.Join("/", l.ToArray());
}
}
}
*
*/
/// <summary>
/// Instance name.
/// </summary>
public string Name
{
get { return name; }
set { name = value; }
}
/// <summary>
/// Resource managed by this instance.
/// </summary>
public IResource Resource
{
get
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
return res;
}
else
return null;
}
}
/// <summary>
/// Resource template describes the properties, functions and events of the resource.
/// </summary>
public ResourceTemplate Template
{
get { return template; }
/*
internal set
{
template = Warehouse.GetTemplate(resource.GetType());
// set ages
for (byte i = 0; i < template.Properties.Length; i++)
{
ages.Add(0);
modificationDates.Add(DateTime.MinValue);
}
}
*/
}
/// <summary>
/// Check for permission.
/// </summary>
/// <param name="session">Caller sessions.</param>
/// <param name="action">Action type</param>
/// <param name="member">Function, property or event to check for permission.</param>
/// <param name="inquirer">Permission inquirer.</param>
/// <returns>Ruling.</returns>
public Ruling Applicable(Session session, ActionType action, MemberTemplate member, object inquirer = null)
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
foreach (IPermissionsManager manager in managers)
{
var r = manager.Applicable(res, session, action, member, inquirer);
if (r != Ruling.DontCare)
return r;
}
}
return Ruling.DontCare;
}
/// <summary>
/// Execution managers.
/// </summary>
public AutoList<IPermissionsManager, Instance> Managers => managers;
/// <summary>
/// Create new instance.
/// </summary>
/// <param name="id">Instance Id.</param>
/// <param name="name">Name of the instance.</param>
/// <param name="resource">Resource to manage.</param>
/// <param name="store">Store responsible for the resource.</param>
public Instance(uint id, string name, IResource resource, IStore store, ResourceTemplate customTemplate = null, ulong age = 0)
{
this.store = store;
this.resource = new WeakReference<IResource>(resource);
this.id = id;
this.name = name;
this.instanceAge = age;
this.attributes = new KeyList<string, object>(this);
//children = new AutoList<IResource, Instance>(this);
//parents = new AutoList<IResource, Instance>(this);
managers = new AutoList<IPermissionsManager, Instance>(this);
//children.OnAdd += Children_OnAdd;
//children.OnRemoved += Children_OnRemoved;
//parents.OnAdd += Parents_OnAdd;
//parents.OnRemoved += Parents_OnRemoved;
resource.OnDestroy += Resource_OnDestroy;
if (customTemplate != null)
this.template = customTemplate;
else
this.template = Warehouse.GetTemplate(resource.GetType());
// set ages
for (byte i = 0; i < template.Properties.Length; i++)
{
ages.Add(0);
modificationDates.Add(DateTime.MinValue);
}
// connect events
Type t = ResourceProxy.GetBaseType(resource);
#if NETSTANDARD
var events = t.GetTypeInfo().GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
#else
var events = t.GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
#endif
foreach (var evt in events)
{
//if (evt.EventHandlerType != typeof(ResourceEventHanlder))
// continue;
if (evt.EventHandlerType == typeof(ResourceEventHanlder))
{
var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
if (ca.Length == 0)
continue;
ResourceEventHanlder proxyDelegate = (args) => EmitResourceEvent(null, null, evt.Name, args);
evt.AddEventHandler(resource, proxyDelegate);
}
else if (evt.EventHandlerType == typeof(CustomResourceEventHanlder))
{
var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
if (ca.Length == 0)
continue;
CustomResourceEventHanlder proxyDelegate = (issuer, receivers, args) => EmitResourceEvent(issuer, receivers, evt.Name, args);
evt.AddEventHandler(resource, proxyDelegate);
}
/*
else if (evt.EventHandlerType == typeof(CustomUsersEventHanlder))
{
var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
if (ca.Length == 0)
continue;
CustomUsersEventHanlder proxyDelegate = (users, args) => EmitResourceEvent(evt.Name, users, null, args);
evt.AddEventHandler(resource, proxyDelegate);
}
else if (evt.EventHandlerType == typeof(CustomConnectionsEventHanlder))
{
var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
if (ca.Length == 0)
continue;
CustomConnectionsEventHanlder proxyDelegate = (connections, args) => EmitResourceEvent(evt.Name, null, connections, args);
evt.AddEventHandler(resource, proxyDelegate);
}
else if (evt.EventHandlerType == typeof(CustomReceiversEventHanlder))
{
var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true);
if (ca.Length == 0)
continue;
CustomReceiversEventHanlder proxyDelegate = (users, connections, args) => EmitResourceEvent(evt.Name, users, connections, args);
evt.AddEventHandler(resource, proxyDelegate);
}
*/
}
}
//IQueryable<IResource> Children => store.GetChildren(this);
/*
* private void Children_OnRemoved(Instance parent, IResource value)
{
value.Instance.parents.Remove(resource);
}
private void Children_OnAdd(Instance parent, IResource value)
{
if (!value.Instance.parents.Contains(resource))
value.Instance.parents.Add(resource);
}
private void Parents_OnRemoved(Instance parent, IResource value)
{
value.Instance.children.Remove(resource);
}
private void Parents_OnAdd(Instance parent, IResource value)
{
if (!value.Instance.children.Contains(resource))
value.Instance.children.Add(resource);
}
*/
private void Resource_OnDestroy(object sender)
{
ResourceDestroyed?.Invoke((IResource)sender);
}
}
}

View File

@ -1,60 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Esiur.Core;
namespace Esiur.Resource
{
public class Resource : IResource
{
public Instance Instance { get; set; }
public event DestroyedEvent OnDestroy;
public virtual void Destroy()
{
OnDestroy?.Invoke(this);
}
public virtual AsyncReply<bool> Trigger(ResourceTrigger trigger)
{
if (trigger == ResourceTrigger.Initialize)
return new AsyncReply<bool>(this.Create());
else
return new AsyncReply<bool>(true);
}
public virtual bool Create()
{
return true;
}
~Resource()
{
Destroy();
}
}
}

View File

@ -1,53 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Resource
{
[AttributeUsage(AttributeTargets.Event)]
public class ResourceEvent : System.Attribute
{
string expansion;
public string Expansion
{
get
{
return expansion;
}
}
public ResourceEvent(string expansion = null)
{
this.expansion = expansion;
}
}
}

View File

@ -1,45 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using Esiur.Data;
using Esiur.Core;
using Esiur.Net.IIP;
using Esiur.Security.Authority;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Resource
{
public delegate void ResourceEventHanlder(params object[] args);
// public delegate void CustomUsersEventHanlder(string[] usernames, params object[] args);
//public delegate void CustomReceiversEventHanlder(DistributedConnection[] connections, params object[] args);
//public delegate void CustomInquirerEventHanlder(object inquirer, params object[] args);
public delegate void CustomResourceEventHanlder(object issuer, Session[] receivers, params object[] args);
// public delegate void CustomReceiversEventHanlder(string[] usernames, DistributedConnection[] connections, params object[] args);
}

View File

@ -1,52 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Resource
{
[AttributeUsage(AttributeTargets.Method)]
public class ResourceFunction : System.Attribute
{
private string expansion = null;
public string Expansion
{
get
{
return expansion;
}
}
public ResourceFunction(string expansion = null)
{
this.expansion = expansion;
}
}
}

View File

@ -1,77 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using Esiur.Resource.Template;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Resource
{
[AttributeUsage(AttributeTargets.Property)]
public class ResourceProperty : System.Attribute
{
bool serialize;
string readExpansion;
string writeExpansion;
// bool recordable;
//bool storable;
//public bool Recordable => recordable;
//public bool Storable => storable;
StorageMode storage;
public StorageMode Storage => storage;
public bool Serialize => serialize;
public string ReadExpansion
{
get
{
return readExpansion;
}
}
public string WriteExpansion
{
get
{
return writeExpansion;
}
}
public ResourceProperty(StorageMode storage = StorageMode.NonVolatile, bool serialize = true, string readExpansion = null, string writeExpansion = null)
{
this.readExpansion = readExpansion;
this.writeExpansion = writeExpansion;
this.storage = storage;
this.serialize = serialize;
}
}
}

View File

@ -1,28 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
namespace Esiur.Resource
{
public class ResourceQuery : IQueryable<IResource>
{
public Type ElementType => throw new NotImplementedException();
public Expression Expression => throw new NotImplementedException();
public IQueryProvider Provider => throw new NotImplementedException();
public IEnumerator<IResource> GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
}

View File

@ -1,43 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Resource
{
public enum ResourceTrigger : int
{
Open = 0,
Initialize,
Terminate,
Configure,
SystemInitialized,
SystemTerminated,
SystemReload,
}
}

View File

@ -1,72 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using Esiur.Data;
using Esiur.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Resource
{
[AttributeUsage(AttributeTargets.All)]
public class Storable : global::System.Attribute
{
public delegate object SerializerFunction(object value);
public delegate object DeserializerFunction(object data);
SerializerFunction serializer;
DeserializerFunction deserializer;
DataType type;
public Storable()
{
type = DataType.Void;
}
public DeserializerFunction Deserializer
{
get { return deserializer; }
}
public SerializerFunction Serializer
{
get { return serializer; }
}
public Storable(DataType type)
{
this.type = type;
}
public Storable(DataType type, SerializerFunction serializer, DeserializerFunction deserializer)
{
this.type = type;
this.serializer = serializer;
this.deserializer = deserializer;
}
}
}

View File

@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Resource
{
public enum StorageMode : byte
{
NonVolatile,
Volatile,
Recordable
}
}

View File

@ -1,48 +0,0 @@
using Esiur.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Resource.Template
{
public class EventTemplate : MemberTemplate
{
public string Expansion
{
get;
set;
}
public override byte[] Compose()
{
var name = base.Compose();
if (Expansion != null)
{
var exp = DC.ToBytes(Expansion);
return new BinaryList()
.AddUInt8(0x50)
.AddInt32(exp.Length)
.AddUInt8Array(exp)
.AddUInt8((byte)name.Length)
.AddUInt8Array(name)
.ToArray();
}
else
return new BinaryList()
.AddUInt8(0x40)
.AddUInt8((byte)name.Length)
.AddUInt8Array(name)
.ToArray();
}
public EventTemplate(ResourceTemplate template, byte index, string name, string expansion)
:base(template, MemberType.Property, index, name)
{
this.Expansion = expansion;
}
}
}

View File

@ -1,55 +0,0 @@
using Esiur.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Resource.Template
{
public class FunctionTemplate : MemberTemplate
{
public string Expansion
{
get;
set;
}
public bool IsVoid
{
get;
set;
}
public override byte[] Compose()
{
var name = base.Compose();
if (Expansion != null)
{
var exp = DC.ToBytes(Expansion);
return new BinaryList().AddUInt8((byte)(0x10 | (IsVoid ? 0x8 : 0x0)))
.AddUInt8((byte)name.Length)
.AddUInt8Array(name)
.AddInt32(exp.Length)
.AddUInt8Array(exp)
.ToArray();
}
else
return new BinaryList().AddUInt8((byte)(IsVoid ? 0x8 : 0x0))
.AddUInt8((byte)name.Length)
.AddUInt8Array(name)
.ToArray();
}
public FunctionTemplate(ResourceTemplate template, byte index, string name,bool isVoid, string expansion)
:base(template, MemberType.Property, index, name)
{
this.IsVoid = isVoid;
this.Expansion = expansion;
}
}
}

View File

@ -1,46 +0,0 @@
using Esiur.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Resource.Template
{
public class MemberTemplate
{
public enum MemberType
{
Function = 0,
Property = 1,
Event = 2,
}
public byte Index => index;
public string Name => name;
public MemberType Type => type;
ResourceTemplate template;
string name;
MemberType type;
byte index;
public ResourceTemplate Template => template;
public MemberTemplate(ResourceTemplate template, MemberType type, byte index, string name)
{
this.template = template;
this.type = type;
this.index = index;
this.name = name;
}
public string Fullname => template.ClassName + "." + Name;
public virtual byte[] Compose()
{
return DC.ToBytes(Name);
}
}
}

View File

@ -1,129 +0,0 @@
using Esiur.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Resource.Template
{
public class PropertyTemplate : MemberTemplate
{
public enum PropertyPermission:byte
{
Read = 1,
Write,
ReadWrite
}
public PropertyInfo Info
{
get;
set;
}
public bool Serilize
{
get;set;
}
//bool ReadOnly;
//IIPTypes::DataType ReturnType;
public PropertyPermission Permission {
get;
set;
}
/*
public bool Recordable
{
get;
set;
}*/
public StorageMode Storage
{
get;
set;
}
public string ReadExpansion
{
get;
set;
}
public string WriteExpansion
{
get;
set;
}
/*
public bool Storable
{
get;
set;
}*/
public override byte[] Compose()
{
var name = base.Compose();
var pv = ((byte)(Permission) << 1) | (Storage == StorageMode.Recordable ? 1 : 0);
if (WriteExpansion != null && ReadExpansion != null)
{
var rexp = DC.ToBytes(ReadExpansion);
var wexp = DC.ToBytes(WriteExpansion);
return new BinaryList()
.AddUInt8((byte)(0x38 | pv))
.AddUInt8((byte)name.Length)
.AddUInt8Array(name)
.AddInt32(wexp.Length)
.AddUInt8Array(wexp)
.AddInt32(rexp.Length)
.AddUInt8Array(rexp)
.ToArray();
}
else if (WriteExpansion != null)
{
var wexp = DC.ToBytes(WriteExpansion);
return new BinaryList()
.AddUInt8((byte)(0x30 | pv))
.AddUInt8((byte)name.Length)
.AddUInt8Array(name)
.AddInt32(wexp.Length)
.AddUInt8Array(wexp)
.ToArray();
}
else if (ReadExpansion != null)
{
var rexp = DC.ToBytes(ReadExpansion);
return new BinaryList()
.AddUInt8((byte)(0x28 | pv))
.AddUInt8((byte)name.Length)
.AddUInt8Array(name)
.AddInt32(rexp.Length)
.AddUInt8Array(rexp)
.ToArray();
}
else
return new BinaryList()
.AddUInt8((byte)(0x20 | pv))
.AddUInt8((byte)name.Length)
.AddUInt8Array(name)
.ToArray();
}
public PropertyTemplate(ResourceTemplate template, byte index, string name, string read, string write, StorageMode storage)
:base(template, MemberType.Property, index, name)
{
//this.Recordable = recordable;
this.Storage = storage;
this.ReadExpansion = read;
this.WriteExpansion = write;
}
}
}

View File

@ -1,365 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Esiur.Misc;
using Esiur.Data;
using Esiur.Core;
using System.Security.Cryptography;
using Esiur.Proxy;
namespace Esiur.Resource.Template
{
public class ResourceTemplate
{
Guid classId;
string className;
List<MemberTemplate> members = new List<MemberTemplate>();
List<FunctionTemplate> functions = new List<FunctionTemplate>();
List<EventTemplate> events = new List<EventTemplate>();
List<PropertyTemplate> properties = new List<PropertyTemplate>();
int version;
//bool isReady;
byte[] content;
public byte[] Content
{
get { return content; }
}
public MemberTemplate GetMemberTemplate(MemberInfo member)
{
if (member is MethodInfo)
return GetFunctionTemplateByName(member.Name);
else if (member is EventInfo)
return GetEventTemplateByName(member.Name);
else if (member is PropertyInfo)
return GetPropertyTemplateByName(member.Name);
else
return null;
}
public EventTemplate GetEventTemplateByName(string eventName)
{
foreach (var i in events)
if (i.Name == eventName)
return i;
return null;
}
public EventTemplate GetEventTemplateByIndex(byte index)
{
foreach (var i in events)
if (i.Index == index)
return i;
return null;
}
public FunctionTemplate GetFunctionTemplateByName(string functionName)
{
foreach (var i in functions)
if (i.Name == functionName)
return i;
return null;
}
public FunctionTemplate GetFunctionTemplateByIndex(byte index)
{
foreach (var i in functions)
if (i.Index == index)
return i;
return null;
}
public PropertyTemplate GetPropertyTemplateByIndex(byte index)
{
foreach (var i in properties)
if (i.Index == index)
return i;
return null;
}
public PropertyTemplate GetPropertyTemplateByName(string propertyName)
{
foreach (var i in properties)
if (i.Name == propertyName)
return i;
return null;
}
public Guid ClassId
{
get { return classId; }
}
public string ClassName
{
get { return className; }
}
public MemberTemplate[] Methods
{
get{return members.ToArray();}
}
public FunctionTemplate[] Functions
{
get { return functions.ToArray(); }
}
public EventTemplate[] Events
{
get { return events.ToArray(); }
}
public PropertyTemplate[] Properties
{
get { return properties.ToArray(); }
}
public ResourceTemplate()
{
}
public ResourceTemplate(Type type)
{
type = ResourceProxy.GetBaseType(type);
// set guid
var typeName = Encoding.UTF8.GetBytes(type.FullName);
var hash = SHA256.Create().ComputeHash(typeName).Clip(0, 16);
classId = new Guid(hash);
className = type.FullName;
#if NETSTANDARD
PropertyInfo[] propsInfo = type.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
EventInfo[] eventsInfo = type.GetTypeInfo().GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
MethodInfo[] methodsInfo = type.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
#else
PropertyInfo[] propsInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
EventInfo[] eventsInfo = type.GetEvents(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
#endif
//byte currentIndex = 0;
byte i = 0;
foreach (var pi in propsInfo)
{
var ps = (ResourceProperty[])pi.GetCustomAttributes(typeof(ResourceProperty), true);
if (ps.Length > 0)
{
var pt = new PropertyTemplate(this, i++, pi.Name, ps[0].ReadExpansion, ps[0].WriteExpansion, ps[0].Storage);
pt.Info = pi;
pt.Serilize = ps[0].Serialize;
properties.Add(pt);
}
}
i = 0;
foreach (var ei in eventsInfo)
{
var es = (ResourceEvent[])ei.GetCustomAttributes(typeof(ResourceEvent), true);
if (es.Length > 0)
{
var et = new EventTemplate(this, i++, ei.Name, es[0].Expansion);
events.Add(et);
}
}
i = 0;
foreach (MethodInfo mi in methodsInfo)
{
var fs = (ResourceFunction[])mi.GetCustomAttributes(typeof(ResourceFunction), true);
if (fs.Length > 0)
{
var ft = new FunctionTemplate(this, i++, mi.Name, mi.ReturnType == typeof(void), fs[0].Expansion);
functions.Add(ft);
}
}
// append signals
for (i = 0; i < events.Count; i++)
members.Add(events[i]);
// append slots
for (i = 0; i < functions.Count; i++)
members.Add(functions[i]);
// append properties
for (i = 0; i < properties.Count; i++)
members.Add(properties[i]);
// bake it binarily
var b = new BinaryList();
b.AddGuid(classId)
.AddUInt8((byte)className.Length)
.AddString(className)
.AddInt32(version)
.AddUInt16((ushort)members.Count);
foreach (var ft in functions)
b.AddUInt8Array(ft.Compose());
foreach (var pt in properties)
b.AddUInt8Array(pt.Compose());
foreach (var et in events)
b.AddUInt8Array(et.Compose());
content = b.ToArray();
}
public static ResourceTemplate Parse(byte[] data)
{
return Parse(data, 0, (uint)data.Length);
}
public static ResourceTemplate Parse(byte[] data, uint offset, uint contentLength)
{
uint ends = offset + contentLength;
uint oOffset = offset;
// start parsing...
var od = new ResourceTemplate();
od.content = data.Clip(offset, contentLength);
od.classId = data.GetGuid(offset);
offset += 16;
od.className = data.GetString(offset + 1, data[offset]);
offset += (uint)data[offset] + 1;
od.version = data.GetInt32(offset);
offset += 4;
ushort methodsCount = data.GetUInt16(offset);
offset += 2;
byte functionIndex = 0;
byte propertyIndex = 0;
byte eventIndex = 0;
for (int i = 0; i < methodsCount; i++)
{
var type = data[offset] >> 5;
if (type == 0) // function
{
string expansion = null;
var hasExpansion = ((data[offset] & 0x10) == 0x10);
var isVoid = ((data[offset++] & 0x08) == 0x08);
var name = data.GetString(offset + 1, data[offset]);
offset += (uint)data[offset] + 1;
if (hasExpansion) // expansion ?
{
var cs = data.GetUInt32(offset);
offset += 4;
expansion = data.GetString(offset, cs);
offset += cs;
}
var ft = new FunctionTemplate(od, functionIndex++, name, isVoid, expansion);
od.functions.Add(ft);
}
else if (type == 1) // property
{
string readExpansion = null, writeExpansion = null;
var hasReadExpansion = ((data[offset] & 0x8) == 0x8);
var hasWriteExpansion = ((data[offset] & 0x10) == 0x10);
var recordable = ((data[offset] & 1) == 1);
var permission = (PropertyTemplate.PropertyPermission)((data[offset++] >> 1) & 0x3);
var name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]);
offset += (uint)data[offset] + 1;
if (hasReadExpansion) // expansion ?
{
var cs = data.GetUInt32(offset);
offset += 4;
readExpansion = data.GetString(offset, cs);
offset += cs;
}
if (hasWriteExpansion) // expansion ?
{
var cs = data.GetUInt32(offset);
offset += 4;
writeExpansion = data.GetString(offset, cs);
offset += cs;
}
var pt = new PropertyTemplate(od, propertyIndex++, name, readExpansion, writeExpansion, recordable ? StorageMode.Recordable : StorageMode.Volatile);
od.properties.Add(pt);
}
else if (type == 2) // Event
{
string expansion = null;
var hasExpansion = ((data[offset++] & 0x10) == 0x10);
var name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, (int)data[offset]);
offset += (uint)data[offset] + 1;
if (hasExpansion) // expansion ?
{
var cs = data.GetUInt32(offset);
offset += 4;
expansion = data.GetString(offset, cs);
offset += cs;
}
var et = new EventTemplate(od, eventIndex++, name, expansion);
od.events.Add(et);
}
}
// append signals
for (int i = 0; i < od.events.Count; i++)
od.members.Add(od.events[i]);
// append slots
for (int i = 0; i < od.functions.Count; i++)
od.members.Add(od.functions[i]);
// append properties
for (int i = 0; i < od.properties.Count; i++)
od.members.Add(od.properties[i]);
//od.isReady = true;
/*
var oo = owner.Socket.Engine.GetObjectDescription(od.GUID);
if (oo != null)
{
Console.WriteLine("Already there ! description");
return oo;
}
else
{
owner.Socket.Engine.AddObjectDescription(od);
return od;
}
*/
return od;
}
}
}

View File

@ -1,548 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using Esiur.Data;
using Esiur.Core;
using Esiur.Proxy;
using Esiur.Resource.Template;
using Esiur.Security.Permissions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Esiur.Net.IIP;
using System.Text.RegularExpressions;
namespace Esiur.Resource
{
// Centeral Resource Issuer
public static class Warehouse
{
//static byte prefixCounter;
static AutoList<IStore, Instance> stores = new AutoList<IStore, Instance>(null);
static Dictionary<uint, WeakReference<IResource>> resources = new Dictionary<uint, WeakReference<IResource>>();
static uint resourceCounter = 0;
static KeyList<Guid, ResourceTemplate> templates = new KeyList<Guid, ResourceTemplate>();
static bool warehouseIsOpen = false;
public delegate void StoreConnectedEvent(IStore store, string name);
public delegate void StoreDisconnectedEvent(IStore store);
public static event StoreConnectedEvent StoreConnected;
public static event StoreDisconnectedEvent StoreDisconnected;
public static KeyList<string, Func<IStore>> Protocols { get; } = getSupportedProtocols();
static KeyList<string, Func<IStore>> getSupportedProtocols()
{
var rt = new KeyList<string, Func<IStore>>();
rt.Add("iip", () => new DistributedConnection());
return rt;
}
/// <summary>
/// Get a store by its name.
/// </summary>
/// <param name="name">Store instance name</param>
/// <returns></returns>
public static IStore GetStore(string name)
{
foreach (var s in stores)
if (s.Instance.Name == name)
return s as IStore;
return null;
}
/// <summary>
/// Get a resource by instance Id.
/// </summary>
/// <param name="id">Instance Id</param>
/// <returns></returns>
public static AsyncReply<IResource> GetById(uint id)
{
if (resources.ContainsKey(id))
{
IResource r;
if (resources[id].TryGetTarget(out r))
return new AsyncReply<IResource>(r);
else
return new AsyncReply<IResource>(null);
}
else
return new AsyncReply<IResource>(null);
}
/// <summary>
/// Open the warehouse.
/// This function issues the initialize trigger to all stores and resources.
/// </summary>
/// <returns>True, if no problem occurred.</returns>
public static AsyncReply<bool> Open()
{
var bag = new AsyncBag<bool>();
foreach (var store in stores)
bag.Add(store.Trigger(ResourceTrigger.Initialize));
bag.Seal();
var rt = new AsyncReply<bool>();
bag.Then((x) =>
{
foreach (var b in x)
if (!b)
{
rt.Trigger(false);
return;
}
var rBag = new AsyncBag<bool>();
foreach (var rk in resources)
{
IResource r;
if (rk.Value.TryGetTarget(out r))
rBag.Add(r.Trigger(ResourceTrigger.SystemInitialized));
}
rBag.Seal();
rBag.Then(y =>
{
foreach (var b in y)
if (!b)
{
rt.Trigger(false);
return;
}
rt.Trigger(true);
warehouseIsOpen = true;
});
});
return rt;
}
/// <summary>
/// Close the warehouse.
/// This function issues terminate trigger to all resources and stores.
/// </summary>
/// <returns>True, if no problem occurred.</returns>
public static AsyncReply<bool> Close()
{
var bag = new AsyncBag<bool>();
foreach (var resource in resources.Values)
{
IResource r;
if (resource.TryGetTarget(out r))
{
if (!(r is IStore))
bag.Add(r.Trigger(ResourceTrigger.Terminate));
}
}
foreach (var store in stores)
bag.Add(store.Trigger(ResourceTrigger.Terminate));
foreach (var resource in resources.Values)
{
IResource r;
if (resource.TryGetTarget(out r))
{
if (!(r is IStore))
bag.Add(r.Trigger(ResourceTrigger.SystemTerminated));
}
}
foreach (var store in stores)
bag.Add(store.Trigger(ResourceTrigger.SystemTerminated));
bag.Seal();
var rt = new AsyncReply<bool>();
bag.Then((x) =>
{
foreach (var b in x)
if (!b)
{
rt.Trigger(false);
return;
}
rt.Trigger(true);
});
return rt;
}
/*
private static IResource[] QureyIn(string[] path, int index, IEnumerable<IResource> resources)// AutoList<IResource, Instance> resources)
{
var rt = new List<IResource>();
if (index == path.Length - 1)
{
if (path[index] == "")
foreach (IResource child in resources)
rt.Add(child);
else
foreach (IResource child in resources)
if (child.Instance.Name == path[index])
rt.Add(child);
}
else
foreach (IResource child in resources)
if (child.Instance.Name == path[index])
rt.AddRange(QureyIn(path, index+1, child.Instance.Children<IResource>()));
return rt.ToArray();
}
public static AsyncReply<IResource[]> Query(string path)
{
if (path == null || path == "")
{
var roots = stores.Where(s => s.Instance.Parents<IResource>().Count() == 0).ToArray();
return new AsyncReply<IResource[]>(roots);
}
else
{
var rt = new AsyncReply<IResource[]>();
Get(path).Then(x =>
{
var p = path.Split('/');
if (x == null)
{
rt.Trigger(QureyIn(p, 0, stores));
}
else
{
var ar = QureyIn(p, 0, stores).Where(r => r != x).ToList();
ar.Insert(0, x);
rt.Trigger(ar.ToArray());
}
});
return rt;
}
}
*/
public static async Task<IResource[]> Query(string path)
{
var rt = new AsyncReply<IResource[]>();
var p = path.Trim().Split('/');
IResource resource;
foreach (var store in stores)
if (p[0] == store.Instance.Name)
{
if (p.Length == 1)
return new IResource[] { store };
var res = await store.Get(String.Join("/", p.Skip(1).ToArray()));
if (res != null)
return new IResource[] { res };
resource = store;
for (var i = 1; i < p.Length; i++)
{
var children = await resource.Instance.Children<IResource>(p[i]);
if (children.Length > 0)
{
if (i == p.Length - 1)
return children;
else
resource = children[0];
}
else
break;
}
return null;
}
return null;
}
/// <summary>
/// Get a resource by its path.
/// Resource path is sperated by '/' character, e.g. "system/http".
/// </summary>
/// <param name="path"></param>
/// <returns>Resource instance.</returns>
public static AsyncReply<IResource> Get(string path, object attributes = null, IResource parent = null, IPermissionsManager manager = null)
{
var rt = new AsyncReply<IResource>();
// Should we create a new store ?
if (path.Contains("://"))
{
var url = path.Split(new string[] { "://" }, 2, StringSplitOptions.None);
var hostname = url[1].Split(new char[] { '/' }, 2)[0];
var pathname = string.Join("/", url[1].Split(new char[] { '/' }).Skip(1));
if (Protocols.ContainsKey(url[0]))
{
var handler = Protocols[url[0]];
var store = handler();
Put(store, hostname, null, parent, null, 0, manager, attributes);
store.Trigger(ResourceTrigger.Open).Then(x => {
warehouseIsOpen = true;
if (pathname.Length > 0 && pathname != "")
store.Get(pathname).Then(r => {
rt.Trigger(r);
}).Error(e => rt.TriggerError(e));
else
rt.Trigger(store);
}).Error(e => {
rt.TriggerError(e);
Warehouse.Remove(store);
});
return rt;
}
}
Query(path).ContinueWith(rs =>
{
// rt.TriggerError(new Exception());
if (rs.Result != null && rs.Result.Length > 0)
rt.Trigger(rs.Result[0]);
else
rt.Trigger(null);
});
return rt;
}
/// <summary>
/// Put a resource in the warehouse.
/// </summary>
/// <param name="resource">Resource instance.</param>
/// <param name="name">Resource name.</param>
/// <param name="store">IStore that manages the resource. Can be null if the resource is a store.</param>
/// <param name="parent">Parent resource. if not presented the store becomes the parent for the resource.</param>
public static void Put(IResource resource, string name, IStore store = null, IResource parent = null, ResourceTemplate customTemplate = null, ulong age = 0, IPermissionsManager manager = null, object attributes = null)
{
if (store == null)
{
// assign parent as a store
if (parent is IStore)
store = (IStore)parent;
// assign parent's store as a store
else if (parent != null)
store = parent.Instance.Store;
// assign self as a store (root store)
else if (resource is IStore)
{
store = (IStore)resource;
stores.Add(resource as IStore);
}
else
throw new Exception("Can't find a store for the resource.");
}
resource.Instance = new Instance(resourceCounter++, name, resource, store, customTemplate, age);
if (attributes != null)
resource.Instance.SetAttributes(Structure.FromObject(attributes));
if (manager != null)
resource.Instance.Managers.Add(manager);
if (store == parent)
parent = null;
/*
if (parent == null)
{
if (!(resource is IStore))
store.Instance.Children.Add(resource);
}
else
parent.Instance.Children.Add(resource);
*/
if (resource is IStore)
StoreConnected?.Invoke(resource as IStore, name);
//else
store.Put(resource);
if (parent != null)
{
parent.Instance.Store.AddChild(parent, resource);
store.AddParent(resource, parent);
//store.AddChild(parent, resource);
}
resources.Add(resource.Instance.Id, new WeakReference<IResource>(resource));
if (warehouseIsOpen)
resource.Trigger(ResourceTrigger.Initialize);
}
public static T New<T>(string name, IStore store = null, IResource parent = null, IPermissionsManager manager = null, Structure attributes = null)
where T:IResource
{
var type = ResourceProxy.GetProxy<T>();
var res = Activator.CreateInstance(type) as IResource;
Put(res, name, store, parent, null, 0, manager, attributes);
return (T)res;
}
/// <summary>
/// Put a resource template in the templates warehouse.
/// </summary>
/// <param name="template">Resource template.</param>
public static void PutTemplate(ResourceTemplate template)
{
if (!templates.ContainsKey(template.ClassId))
templates.Add(template.ClassId, template);
}
/// <summary>
/// Get a template by type from the templates warehouse. If not in the warehouse, a new ResourceTemplate is created and added to the warehouse.
/// </summary>
/// <param name="type">.Net type.</param>
/// <returns>Resource template.</returns>
public static ResourceTemplate GetTemplate(Type type)
{
// loaded ?
foreach (var t in templates.Values)
if (t.ClassName == type.FullName)
return t;
var template = new ResourceTemplate(type);
templates.Add(template.ClassId, template);
return template;
}
/// <summary>
/// Get a template by class Id from the templates warehouse. If not in the warehouse, a new ResourceTemplate is created and added to the warehouse.
/// </summary>
/// <param name="classId">Class Id.</param>
/// <returns>Resource template.</returns>
public static AsyncReply<ResourceTemplate> GetTemplate(Guid classId)
{
if (templates.ContainsKey(classId))
return new AsyncReply<ResourceTemplate>(templates[classId]);
return null;
}
/// <summary>
/// Get a template by class name from the templates warehouse. If not in the warehouse, a new ResourceTemplate is created and added to the warehouse.
/// </summary>
/// <param name="className">Class name.</param>
/// <returns>Resource template.</returns>
public static AsyncReply<ResourceTemplate> GetTemplate(string className)
{
foreach (var t in templates.Values)
if (t.ClassName == className)
return new AsyncReply<ResourceTemplate>(t);
return null;
}
public static bool Remove(IResource resource)
{
if (resource.Instance == null)
return false;
if (resources.ContainsKey(resource.Instance.Id))
resources.Remove(resource.Instance.Id);
else
return false;
if (resource is IStore)
{
stores.Remove(resource as IStore);
// remove all objects associated with the store
var toBeRemoved = resources.Values.Where(x => {
IResource r;
return x.TryGetTarget(out r) && r.Instance.Store == resource;
}).ToArray();
foreach (var o in toBeRemoved)
{
IResource r;
if (o.TryGetTarget(out r))
Remove(r);
}
StoreDisconnected?.Invoke(resource as IStore);
}
if (resource.Instance.Store != null)
resource.Instance.Store.Remove(resource);
resource.Destroy();
return true;
}
}
}

View File

@ -1,41 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Authority
{
public class AlienAuthentication : Authentication
{
public AlienAuthentication() :
base(AuthenticationType.Alien)
{
}
}
}

View File

@ -1,62 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Authority
{
public class Authentication
{
AuthenticationType type;
public string Username { get; set; }
public Certificate Certificate { get; set; }
public string Domain { get; set; }
public string FullName => Username + "@" + Domain;
public Source Source { get; } = new Source();
public AuthenticationState State
{
get;
set;
}
public AuthenticationType Type
{
get => type;
}
public Authentication(AuthenticationType type)
{
this.type = type;
}
}
}

View File

@ -1,42 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Authority
{
public enum AuthenticationState : int
{
Denied = 0x1,
Succeeded = 0x2,
Blocked = 0x4,
Rejected = 0x8,
NeedsUpdate = 0x10,
NotFound = 0x20
}
}

View File

@ -1,40 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Authority
{
public enum AuthenticationType
{
Host,
CoHost,
Client,
Alien
}
}

View File

@ -1,202 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using Esiur.Data;
using Esiur.Core;
using Esiur.Misc;
using Esiur.Security.Cryptography;
using Esiur.Security.Integrity;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Authority
{
public class CACertificate : Certificate
{
string name;
public string Name
{
get { return name; }
}
public CACertificate(byte[] data, uint offset, uint length, bool privateKeyIncluded = false)
:base(0, DateTime.MinValue, DateTime.MinValue, HashFunctionType.MD5)
{
uint oOffset = offset;
this.id = DC.GetUInt64(data, offset);
offset += 8;
this.issueDate = DC.GetDateTime(data, offset);
offset += 8;
this.expireDate = DC.GetDateTime(data, offset);
offset += 8;
this.hashFunction = (HashFunctionType)(data[offset++] >> 4);
this.name = (Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]));
offset += (uint)data[offset] + 1;
var aea = (AsymetricEncryptionAlgorithmType)(data[offset] >> 5);
if (aea == AsymetricEncryptionAlgorithmType.RSA)
{
var key = new RSAParameters();
uint exponentLength = (uint)data[offset++] & 0x1F;
key.Exponent = DC.Clip(data, offset, exponentLength);
offset += exponentLength;
uint keySize = DC.GetUInt16(data, offset);
offset += 2;
key.Modulus = DC.Clip(data, offset, keySize);
offset += keySize;
// copy cert data
this.publicRawData = new byte[offset - oOffset];
Buffer.BlockCopy(data, (int)oOffset, publicRawData, 0, publicRawData.Length);
if (privateKeyIncluded)
{
uint privateKeyLength = (keySize * 3) + (keySize / 2);
uint halfKeySize = keySize / 2;
privateRawData = DC.Clip(data, offset, privateKeyLength);
key.D = DC.Clip(data, offset, keySize);
offset += keySize;
key.DP = DC.Clip(data, offset, halfKeySize);
offset += halfKeySize;
key.DQ = DC.Clip(data, offset, halfKeySize);
offset += halfKeySize;
key.InverseQ = DC.Clip(data, offset, halfKeySize);
offset += halfKeySize;
key.P = DC.Clip(data, offset, halfKeySize);
offset += halfKeySize;
key.Q = DC.Clip(data, offset, halfKeySize);
offset += halfKeySize;
}
// setup rsa
this.rsa = RSA.Create();// new RSACryptoServiceProvider();
this.rsa.ImportParameters(key);
}
}
public CACertificate(ulong id, string authorityName, DateTime issueDate, DateTime expireDate,
HashFunctionType hashFunction = HashFunctionType.SHA1, uint ip = 0, byte[] ip6 = null)
: base(id, issueDate, expireDate, hashFunction)
{
// assign type
BinaryList cr = new BinaryList();
// make header
cr.AddUInt64(id)
.AddDateTime(issueDate)
.AddDateTime(expireDate);
// hash function
cr.AddUInt8((byte)((byte)hashFunction << 4));
this.hashFunction = hashFunction;
// CA Name
this.name = authorityName;
cr.AddUInt8((byte)(authorityName.Length))
.AddUInt8Array(Encoding.ASCII.GetBytes(authorityName));
// public key
rsa = RSA.Create();// new RSACryptoServiceProvider(2048);
rsa.KeySize = 2048;
RSAParameters dRSAKey = rsa.ExportParameters(true);
cr.AddUInt8((byte)dRSAKey.Exponent.Length)
.AddUInt8Array(dRSAKey.Exponent)
.AddUInt16((ushort)dRSAKey.Modulus.Length)
.AddUInt8Array(dRSAKey.Modulus);
publicRawData = cr.ToArray();
privateRawData = DC.Merge(dRSAKey.D, dRSAKey.DP, dRSAKey.DQ, dRSAKey.InverseQ, dRSAKey.P, dRSAKey.Q);
}
public override bool Save(string filename, bool includePrivate = false)
{
try
{
if (includePrivate)
File.WriteAllBytes(filename, new BinaryList()
.AddUInt8((byte)CertificateType.CAPrivate)
.AddUInt8Array(publicRawData)
.AddUInt8Array(privateRawData)
.ToArray());
else
File.WriteAllBytes(filename, new BinaryList()
.AddUInt8((byte)CertificateType.CAPublic)
.AddUInt8Array(publicRawData).ToArray());
return true;
}
catch
{
return false;
}
}
public override byte[] Serialize(bool includePrivate = false)
{
if (includePrivate)
return new BinaryList()
.AddUInt8Array(publicRawData)
.AddUInt8Array(privateRawData)
.ToArray();
else
return publicRawData;
}
}
}

View File

@ -1,222 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using Esiur.Data;
using Esiur.Core;
using Esiur.Misc;
using Esiur.Security.Cryptography;
using Esiur.Security.Integrity;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Authority
{
public abstract class Certificate
{
protected DateTime issueDate, expireDate;
protected RSA rsa;
protected Aes aes;
protected byte[] publicRawData;
protected byte[] privateRawData;
protected ulong id;
protected HashFunctionType hashFunction;
public Certificate(ulong id, DateTime issueDate, DateTime expireDate, HashFunctionType hashFunction)
{
this.id = id;
this.issueDate = issueDate;
this.expireDate = expireDate;
this.hashFunction = hashFunction;
}
public ulong Id
{
get { return id; }
}
public AsymetricEncryptionAlgorithmType AsymetricEncryptionAlgorithm
{
get { return AsymetricEncryptionAlgorithmType.RSA; }
}
public byte[] AsymetricEncrypt(byte[] message)
{
return rsa.Encrypt(message, RSAEncryptionPadding.OaepSHA512);
}
public byte[] AsymetricEncrypt(byte[] message, uint offset, uint length)
{
if (message.Length != length)
return rsa.Encrypt(DC.Clip(message, offset, length), RSAEncryptionPadding.OaepSHA512);
else
return rsa.Encrypt(message, RSAEncryptionPadding.OaepSHA512);
}
public byte[] AsymetricDecrypt(byte[] message)
{
try
{
return rsa.Decrypt(message, RSAEncryptionPadding.OaepSHA512);
}
catch (Exception ex)
{
Global.Log("Certificate", LogType.Error, ex.ToString());
return null;
}
}
public byte[] AsymetricDecrypt(byte[] message, uint offset, uint length)
{
try
{
if (message.Length != length)
return rsa.Decrypt(DC.Clip(message, offset, length), RSAEncryptionPadding.OaepSHA512);
else
return rsa.Decrypt(message, RSAEncryptionPadding.OaepSHA512);
}
catch (Exception ex)
{
Global.Log("Certificate", LogType.Error, ex.ToString());
return null;
}
}
public byte[] SymetricEncrypt(byte[] message, uint offset, uint length)
{
byte[] rt = null;
using (var ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
cs.Write(message, (int)offset, (int)length);
rt = ms.ToArray();
}
return rt;
}
public byte[] SymetricEncrypt(byte[] message)
{
return SymetricEncrypt(message, 0, (uint)message.Length);
}
public byte[] SymetricDecrypt(byte[] message, uint offset, uint length)
{
byte[] rt = null;
using (var ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
cs.Write(message, (int)offset, (int)length);
rt = ms.ToArray();
}
return rt;
}
public byte[] SymetricDecrypt(byte[] message)
{
return SymetricDecrypt(message, 0, (uint)message.Length);
}
public byte[] Sign(byte[] message)
{
return Sign(message, 0, (uint)message.Length);
}
public byte[] Sign(byte[] message, uint offset, uint length)
{
if (hashFunction == HashFunctionType.SHA1)
return rsa.SignData(message, (int)offset, (int)length, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
else if (hashFunction == HashFunctionType.MD5)
return rsa.SignData(message, (int)offset, (int)length, HashAlgorithmName.MD5, RSASignaturePadding.Pkcs1);
else if (hashFunction == HashFunctionType.SHA256)
return rsa.SignData(message, (int)offset, (int)length, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
else if (hashFunction == HashFunctionType.SHA384)
return rsa.SignData(message, (int)offset, (int)length, HashAlgorithmName.SHA384, RSASignaturePadding.Pkcs1);
else if (hashFunction == HashFunctionType.SHA512)
return rsa.SignData(message, (int)offset, (int)length, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
return null;
}
public bool InitializeSymetricCipher(SymetricEncryptionAlgorithmType algorithm, int keyLength, byte[] key, byte[] iv)
{
if (algorithm == SymetricEncryptionAlgorithmType.AES)
{
if (keyLength == 0) // 128 bit
{
aes = Aes.Create();
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.Key = key;
aes.IV = iv;
return true;
}
}
return false;
}
public abstract bool Save(string filename, bool includePrivate = false);
public abstract byte[] Serialize(bool includePrivate = false);
public static Certificate Load(string filename)
{
byte[] ar = File.ReadAllBytes(filename);
var t = (CertificateType)ar[0];
switch (t)
{
case CertificateType.CAPublic:
return new CACertificate(ar, 1, (uint)ar.Length - 1);
case CertificateType.CAPrivate:
return new CACertificate(ar, 1, (uint)ar.Length - 1, true);
case CertificateType.DomainPublic:
return new DomainCertificate(ar, 1, (uint)ar.Length - 1);
case CertificateType.DomainPrivate:
return new DomainCertificate(ar, 1, (uint)ar.Length - 1, true);
case CertificateType.UserPublic:
return new UserCertificate(ar, 1, (uint)ar.Length - 1);
case CertificateType.UserPrivate:
return new UserCertificate(ar, 1, (uint)ar.Length - 1, true);
}
return null;
}
}
}

View File

@ -1,42 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Authority
{
public enum CertificateType
{
CAPublic = 0,
CAPrivate,
DomainPublic,
DomainPrivate,
UserPublic,
UserPrivate
}
}

View File

@ -1,72 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Authority
{
public class ClientAuthentication : Authentication
{
/*
string username;
byte[] password;
string domain;
byte[] token;
UserCertificate certificate;
public string Username => username;
public byte[] Password => password;
//public string Domain => domain;
public byte[] Token => token;
public byte[] Nounce { get; set; }
*/
public ClientAuthentication()
:base(AuthenticationType.Client)
{
}
/*
public ClientAuthentication(byte[] token)
: base(AuthenticationType.Client)
{
this.token = token;
}
public ClientAuthentication(string username, byte[] password)
: base(AuthenticationType.Client)
{
this.username = username;
this.password = password;
//this.domain = domain;
}
*/
}
}

View File

@ -1,41 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Authority
{
public class CoHostAuthentication : Authentication
{
public CoHostAuthentication()
: base(AuthenticationType.CoHost)
{
}
}
}

View File

@ -1,250 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using Esiur.Data;
using Esiur.Misc;
using Esiur.Security.Cryptography;
using Esiur.Security.Integrity;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Authority
{
public class DomainCertificate : Certificate
{
uint ip;
byte[] ip6;
string domain;
//CACertificate ca;
string caName;
ulong caId;
byte[] signature;
string authorityName;
public string AuthorityName
{
get { return authorityName; }
}
public string Domain
{
get { return domain; }
}
public byte[] Signature
{
get { return signature; }
}
public uint IPAddress
{
get { return ip; }
}
public byte[] IPv6Address
{
get { return ip6; }
}
public DomainCertificate(byte[] data, uint offset, uint length, bool privateKeyIncluded = false)
:base(0, DateTime.MinValue, DateTime.MinValue, HashFunctionType.MD5)
{
var oOffset = offset;
this.id = DC.GetUInt64(data, offset);
offset += 8;
// load IPs
this.ip = DC.GetUInt32(data, offset);
offset += 4;
this.ip6 = DC.Clip(data, offset, 16);
offset += 16;
this.issueDate = DC.GetDateTime(data, offset);
offset += 8;
this.expireDate = DC.GetDateTime(data, offset);
offset += 8;
this.domain = Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]);
offset += (uint)data[offset] + 1;
this.authorityName = (Encoding.ASCII.GetString(data, (int)offset + 1, data[offset]));
offset += (uint)data[offset] + 1;
caId = DC.GetUInt64(data, offset);
offset += 8;
var aea = (AsymetricEncryptionAlgorithmType)(data[offset] >> 5);
if (aea == AsymetricEncryptionAlgorithmType.RSA)
{
var key = new RSAParameters();
uint exponentLength = (uint)data[offset++] & 0x1F;
key.Exponent = DC.Clip(data, offset, exponentLength);
offset += exponentLength;
uint keySize = DC.GetUInt16(data, offset);
offset += 2;
key.Modulus = DC.Clip(data, offset, keySize);
offset += keySize;
// copy cert data
publicRawData = new byte[offset - oOffset];
Buffer.BlockCopy(data, (int)oOffset, publicRawData, 0, publicRawData.Length);
if (privateKeyIncluded)
{
uint privateKeyLength = (keySize * 3) + (keySize / 2);
privateRawData = DC.Clip(data, offset, privateKeyLength);
uint halfKeySize = keySize / 2;
key.D = DC.Clip(data, offset, keySize);
offset += keySize;
key.DP = DC.Clip(data, offset, halfKeySize);
offset += halfKeySize;
key.DQ = DC.Clip(data, offset, halfKeySize);
offset += halfKeySize;
key.InverseQ = DC.Clip(data, offset, halfKeySize);
offset += halfKeySize;
key.P = DC.Clip(data, offset, halfKeySize);
offset += halfKeySize;
key.Q = DC.Clip(data, offset, halfKeySize);
offset += halfKeySize;
}
// setup rsa
rsa = RSA.Create();// new RSACryptoServiceProvider();
rsa.ImportParameters(key);
this.signature = DC.Clip(data, offset, length - (offset - oOffset));
}
}
public DomainCertificate(ulong id, string domain, CACertificate authority, DateTime issueDate,
DateTime expireDate, HashFunctionType hashFunction = HashFunctionType.SHA1, uint ip = 0, byte[] ip6 = null)
: base (id, issueDate, expireDate, hashFunction)
{
// assign type
var cr = new BinaryList();
// id
cr.AddUInt64(id);
// ip
this.ip = ip;
this.ip6 = ip6;
cr.AddUInt32(ip);
if (ip6?.Length == 16)
cr.AddUInt8Array(ip6);
else
cr.AddUInt8Array(new byte[16]);
cr.AddDateTime(issueDate)
.AddDateTime(expireDate);
// domain
this.domain = domain;
cr.AddUInt8((byte)(domain.Length))
.AddUInt8Array(Encoding.ASCII.GetBytes(domain));
// CA
this.caName = authority.Name;
cr.AddUInt8((byte)(authority.Name.Length))
.AddUInt8Array(Encoding.ASCII.GetBytes(authority.Name));
this.authorityName = authority.Name;
// CA Index
//co.KeyIndex = authority.KeyIndex;
this.caId = authority.Id;
cr.AddUInt64(caId);
// public key
rsa = RSA.Create();// new RSACryptoServiceProvider(2048);
rsa.KeySize = 2048;
RSAParameters dRSAKey = rsa.ExportParameters(true);
cr.AddUInt8((byte)dRSAKey.Exponent.Length)
.AddUInt8Array(dRSAKey.Exponent)
.AddUInt16((ushort)dRSAKey.Modulus.Length)
.AddUInt8Array(dRSAKey.Modulus);
publicRawData = cr.ToArray();
// private key
this.privateRawData = DC.Merge(dRSAKey.D, dRSAKey.DP, dRSAKey.DQ, dRSAKey.InverseQ, dRSAKey.P, dRSAKey.Q);
this.signature = authority.Sign(publicRawData);
}
public override bool Save(string filename, bool includePrivate = false)
{
try
{
if (includePrivate)
File.WriteAllBytes(filename, DC.Merge(new byte[] { (byte)CertificateType.DomainPrivate }, publicRawData, signature, privateRawData));
else
File.WriteAllBytes(filename, DC.Merge(new byte[] { (byte)CertificateType.DomainPublic }, publicRawData, signature));
return true;
}
catch
{
return false;
}
}
public override byte[] Serialize(bool includePrivate = false)
{
if (includePrivate)
return DC.Merge(publicRawData, signature, privateRawData);
else
return DC.Merge(publicRawData, signature);
}
}
}

View File

@ -1,43 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Authority
{
public class HostAuthentication : Authentication
{
public HostAuthentication()
:base(AuthenticationType.Host)
{
}
}
}

View File

@ -1,61 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using Esiur.Data;
using Esiur.Core;
using Esiur.Net;
using Esiur.Resource;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Authority
{
public class Session
{
public Authentication LocalAuthentication => localAuth;
public Authentication RemoteAuthentication => remoteAuth;
// public Source Source { get; }
public byte[] Id { get; set; }
public DateTime Creation { get; }
public DateTime Modification { get; }
public KeyList<string, object> Variables {get;} = new KeyList<string, object>();
//KeyList<string, object> Variables { get; }
//IStore Store { get; }
//string id;
Authentication localAuth, remoteAuth;
//string domain;
public Session(Authentication localAuthentication, Authentication remoteAuthentication)
{
this.localAuth = localAuthentication;
this.remoteAuth = remoteAuthentication;
}
}
}

View File

@ -1,59 +0,0 @@
/*
Copyright (c) 2017 Ahmed Kh. Zamil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
using Esiur.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Esiur.Security.Authority
{
public class Source
{
//string id;
KeyList<SourceAttributeType, object> attributes;
public string Id { get; set; }
public KeyList<SourceAttributeType, object> Attributes
{
get => attributes;
}
public Source(string id, KeyList<SourceAttributeType, object> attributes)
{
Id = id;
this.attributes = attributes;
}
public Source()
{
attributes = new KeyList<SourceAttributeType, object>();
}
}
}

Some files were not shown because too many files have changed in this diff Show More