3using System.Text.RegularExpressions;
4using System.Threading.Tasks;
10 internal class ChunkCounter : IDisposable
14 private readonly
bool receiving;
15 private readonly
bool cacheE2e;
19 this.receiving = Receiving;
20 this.comLayer = ComLayer;
21 this.cacheE2e = CacheE2e;
23 this.streams =
new Cache<string, Rec>(
int.MaxValue,
new TimeSpan(0, 0, 10),
new TimeSpan(0, 0, 2),
true);
24 this.streams.Removed += this.Streams_Removed;
27 public Task Client_OnDisposed(
object Sender, EventArgs e)
30 return Task.CompletedTask;
39 public string StreamId;
40 public int NrChunks = 0;
41 public long NrBytes = 0;
42 public bool Complete =
false;
45 public Rec(
string StreamId,
bool E2e)
47 this.StreamId = StreamId;
52 private static readonly Regex chunk =
new Regex(
"<(?'Tag'chunk)\\s+(((nr=['\"](?'Nr'\\d+)['\"])|(streamId=['\"](?'StreamId'[^'\"]+)['\"])|(last=['\"](?'Last'(true|false))['\"])|(xmlns=['\"](?'Namespace'[^'\"]+)['\"]))\\s*)+>(?'Base64'[^<]*)</chunk>", RegexOptions.Compiled | RegexOptions.Singleline);
54 public Task<string> RemoveChunkMessage(
string Text)
56 if (Text ==
"ChunkReceived")
59 return Task.FromResult(Text);
62 public Task<string> ShortenChunks(
string Text)
66 if (Text.IndexOf(
"<chunk") >= 0 && (M = chunk.Match(Text)).Success)
68 string Tag = M.Groups[
"Tag"].Value;
69 string Namespace = M.Groups[
"Namespace"].Value;
73 if (Namespace !=
"urn:xmpp:http")
74 return Task.FromResult(Text);
77 return Task.FromResult(Text);
79 string StreamId = M.Groups[
"StreamId"].Value;
80 bool Last = M.Groups[
"Last"].Value ==
"true";
81 string Base64 = M.Groups[
"Base64"].Value;
86 Data = Convert.FromBase64String(Base64);
90 return Task.FromResult(Text);
93 int NrBytes = Data.Length;
95 if (!this.streams.TryGetValue(StreamId, out Rec Rec))
97 Rec =
new Rec(StreamId,
false);
98 this.streams.Add(StreamId, Rec);
102 Rec.NrBytes += NrBytes;
107 this.streams.Remove(StreamId);
111 return Task.FromResult(Text);
114 int i = Text.IndexOf(
"<resp ");
117 i = Text.IndexOf(
"<data><base64>", i + 6);
119 return Task.FromResult(Text);
123 int j = Text.IndexOf(
"</base64></data>", i);
125 return Task.FromResult(Text);
127 string Base64 = Text.Substring(i, j - i);
132 Data = Convert.FromBase64String(Base64);
136 return Task.FromResult(Text);
139 Text = Text.Substring(0, i) +
"(" + Data.Length.ToString() +
" bytes)" + Text.Substring(j);
142 return Task.FromResult(Text);
147 if (this.comLayer.HasSniffers)
149 StringBuilder sb =
new StringBuilder();
155 sb.Append(Rec.NrChunks.ToString());
156 sb.Append(
" stanzas containing ");
157 sb.Append(Rec.NrBytes.ToString());
158 sb.Append(
" cipher bytes");
161 sb.Append(
" received from ");
163 sb.Append(
" transmitted to ");
165 sb.Append(Rec.StreamId);
171 sb.Append(Rec.NrChunks.ToString());
172 sb.Append(
" chunks containing ");
173 sb.Append(Rec.NrBytes.ToString());
174 sb.Append(
" bytes pertaining to stream ");
175 sb.Append(Rec.StreamId);
178 sb.Append(
" received.");
180 sb.Append(
" transmitted.");
182 if (e.
Value.Complete)
183 sb.Append(
" Transfer completed.");
188 if (this.comLayer.HasSniffers)
189 await this.comLayer.Information(sb.ToString());
Simple base class for classes implementing communication protocols.
Implements an in-memory cache.
Event arguments for cache item removal events.
ValueType Value
Value of item that was removed.