Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
SmtpS2SEndpoint.cs
1using System;
2using System.Collections.Generic;
3using System.Net.Mail;
4using System.Text;
5using System.Threading.Tasks;
6using System.Xml;
7using Waher.Content;
13using Waher.Events;
19
21{
26 {
27 private static Cache<string, OutgoingMail> outgoingMails;
28 private readonly SmtpServer smtpServer;
29 private readonly XmppServer xmppServer;
30
31 static SmtpS2SEndpoint()
32 {
33 outgoingMails = new Cache<string, OutgoingMail>(int.MaxValue, TimeSpan.FromHours(1), TimeSpan.FromMinutes(1), true);
34 outgoingMails.Removed += OutgoingMails_Removed;
35
36 Log.Terminating += (Sender, e) =>
37 {
38 outgoingMails?.Dispose();
39 outgoingMails = null;
40 };
41 }
42
53 {
54 this.smtpServer = SmtpServer;
55 this.xmppServer = XmppServer;
56 }
57
61 public bool TrustServer => false;
62
66 public override string Type => "SMTP";
67
69 public override async Task<bool> Message(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml, ISender Sender)
70 {
71 if (string.Compare(Type, "chat", true) == 0)
72 {
73 string Key = From.Address + " | " + To.Address;
74 outgoingMails.TryGetValue(Key, out OutgoingMail Mail);
75
76 try
77 {
78 Stanza Stanza = XmppServer.ToStanza("message", Type, Id, To, From, Language, ContentXml);
79 List<EmbeddedContent> EmbeddedContent = null;
80 string Text = null;
81 string Html = null;
82 string Markdown = null;
83 string Subject = null;
84 string ReplaceId = null;
85 bool Immediate = false;
86
87 foreach (XmlNode N in Stanza.StanzaElement.ChildNodes)
88 {
89 if (N is XmlElement E)
90 {
91 switch (E.LocalName)
92 {
93 case "subject":
94 Subject = E.InnerText;
95 break;
96
97 case "body":
98 Text = E.InnerText;
99 break;
100
101 case "replace":
102 if (E.NamespaceURI == "urn:xmpp:message-correct:0")
103 ReplaceId = XML.Attribute(E, "id");
104 break;
105
106 case "html":
107 foreach (XmlNode N2 in E.ChildNodes)
108 {
109 if (N2 is XmlElement E2 && E2.LocalName == "body")
110 {
111 Html = E.InnerXml;
112 break;
113 }
114 }
115 break;
116
117 case "content":
118 switch (E.NamespaceURI)
119 {
121 switch (XML.Attribute(E, "type").ToLower())
122 {
124 Text = E.InnerText;
125 break;
126
128 Html = E.InnerText;
129 break;
130
132 Markdown = E.InnerText;
133 break;
134 }
135 break;
136
138 if (EmbeddedContent is null)
139 EmbeddedContent = new List<EmbeddedContent>();
140
141 byte[] Bin = Convert.FromBase64String(E.InnerText);
142
144 {
145 ID = XML.Attribute(E, "cid"),
146 ContentType = XML.Attribute(E, "type"),
147 Disposition = XML.Attribute(E, "disposition", ContentDisposition.Unknown),
148 Name = XML.Attribute(E, "name"),
149 FileName = XML.Attribute(E, "fileName"),
150 Description = XML.Attribute(E, "description"),
151 Size = Bin.Length,
152 TransferDecoded = Bin
153 });
154 break;
155 }
156 break;
157
158 case "immediate":
159 if (E.NamespaceURI == XmppServer.MailNamespace)
160 Immediate = true;
161 break;
162 }
163 }
164 }
165
166 if (!(Markdown is null) && (Text is null || Html is null))
167 {
168 MarkdownDocument Doc = await MarkdownDocument.CreateAsync(Markdown);
169
170 if (Text is null)
171 Text = await Doc.GeneratePlainText();
172
173 if (Html is null)
174 Html = HtmlDocument.GetBody(await Doc.GenerateHTML());
175 }
176
177
178 if (Subject is null && Text is null && Html is null)
179 return true;
180
181 if (Mail is null)
182 {
183 Mail = new OutgoingMail()
184 {
185 Endpoint = this,
186 From = From.BareJid,
187 To = To.BareJid
188 };
189
190 outgoingMails[Key] = Mail;
191 }
192
193 if (!string.IsNullOrEmpty(ReplaceId) &&
194 !(Mail.ById is null) &&
195 Mail.ById.TryGetValue(ReplaceId, out OutgoingMailRec Rec))
196 {
197 Rec.Html = Html;
198 Rec.Text = Text;
199 Rec.Embedded = EmbeddedContent?.ToArray();
200 }
201 else
202 {
203 if (string.IsNullOrEmpty(Mail.Subject))
204 Mail.Subject = Subject;
205 else if (Mail.Subject != Subject && !string.IsNullOrEmpty(Subject))
206 {
207 await Send(Mail);
208 Mail.Subject = Subject;
209 Mail.Records.Clear();
210 Mail.ById?.Clear();
211 }
212
213 if (string.IsNullOrEmpty(Id) && !string.IsNullOrEmpty(ReplaceId))
214 Id = ReplaceId;
215
216 Rec = new OutgoingMailRec()
217 {
218 Id = Id,
219 Html = Html,
220 Text = Text,
221 Embedded = EmbeddedContent?.ToArray()
222 };
223
224 Mail.Records.AddLast(Rec);
225
226 if (!string.IsNullOrEmpty(Id))
227 {
228 if (Mail.ById is null)
229 Mail.ById = new Dictionary<string, OutgoingMailRec>();
230
231 Mail.ById[Id] = Rec;
232 }
233 }
234
235 if (Immediate)
236 outgoingMails.Remove(Key);
237 }
238 catch (Exception ex)
239 {
240 Log.Exception(ex);
241 }
242 }
243
244 return true;
245 }
246
247 private static async Task OutgoingMails_Removed(object Sender, CacheItemEventArgs<string, OutgoingMail> e)
248 {
249 try
250 {
251 await Send(e.Value);
252 }
253 catch (Exception ex)
254 {
255 Log.Exception(ex);
256 }
257 }
258
259 private static async Task<bool> Send(OutgoingMail Mail)
260 {
261 List<EmbeddedContent> Attachments = null;
262 List<EmbeddedContent> Inline = null;
263 StringBuilder PlainText = null;
264 StringBuilder Html = null;
265 string Id = null;
266
267 foreach (OutgoingMailRec Rec in Mail.Records)
268 {
269 if (Id is null && !string.IsNullOrEmpty(Rec.Id))
270 Id = Rec.Id;
271
272 if (!string.IsNullOrEmpty(Rec.Text))
273 {
274 if (PlainText is null)
275 PlainText = new StringBuilder();
276
277 PlainText.AppendLine(Rec.Text.Trim());
278 }
279
280 if (!string.IsNullOrEmpty(Rec.Html))
281 {
282 if (Html is null)
283 Html = new StringBuilder();
284
285 Html.AppendLine(Rec.Html.Trim());
286 }
287
288 if (!(Rec.Embedded is null))
289 {
290 foreach (EmbeddedContent Embedded in Rec.Embedded)
291 {
292 switch (Embedded.Disposition)
293 {
294 case ContentDisposition.Inline:
295 if (Inline is null)
296 Inline = new List<EmbeddedContent>();
297
298 Inline.Add(Embedded);
299 break;
300
301 case ContentDisposition.Attachment:
302 default:
303 if (Attachments is null)
304 Attachments = new List<EmbeddedContent>();
305
306 Attachments.Add(Embedded);
307 break;
308 }
309 }
310 }
311 }
312
313 List<EmbeddedContent> Alternatives = new List<EmbeddedContent>();
314 string Subject = Mail.Subject;
315 string s;
316
317 if (!(PlainText is null))
318 {
319 s = PlainText.ToString();
320
321 Alternatives.Add(new EmbeddedContent()
322 {
323 ContentType = "text/plain; charset=utf-8",
324 Raw = Encoding.UTF8.GetBytes(s)
325 });
326
327 if (string.IsNullOrEmpty(Subject))
328 Subject = FirstRow(s);
329 }
330
331 if (!(Html is null))
332 {
333 s = Html.ToString();
334
335 EmbeddedContent HtmlContent = new EmbeddedContent()
336 {
337 ContentType = "text/html; charset=utf-8",
338 Raw = Encoding.UTF8.GetBytes(s)
339 };
340
341 if (!(Inline is null) && Inline.Count > 0)
342 {
343 EmbeddedContent[] RelatedContent = new EmbeddedContent[Inline.Count + 1];
344 RelatedContent[0] = HtmlContent;
345 Inline.CopyTo(RelatedContent, 1);
346 RelatedContent Related = new RelatedContent(RelatedContent, HtmlContent.ContentType);
347
348 KeyValuePair<byte[], string> P = await InternetContent.EncodeAsync(Related, null);
349 byte[] Encoded = P.Key;
350 string ContentType = P.Value;
351
352 HtmlContent = new EmbeddedContent()
353 {
355 Raw = Encoded
356 };
357 }
358
359 Alternatives.Add(HtmlContent);
360
361 if (string.IsNullOrEmpty(Subject))
362 {
363 HtmlDocument Doc = new HtmlDocument("<html><body>" + s + "</body></html>");
364 LinkedList<HtmlNode> ToProcess = new LinkedList<HtmlNode>();
365 string FirstHeader = null;
366 int FirstHeaderLevel = int.MaxValue;
367 string FirstParagraph = null;
368
369 foreach (HtmlNode N in Doc.Body.Children)
370 ToProcess.AddLast(N);
371
372 while (!(ToProcess.First is null))
373 {
374 HtmlNode N = ToProcess.First.Value;
375 ToProcess.RemoveFirst();
376
377 if (N is HtmlElement E)
378 {
379 if (string.Compare(E.Name, "P", true) == 0)
380 {
381 if (FirstParagraph is null)
382 FirstParagraph = GetText(E);
383 }
384 else if (E.Name.ToUpper().StartsWith("H") && int.TryParse(E.Name.Substring(1), out int Level))
385 {
386 if (Level < FirstHeaderLevel)
387 {
388 FirstHeader = GetText(E);
389 FirstHeaderLevel = Level;
390 }
391 }
392
393 if (E.HasChildren)
394 {
395 foreach (HtmlNode N2 in E.Children)
396 ToProcess.AddLast(N2);
397 }
398 }
399 }
400
401 Subject = FirstRow(FirstHeader);
402 if (string.IsNullOrEmpty(Subject))
403 Subject = FirstRow(FirstParagraph);
404 }
405 }
406
407 if (string.IsNullOrEmpty(Subject))
408 Subject = CommonTypes.EncodeRfc822(DateTimeOffset.Now);
409
410 return await Mail.Endpoint.smtpServer.SendMessage(Mail.From, Mail.To, Subject, Id, Alternatives.ToArray(), Attachments?.ToArray());
411 }
412
413 private static string FirstRow(string s)
414 {
415 s = s.Trim();
416 int i = s.IndexOfAny(CommonTypes.CRLF);
417 if (i < 0)
418 return s;
419 else
420 return s.Substring(0, i).TrimEnd();
421 }
422
423 private static string GetText(HtmlElement E)
424 {
425 StringBuilder Output = new StringBuilder();
426 GetText(E, Output);
427 return Output.ToString();
428 }
429
430 private static void GetText(HtmlElement E, StringBuilder Output)
431 {
432 if (string.Compare(E.Name, "BR", true) == 0)
433 Output.AppendLine();
434
435 if (E.HasChildren)
436 {
437 foreach (HtmlNode N in E.Children)
438 {
439 if (N is HtmlElement E2)
440 GetText(E2, Output);
441 else if (N is HtmlText Text)
442 Output.Append(Text.InlineText);
443 else if (N is CDATA CDATA)
444 Output.Append(CDATA.Content);
445 }
446 }
447 }
448
450 public override async Task<bool> Presence(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml, ISender Sender)
451 {
452 switch (Type)
453 {
454 case "subscribe":
455 await this.xmppServer.Presence("subscribed", Id, From, To, Language, string.Empty, this);
456
457 StringBuilder Markdown = new StringBuilder();
458
459 Markdown.AppendLine("e-Mail Invitation");
460 Markdown.AppendLine("======================");
461 Markdown.AppendLine();
462
463 Markdown.Append("**");
464 Markdown.Append(MarkdownDocument.Encode(From.BareJid));
465 Markdown.Append("** has added you to its white-list. This means you can send e-mail to **");
466 Markdown.Append(MarkdownDocument.Encode(From.BareJid));
467 Markdown.Append("** from **");
468 Markdown.Append(MarkdownDocument.Encode(To.BareJid));
469 Markdown.AppendLine("**.");
470
471 if (!await this.xmppServer.SendMailMessage(From.BareJid, To.BareJid, "Added to white-list", Markdown.ToString()))
472 return false;
473
474 Log.Informational("Added to white-list.", To.BareJid, From.BareJid);
475 break;
476
477 case "unsubscribe":
478 await this.xmppServer.Presence("unsubscribed", Id, From, To, Language, string.Empty, this);
479
480 Markdown = new StringBuilder();
481
482 Markdown.AppendLine("White-list removal");
483 Markdown.AppendLine("======================");
484 Markdown.AppendLine();
485
486 Markdown.Append("**");
487 Markdown.Append(MarkdownDocument.Encode(From.BareJid));
488 Markdown.Append("** has removed you from its white-list. This means you can no longer send e-mail to **");
489 Markdown.Append(MarkdownDocument.Encode(From.BareJid));
490 Markdown.Append("** from **");
491 Markdown.Append(MarkdownDocument.Encode(To.BareJid));
492 Markdown.AppendLine("**.");
493
494 if (!await this.xmppServer.SendMailMessage(From.BareJid, To.BareJid, "Removed from white-list", Markdown.ToString()))
495 return false;
496
497 Log.Informational("Removed from white-list.", To.BareJid, From.BareJid);
498 break;
499
500 case "subscribed":
501 Markdown = new StringBuilder();
502
503 Markdown.AppendLine("Request approved");
504 Markdown.AppendLine("===================");
505 Markdown.AppendLine();
506
507 Markdown.Append("Your request to be permitted to send e-mail to **");
508 Markdown.Append(MarkdownDocument.Encode(From.BareJid));
509 Markdown.Append("** from **");
510 Markdown.Append(MarkdownDocument.Encode(To.BareJid));
511 Markdown.AppendLine("** has been approved.");
512
513 if (!await this.xmppServer.SendMailMessage(From.BareJid, To.BareJid, "White-listing request approved", Markdown.ToString()))
514 return false;
515
516 Log.Informational("White-listing request approved.", To.BareJid, From.BareJid);
517 break;
518
519 case "unsubscribed":
520 Markdown = new StringBuilder();
521
522 Markdown.AppendLine("Request rejected");
523 Markdown.AppendLine("===================");
524 Markdown.AppendLine();
525
526 Markdown.Append("Your request to be permitted to send e-mail to **");
527 Markdown.Append(MarkdownDocument.Encode(From.BareJid));
528 Markdown.Append("** from **");
529 Markdown.Append(MarkdownDocument.Encode(To.BareJid));
530 Markdown.AppendLine("** has been rejected.");
531
532 if (!await this.xmppServer.SendMailMessage(From.BareJid, To.BareJid, "White-listing request rejected", Markdown.ToString()))
533 return false;
534
535 Log.Informational("White-listing request rejected.", To.BareJid, From.BareJid);
536 break;
537 }
538
539 return true;
540 }
541
543 public override async Task<bool> IQ(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml, ISender Sender)
544 {
545 if (Type == "get" || Type == "set")
546 {
547 StringBuilder sb = new StringBuilder();
548
549 sb.Append("IQ stanzas not supported for mail recipients. From: ");
550 sb.Append(From.Address.Value);
551 sb.Append(", To: ");
552 sb.Append(To.Address.Value);
553
554 return !(await Sender.IqErrorServiceUnavailable(Id, From, To, sb.ToString(), "en") is null);
555 }
556 else
557 return true;
558 }
559
561 public override Task<bool> IQ(string Type, string Id, XmppAddress To, XmppAddress From, string Language, Stanza Stanza, ISender Sender)
562 {
563 return this.IQ(Type, Id, To, From, Language, Stanza?.Content, Sender);
564 }
565
567 public override Task<bool> Message(string Type, string Id, XmppAddress To, XmppAddress From, string Language, Stanza Stanza, ISender Sender)
568 {
569 return this.Message(Type, Id, To, From, Language, Stanza?.Content, Sender);
570 }
571
573 public override Task<bool> Presence(string Type, string Id, XmppAddress To, XmppAddress From, string Language, Stanza Stanza, ISender Sender)
574 {
575 return this.Presence(Type, Id, To, From, Language, Stanza?.Content, Sender);
576 }
577
579 public override Task<bool> IqError(string Id, XmppAddress To, XmppAddress From, string ErrorXml)
580 {
581 return Task.FromResult(true); // Ignore
582 }
583
585 public override Task<string> IqError(string Id, XmppAddress To, XmppAddress From, Exception ex)
586 {
587 return Task.FromResult(string.Empty); // Ignore
588 }
589
591 public override Task<bool> IqResult(string Id, XmppAddress To, XmppAddress From, string ResultXml)
592 {
593 return Task.FromResult(true); // Ignore
594 }
595
597 public override Task<bool> Message(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml)
598 {
599 return this.Message(Type, Id, To, From, Language, ContentXml, null);
600 }
601
603 public override Task<bool> MessageError(string Id, XmppAddress To, XmppAddress From, Exception ex)
604 {
605 return Task.FromResult(true); // Ignore
606 }
607
609 public override Task<bool> Presence(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml)
610 {
611 return this.Presence(Type, Id, To, From, Language, ContentXml, null);
612 }
613
615 public override Task<bool> PresenceError(string Id, XmppAddress To, XmppAddress From, string ErrorXml)
616 {
617 return Task.FromResult(true); // Ignore
618 }
619
621 public override Task<bool> PresenceError(string Id, XmppAddress To, XmppAddress From, Exception ex)
622 {
623 return Task.FromResult(true); // Ignore
624 }
625
632 public Task<bool> RelayMessage(SmtpMessage Message, MailAddress Recipient)
633 {
634 StringBuilder Received = new StringBuilder();
635
636 Received.Append("from ");
637 Received.Append(Message.ClientName);
638 Received.Append(" [");
639 Received.Append(Message.RemoteEndpoint);
640 Received.Append("] by ");
641 Received.Append(this.smtpServer.Domain);
642 Received.Append(" with ");
643 Received.Append(typeof(SmtpServer).Namespace);
644 Received.Append(" ");
645 Received.Append(typeof(SmtpServer).Assembly.ImageRuntimeVersion);
646 Received.Append("; ");
647 Received.Append(CommonTypes.EncodeRfc822(DateTimeOffset.Now));
648
649 KeyValuePair<string, string>[] Headers = new KeyValuePair<string, string>[Message.AllHeaders.Length + 1];
650
651 Message.AllHeaders.CopyTo(Headers, 1);
652 Headers[0] = new KeyValuePair<string, string>("Received", Received.ToString());
653
654 return this.smtpServer.SendMessage(Message.FromMail.Address, Recipient.Address, Headers, Message.UntransformedBody, DateTime.Now);
655 }
656
657 }
658}
Helps with parsing of commong data types.
Definition: CommonTypes.cs:13
static readonly char[] CRLF
Contains the CR LF character sequence.
Definition: CommonTypes.cs:17
static string EncodeRfc822(DateTime Timestamp)
Encodes a date and time, according to RFC 822 §5.
Definition: CommonTypes.cs:667
CDATA content.
Definition: CDATA.cs:12
string Content
CDATA Content
Definition: CDATA.cs:33
HTML encoder/decoder.
Definition: HtmlCodec.cs:13
const string DefaultContentType
Default Content-Type for HTML: text/html
Definition: HtmlCodec.cs:24
static string GetBody(string Html)
Extracts the contents of the BODY element in a HTML string.
Body Body
First BODY element of document, if found, null otherwise.
Base class for all HTML elements.
Definition: HtmlElement.cs:12
bool HasChildren
If the element has children.
Definition: HtmlElement.cs:77
IEnumerable< HtmlNode > Children
Child nodes, or null if none.
Definition: HtmlElement.cs:87
Base class for all HTML nodes.
Definition: HtmlNode.cs:11
Static class managing encoding and decoding of internet content.
static Task< KeyValuePair< byte[], string > > EncodeAsync(object Object, Encoding Encoding, params string[] AcceptedContentTypes)
Encodes an object.
const string ContentType
Markdown content type.
Contains a markdown document. This markdown document class supports original markdown,...
static string Encode(string s)
Encodes all special characters in a string so that it can be included in a markdown document without ...
async Task< string > GeneratePlainText()
Generates Plain Text from the markdown text.
async Task< string > GenerateHTML()
Generates HTML from the markdown text.
static Task< MarkdownDocument > CreateAsync(string MarkdownText, params Type[] TransparentExceptionTypes)
Contains a markdown document. This markdown document class supports original markdown,...
Represents content embedded in other content.
ContentDisposition Disposition
Disposition of embedded object.
string ContentType
Content-Type of embedded object.
Plain text encoder/decoder.
const string DefaultContentType
text/plain
Helps with common XML-related tasks.
Definition: XML.cs:19
static string Attribute(XmlElement E, string Name)
Gets the value of an XML attribute.
Definition: XML.cs:914
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
static void Informational(string Message, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, string StackTrace, params KeyValuePair< string, object >[] Tags)
Logs an informational event.
Definition: Log.cs:334
Task Exception(Exception Exception)
Called to inform the viewer of an exception state.
ISniffer[] Sniffers
Registered sniffers.
Represents one message received over SMTP
Definition: SmtpMessage.cs:13
Implements a simple SMTP Server, as defined in:
Definition: SmtpServer.cs:44
Abstract base class for server connections.
CaseInsensitiveString LocalDomain
Local domain name.
CaseInsensitiveString RemoteDomain
Connection to domain.
Manages the connection with an SMTP server.
override async Task< bool > IQ(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml, ISender Sender)
Sends an IQ stanza. If stanza was sent.
SmtpS2SEndpoint(CaseInsensitiveString LocalDomain, CaseInsensitiveString RemoteDomain, SmtpServer SmtpServer, XmppServer XmppServer, params ISniffer[] Sniffers)
Manages the connection with an SMTP server.
override Task< bool > IqError(string Id, XmppAddress To, XmppAddress From, string ErrorXml)
Sends an IQ error stanza. If stanza was sent.
override Task< bool > IQ(string Type, string Id, XmppAddress To, XmppAddress From, string Language, Stanza Stanza, ISender Sender)
Sends an IQ stanza. If stanza was sent.
override Task< bool > Message(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml)
Sends a message stanza. If stanza was sent.
override Task< bool > Presence(string Type, string Id, XmppAddress To, XmppAddress From, string Language, Stanza Stanza, ISender Sender)
Sends a presence stanza. If stanza was sent.
override Task< bool > IqResult(string Id, XmppAddress To, XmppAddress From, string ResultXml)
Sends an IQ result stanza. If stanza was sent.
override Task< string > IqError(string Id, XmppAddress To, XmppAddress From, Exception ex)
Sends an IQ error stanza. If stanza was sent.
Task< bool > RelayMessage(SmtpMessage Message, MailAddress Recipient)
Relays a mail message
override Task< bool > PresenceError(string Id, XmppAddress To, XmppAddress From, Exception ex)
Sends a presence error stanza. If stanza was sent.
override Task< bool > Presence(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml)
Sends a presence stanza. If stanza was sent.
override Task< bool > PresenceError(string Id, XmppAddress To, XmppAddress From, string ErrorXml)
Sends a presence error stanza. If stanza was sent.
bool TrustServer
If server should be trusted, regardless if the operating system could validate its certificate or not...
override async Task< bool > Message(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml, ISender Sender)
Sends a message stanza. If stanza was sent.
override string Type
Type of endpoint
override async Task< bool > Presence(string Type, string Id, XmppAddress To, XmppAddress From, string Language, string ContentXml, ISender Sender)
Sends a presence stanza. If stanza was sent.
override Task< bool > MessageError(string Id, XmppAddress To, XmppAddress From, Exception ex)
Sends a message error stanza. If stanza was sent.
override Task< bool > Message(string Type, string Id, XmppAddress To, XmppAddress From, string Language, Stanza Stanza, ISender Sender)
Sends a message stanza. If stanza was sent.
Contains information about a stanza.
Definition: Stanza.cs:10
XmlElement StanzaElement
Stanza element.
Definition: Stanza.cs:114
Contains information about one XMPP address.
Definition: XmppAddress.cs:9
override string ToString()
object.ToString()
Definition: XmppAddress.cs:190
CaseInsensitiveString Address
XMPP Address
Definition: XmppAddress.cs:37
CaseInsensitiveString BareJid
Bare JID
Definition: XmppAddress.cs:45
const string ContentNamespace
urn:xmpp:content
Definition: XmppServer.cs:218
const string MailNamespace
urn:xmpp:smtp
Definition: XmppServer.cs:213
Represents a case-insensitive string.
string Value
String-representation of the case-insensitive string. (Representation is case sensitive....
Implements an in-memory cache.
Definition: Cache.cs:15
void Dispose()
IDisposable.Dispose
Definition: Cache.cs:74
bool Remove(KeyType Key)
Removes an item from the cache.
Definition: Cache.cs:451
bool TryGetValue(KeyType Key, out ValueType Value)
Tries to get a value from the cache.
Definition: Cache.cs:203
Event arguments for cache item removal events.
ValueType Value
Value of item that was removed.
Interface for sniffers. Sniffers can be added to ICommunicationLayer classes to eavesdrop on communic...
Definition: ISniffer.cs:11
Interface for senders of stanzas.
Definition: ISender.cs:10
ContentDisposition
Content disposition
ContentType
DTLS Record content type.
Definition: Enumerations.cs:11