Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
WebSniffer.cs
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Threading.Tasks;
5using Waher.Content;
7using Waher.Events;
12using Waher.Security;
13
15{
19 public class WebSniffer : SnifferBase, IDisposable
20 {
21 private readonly BinaryPresentationMethod binaryPresentationMethod;
22 private readonly DateTime created = DateTime.Now;
23 private readonly DateTime expires;
24 private readonly ICommunicationLayer comLayer;
25 private readonly string[] privileges;
26 private readonly string userVariable;
27 private readonly string resource;
28 private readonly string snifferId;
29 private readonly bool feedbackCheck;
30 private string[] tabIds = null;
31 private DateTime tabIdTimestamp = DateTime.MinValue;
32 private Cache<string, bool> outgoing;
33
45 public WebSniffer(string SnifferId, string PageResource, TimeSpan MaxLife, BinaryPresentationMethod BinaryPresentationMethod, ICommunicationLayer ComLayer,
46 string UserVariable, params string[] Privileges)
47 : base()
48 {
49 this.expires = DateTime.Now.Add(MaxLife);
50 this.comLayer = ComLayer;
51 this.snifferId = SnifferId;
52 this.resource = PageResource;
53 this.binaryPresentationMethod = BinaryPresentationMethod;
54 this.tabIds = null;
55 this.userVariable = UserVariable;
56 this.privileges = Privileges;
57 this.feedbackCheck = ComLayer is HttpServer;
58
59 if (this.feedbackCheck)
60 this.outgoing = new Cache<string, bool>(int.MaxValue, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1), true);
61 else
62 this.outgoing = null;
63 }
64
68 public virtual void Dispose()
69 {
70 this.outgoing?.Dispose();
71 this.outgoing = null;
72 }
73
77 public string SnifferId => this.snifferId;
78
79 private Task Process(DateTime Timestamp, string Message, string Function)
80 {
81 if (Timestamp >= this.expires)
82 return this.Close();
83 else
84 return this.Push(Timestamp, Message, Function, true);
85 }
86
87 private async Task Push(DateTime Timestamp, string Message, string Function, bool CloseIfNoTabs)
88 {
89 try
90 {
91 DateTime Now = DateTime.Now;
92
93 if ((Now - this.tabIdTimestamp).TotalSeconds > 2 || this.tabIds is null || this.tabIds.Length == 0)
94 {
95 this.tabIds = ClientEvents.GetTabIDsForLocation(this.resource, true, "SnifferId", this.snifferId);
96 this.tabIdTimestamp = Now;
97 }
98
99 if (this.feedbackCheck && Message.StartsWith("{") && Message.EndsWith("}"))
100 {
101 try
102 {
103 object Parsed = JSON.Parse(Message);
104 if (Parsed is IDictionary<string, object> Obj &&
105 Obj.TryGetValue("data", out object Temp) &&
106 Temp is IDictionary<string, object> Obj2 &&
107 Obj2.TryGetValue("timestamp", out object Timestamp2) &&
108 Obj2.TryGetValue("message", out object Message2) &&
109 (this.outgoing?.ContainsKey(this.ToJson(Timestamp2, Message2)) ?? true))
110 {
111 return;
112 }
113 }
114 catch (Exception)
115 {
116 // Ignore
117 }
118 }
119
120 string Data = this.ToJson(XML.Encode(Timestamp), Message);
121
122 this.outgoing?.Add(Data, true);
123
124 int Tabs = await ClientEvents.PushEvent(this.tabIds, Function, Data, true, this.userVariable, this.privileges);
125
126 if (CloseIfNoTabs && Tabs <= 0 && (Now - this.created).TotalSeconds >= 5)
127 await this.Close();
128 }
129 catch (Exception ex)
130 {
131 Log.Exception(ex);
132 }
133 }
134
135 private string ToJson(object Timestamp, object Message)
136 {
137 return JSON.Encode(new KeyValuePair<string, object>[]
138 {
139 new KeyValuePair<string, object>("timestamp", Timestamp),
140 new KeyValuePair<string, object>("message", Message)
141 }, false);
142 }
143
144 private async Task Close()
145 {
146 await this.Push(DateTime.Now, "Sniffer closed.", "Information", false);
147 this.comLayer.Remove(this);
148 this.Dispose();
149 }
150
151 private Task Process(DateTime Timestamp, byte[] Data, string Function)
152 {
153 if (Timestamp >= this.expires)
154 return this.Close();
155 else
156 return this.Push(Timestamp, this.HexOutput(Data), Function, true);
157 }
158
159 private string HexOutput(byte[] Data)
160 {
161 switch (this.binaryPresentationMethod)
162 {
163 case BinaryPresentationMethod.Hexadecimal:
164 StringBuilder sb = new StringBuilder();
165 int i = 0;
166 bool First = true;
167
168 foreach (byte b in Data)
169 {
170 if (i > 0)
171 sb.Append(' ');
172 else if (First)
173 First = false;
174 else
175 sb.AppendLine();
176
177 sb.Append(b.ToString("X2"));
178
179 i = (i + 1) & 31;
180 }
181
182 return sb.ToString();
183
184 case BinaryPresentationMethod.Base64:
185 return Convert.ToBase64String(Data);
186
187 case BinaryPresentationMethod.ByteCount:
188 default:
189 return "<" + Data.Length.ToString() + " bytes>";
190 }
191 }
192
198 public override Task Error(DateTime Timestamp, string Error)
199 {
200 return this.Process(Timestamp, Error, "Error");
201 }
202
208 public override Task Exception(DateTime Timestamp, string Exception)
209 {
210 return this.Process(Timestamp, Exception, "Exception");
211 }
212
218 public override Task Information(DateTime Timestamp, string Comment)
219 {
220 return this.Process(Timestamp, Comment, "Information");
221 }
222
228 public override Task ReceiveBinary(DateTime Timestamp, byte[] Data)
229 {
230 return this.Process(Timestamp, Data, "Rx");
231 }
232
238 public override Task ReceiveText(DateTime Timestamp, string Text)
239 {
240 return this.Process(Timestamp, Text, "Rx");
241 }
242
248 public override Task TransmitBinary(DateTime Timestamp, byte[] Data)
249 {
250 return this.Process(Timestamp, Data, "Tx");
251 }
252
258 public override Task TransmitText(DateTime Timestamp, string Text)
259 {
260 return this.Process(Timestamp, Text, "Tx");
261 }
262
268 public override Task Warning(DateTime Timestamp, string Warning)
269 {
270 return this.Process(Timestamp, Warning, "Warning");
271 }
272
273 }
274}
Helps with common JSON-related tasks.
Definition: JSON.cs:14
static object Parse(string Json)
Parses a JSON string.
Definition: JSON.cs:43
static string Encode(string s)
Encodes a string for inclusion in JSON.
Definition: JSON.cs:507
Helps with common XML-related tasks.
Definition: XML.cs:19
static string Encode(string s)
Encodes a string for use in XML.
Definition: XML.cs:27
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:13
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
Definition: Log.cs:1647
The ClientEvents class allows applications to push information asynchronously to web clients connecte...
Definition: ClientEvents.cs:51
static string[] GetTabIDsForLocation(string Location)
Gets the Tab IDs of all tabs that display a particular resource.
Sending sniffer events to the corresponding web page(s).
Definition: WebSniffer.cs:20
override Task ReceiveBinary(DateTime Timestamp, byte[] Data)
Called when binary data has been received.
Definition: WebSniffer.cs:228
override Task Information(DateTime Timestamp, string Comment)
Called to inform the viewer of something.
Definition: WebSniffer.cs:218
override Task Error(DateTime Timestamp, string Error)
Called to inform the viewer of an error state.
Definition: WebSniffer.cs:198
override Task Warning(DateTime Timestamp, string Warning)
Called to inform the viewer of a warning state.
Definition: WebSniffer.cs:268
override Task TransmitText(DateTime Timestamp, string Text)
Called when text has been transmitted.
Definition: WebSniffer.cs:258
override Task Exception(DateTime Timestamp, string Exception)
Called to inform the viewer of an exception state.
Definition: WebSniffer.cs:208
WebSniffer(string SnifferId, string PageResource, TimeSpan MaxLife, BinaryPresentationMethod BinaryPresentationMethod, ICommunicationLayer ComLayer, string UserVariable, params string[] Privileges)
Sending sniffer events to the corresponding web page(s).
Definition: WebSniffer.cs:45
virtual void Dispose()
IDisposable.Dispose
Definition: WebSniffer.cs:68
override Task ReceiveText(DateTime Timestamp, string Text)
Called when text has been received.
Definition: WebSniffer.cs:238
override Task TransmitBinary(DateTime Timestamp, byte[] Data)
Called when binary data has been transmitted.
Definition: WebSniffer.cs:248
Implements an HTTP server.
Definition: HttpServer.cs:36
Abstract base class for sniffers. Implements default method overloads.
Definition: SnifferBase.cs:12
Implements an in-memory cache.
Definition: Cache.cs:15
void Dispose()
IDisposable.Dispose
Definition: Cache.cs:74
void Add(KeyType Key, ValueType Value)
Adds an item to the cache.
Definition: Cache.cs:338
Interface for observable classes implementing communication protocols.
BinaryPresentationMethod
How binary data is to be presented.