1#define LOG_SOCKS5_EVENTS
5using System.Globalization;
7using System.Runtime.ExceptionServices;
9using System.Threading.Tasks;
52 private readonly
int maxChunkSize;
60 : this(
Client, null, MaxChunkSize)
74 this.maxChunkSize = MaxChunkSize;
76 HttpxChunks.RegisterChunkReceiver(this.
client);
82 public override string[]
Extensions =>
new string[] { ExtensionId };
90 set => this.e2e = value;
98 get => this.ibbClient;
101 if (!(this.ibbClient is
null))
102 this.ibbClient.OnOpen -= this.IbbClient_OnOpen;
104 this.ibbClient = value;
105 this.ibbClient.OnOpen += this.IbbClient_OnOpen;
114 get => this.socks5Proxy;
117 if (!(this.socks5Proxy is
null))
118 this.socks5Proxy.OnOpen -= this.Socks5Proxy_OnOpen;
120 this.socks5Proxy = value;
121 this.socks5Proxy.OnOpen += this.Socks5Proxy_OnOpen;
130 get => this.postResource;
131 set => this.postResource = value;
137 HttpxChunks.UnregisterChunkReceiver(this.
client);
150 public Task
GET(
string To,
string Resource, EventHandlerAsync<HttpxResponseEventArgs> Callback,
151 EventHandlerAsync<HttpxResponseDataEventArgs> DataCallback,
object State, params
HttpField[] Headers)
153 return this.
Request(To,
"GET", Resource, Callback, DataCallback, State, Headers);
166 public async Task
POST(
string To,
string Resource,
object Data,
167 EventHandlerAsync<HttpxResponseEventArgs> Callback, EventHandlerAsync<HttpxResponseDataEventArgs> DataCallback,
168 object State, params
HttpField[] Headers)
187 public async Task
POST(
string To,
string Resource,
byte[] Data,
string ContentType,
188 EventHandlerAsync<HttpxResponseEventArgs> Callback, EventHandlerAsync<HttpxResponseDataEventArgs> DataCallback,
189 object State, params
HttpField[] Headers)
191 MemoryStream DataStream =
new MemoryStream(Data);
197 DataStream?.Dispose();
200 return Callback.Raise(Sender, e);
204 await this.
POST(To, Resource, DataStream, ContentType, ResponseReceived, DataCallback, State, Headers);
208 DataStream?.Dispose();
209 ExceptionDispatchInfo.Capture(ex).Throw();
224 public Task
POST(
string To,
string Resource, Stream DataStream,
string ContentType,
225 EventHandlerAsync<HttpxResponseEventArgs> Callback, EventHandlerAsync<HttpxResponseDataEventArgs> DataCallback,
226 object State, params
HttpField[] Headers)
228 List<HttpField> Headers2 =
new List<HttpField>()
230 new HttpField(
"Content-Type", ContentType)
233 if (!(Headers is
null))
237 if (Field.
Key !=
"Content-Type")
242 return this.
Request(To,
"POST", Resource, 1.1, Headers2, DataStream, Callback, DataCallback, State);
255 public Task
Request(
string To,
string Method,
string LocalResource, EventHandlerAsync<HttpxResponseEventArgs> Callback,
256 EventHandlerAsync<HttpxResponseDataEventArgs> DataCallback,
object State, params
HttpField[] Headers)
258 return this.
Request(To, Method, LocalResource, 1.1, Headers,
null, Callback, DataCallback, State);
273 public async Task
Request(
string To,
string Method,
string LocalResource,
double HttpVersion, IEnumerable<HttpField> Headers,
274 Stream DataStream, EventHandlerAsync<HttpxResponseEventArgs> Callback, EventHandlerAsync<HttpxResponseDataEventArgs> DataCallback,
object State)
276 StringBuilder Xml =
new StringBuilder();
277 ResponseState ResponseState =
new ResponseState()
280 DataCallback = DataCallback,
284 Xml.Append(
"<req xmlns='");
286 Xml.Append(
"' method='");
288 Xml.Append(
"' resource='");
290 Xml.Append(
"' version='");
291 Xml.Append(HttpVersion.ToString(
"F1", CultureInfo.InvariantCulture));
292 Xml.Append(
"' maxChunkSize='");
293 Xml.Append(this.maxChunkSize.ToString());
295 if (!(this.postResource is
null))
297 string Resource = await this.postResource.
GetUrl(this.ResponsePostbackHandler, ResponseState);
299 Xml.Append(
"' post='");
302 ResponseState.PreparePostBackCall(this.e2e, Resource, this.
client);
305 Xml.Append(
"' sipub='false' ibb='");
307 Xml.Append(
"' s5='");
309 Xml.Append(
"' jingle='false'>");
311 Xml.Append(
"<headers xmlns='");
315 foreach (
HttpField HeaderField
in Headers)
317 Xml.Append(
"<header name='");
321 Xml.Append(
"</header>");
323 Xml.Append(
"</headers>");
325 string StreamId =
null;
327 if (!(DataStream is
null))
329 if (DataStream.Length <
this.maxChunkSize)
331 DataStream.Position = 0;
332 byte[] Data = await DataStream.ReadAllAsync();
334 Xml.Append(
"<data><base64>");
335 Xml.Append(Convert.ToBase64String(Data));
336 Xml.Append(
"</base64></data>");
340 StreamId = Guid.NewGuid().ToString().Replace(
"-",
string.Empty);
342 Xml.Append(
"<data><chunkedBase64 streamId='");
343 Xml.Append(StreamId);
344 Xml.Append(
"'/></data>");
348 Xml.Append(
"</req>");
350 await this.SendIqSet(To, Xml.ToString(), ResponseState);
352 if (!
string.IsNullOrEmpty(StreamId))
354 byte[] Data =
new byte[this.maxChunkSize];
356 long Len = DataStream.Length;
360 DataStream.Position = 0;
364 if (Pos + this.maxChunkSize <= Len)
365 i = this.maxChunkSize;
367 i = (int)(Len - Pos);
369 await DataStream.ReadAllAsync(Data, 0, i);
374 Xml.Append(
"<chunk xmlns='");
376 Xml.Append(
"' streamId='");
377 Xml.Append(StreamId);
378 Xml.Append(
"' nr='");
379 Xml.Append(Nr.ToString());
382 Xml.Append(
"' last='true");
385 Xml.Append(Convert.ToBase64String(Data, 0, i));
386 Xml.Append(
"</chunk>");
389 await this.SendChunk(To, Xml.ToString(), ResponseState);
394 private async Task SendIqSet(
string To,
string Xml,
object ResponseState)
396 TaskCompletionSource<bool> StanzaSent =
new TaskCompletionSource<bool>();
397 Task FlagStanzaAsSent(
object Sender, EventArgs e)
399 StanzaSent.TrySetResult(
true);
400 return Task.CompletedTask;
404 if (!(this.e2e is
null))
411 await this.
client.
SendIqSet(To, Xml, this.ResponseHandler, ResponseState,
415 Task
_ = Task.Delay(10000).ContinueWith((_2) =>
416 StanzaSent.TrySetException(
new GenericException(
new TimeoutException(
"Unable to send HTTPX request."),
null, To)));
418 await StanzaSent.Task;
421 private async Task SendChunk(
string To,
string Xml,
object ResponseState)
423 TaskCompletionSource<bool> StanzaSent =
new TaskCompletionSource<bool>();
424 Task FlagStanzaAsSent(
object Sender, EventArgs e)
426 StanzaSent.TrySetResult(
true);
427 return Task.CompletedTask;
430 if (!(this.e2e is
null))
433 MessageType.Normal,
string.Empty, To, Xml.ToString(),
string.Empty,
string.Empty,
434 string.Empty,
string.Empty,
string.Empty, FlagStanzaAsSent, ResponseState);
439 string.Empty,
string.Empty,
string.Empty,
string.Empty,
string.Empty, FlagStanzaAsSent, ResponseState);
442 Task
_ = Task.Delay(10000).ContinueWith((_2) =>
443 StanzaSent.TrySetException(
new GenericException(
new TimeoutException(
"Unable to send HTTPX data chunk."),
null, To)));
445 await StanzaSent.Task;
448 internal class ResponseState : IDisposable
450 public EventHandlerAsync<HttpxResponseEventArgs> Callback;
451 public EventHandlerAsync<HttpxResponseDataEventArgs> DataCallback;
452 public HttpxResponseEventArgs HttpxResponse =
null;
455 private string sha256 =
null;
456 private string id =
null;
457 private string from =
null;
458 private string to =
null;
459 private string endpointReference =
null;
460 private string symmetricCipherReference =
null;
461 private Stream data =
null;
463 private bool e2e =
false;
464 private bool disposeData =
false;
465 private bool disposed =
false;
472 this.endpointSecurity = EndpointSecurity;
477 public async Task PostDataReceived(
object Sender, Stream Data,
string From,
string To,
string EndpointReference,
string SymmetricCipherReference)
484 this.client.Error(
"Unable to get access to HTTPX client. Dropping posted response.");
492 this.endpointReference = EndpointReference;
493 this.symmetricCipherReference = SymmetricCipherReference;
495 if (this.sha256 is
null)
498 await Data.CopyToAsync(this.data);
499 this.disposeData =
true;
501 this.client.
Information(
"HTTP(S) POST received. Waiting for HTTPX response.");
506 string Msg = await this.CheckPostedData(Sender, Data);
507 if (!
string.IsNullOrEmpty(Msg))
513 if (!(this.synchObj is
null))
518 public async Task Sha256Received(
object Sender,
string Sha256,
bool E2e)
525 this.client.Error(
"Unable to get access to HTTPX client. Dropping posted response.");
531 this.sha256 = Sha256;
534 if (!(this.data is
null))
535 await this.CheckPostedData(Sender, this.data);
539 if (!(this.synchObj is
null))
544 private async Task<string> CheckPostedData(
object Sender, Stream Data)
548 string CipherLocalName;
549 string CipherNamespace;
556 int i = this.symmetricCipherReference.IndexOf(
'#');
560 CipherLocalName = this.symmetricCipherReference;
561 CipherNamespace =
string.Empty;
565 CipherLocalName = this.symmetricCipherReference[(i + 1)..];
566 CipherNamespace = this.symmetricCipherReference[..i];
571 this.client.Error(Msg =
"Symmetric cipher not understood: " + this.symmetricCipherReference);
575 Stream Decrypted = await this.endpointSecurity.
Decrypt(this.endpointReference, this.
id,
"POST", this.from, this.to, Data, SymmetricCipher);
576 if (Decrypted is
null)
578 StringBuilder sb =
new StringBuilder();
580 sb.Append(
"Unable to decrypt POSTed payload. Endpoint: ");
581 sb.Append(this.endpointReference);
584 sb.Append(
", Type: POST, From: ");
585 sb.Append(this.from);
588 sb.Append(
", Cipher: ");
589 sb.Append(this.symmetricCipherReference);
590 sb.Append(
", Bytes: ");
591 sb.Append(Data.Length.ToString());
593 this.client.Error(Msg = sb.ToString());
597 if (this.disposeData)
598 this.data?.Dispose();
600 this.data = Data = Decrypted;
601 this.disposeData =
true;
606 string DigestBase64 = Convert.ToBase64String(Digest);
608 if (DigestBase64 == this.sha256)
610 this.client.
Information(
"POSTed response validated and accepted.");
612 long Count = Data.Length;
613 int BufSize = (int)Math.Min(65536, Count);
614 byte[] Buf =
new byte[BufSize];
622 Array.Resize(ref Buf, (
int)Count);
623 BufSize = (int)Count;
626 await Data.ReadAllAsync(Buf, 0, BufSize);
630 HttpxResponseDataEventArgs e =
new HttpxResponseDataEventArgs(this.HttpxResponse,
631 true, Buf,
string.Empty, Count <= 0, this.State);
633 await this.DataCallback.Raise(Sender, e,
false);
638 this.client.Error(Msg =
"Dropping POSTed response, as SHA-256 digest did not match reported digest in response.");
650 public void Dispose()
654 this.disposed =
true;
656 this.synchObj =
null;
658 if (this.disposeData)
660 this.data?.Dispose();
667 private Task ResponsePostbackHandler(
object Sender, PostBackEventArgs e)
669 ResponseState ResponseState = (ResponseState)e.State;
670 return ResponseState.PostDataReceived(
this, e.Data, e.From, e.To, e.EndpointReference, e.SymmetricCipherReference);
677 string StatusMessage;
680 ResponseState ResponseState = (ResponseState)e.
State;
682 bool HasData =
false;
683 bool DisposeResponse =
true;
684 ClientChunkRecord Record =
null;
685 PendingChunkRecord PendingRecord =
null;
687 if (e.
Ok && !(E is
null) && E.LocalName ==
"resp" && E.NamespaceURI ==
Namespace)
695 foreach (XmlNode N
in E.ChildNodes)
700 foreach (XmlNode N2
in N.ChildNodes)
702 switch (N2.LocalName)
706 string Value = N2.InnerText;
715 foreach (XmlNode N2
in N.ChildNodes)
717 switch (N2.LocalName)
720 MemoryStream ms =
new MemoryStream();
722 Data = Response.
Encoding.GetBytes(N2.InnerText);
723 ms.Write(Data, 0, Data.Length);
729 ms =
new MemoryStream();
731 Data = Response.
Encoding.GetBytes(N2.InnerText);
732 ms.Write(Data, 0, Data.Length);
738 ms =
new MemoryStream();
740 Data = Convert.FromBase64String(N2.InnerText);
741 ms.Write(Data, 0, Data.Length);
746 case "chunkedBase64":
747 string StreamId =
XML.
Attribute((XmlElement)N2,
"streamId");
749 ResponseState.HttpxResponse =
new HttpxResponseEventArgs(e, Response, ResponseState.State, Version, StatusCode, StatusMessage,
true,
true,
null);
751 Record =
new ClientChunkRecord(
this, ResponseState.HttpxResponse,
752 Response, ResponseState.DataCallback, ResponseState.State, StreamId, e.
From,
753 e.
To,
false,
null,
null);
755 PendingRecord = await HttpxChunks.Add(e.
From +
" " + StreamId, Record);
757 DisposeResponse =
false;
764 ResponseState.HttpxResponse =
new HttpxResponseEventArgs(e, Response, ResponseState.State, Version, StatusCode, StatusMessage,
true,
true,
null);
766 Record =
new ClientChunkRecord(
this, ResponseState.HttpxResponse,
767 Response, ResponseState.DataCallback, ResponseState.State, StreamId, e.
From,
768 e.
To,
false,
null,
null);
770 PendingRecord = await HttpxChunks.Add(e.
From +
" " + StreamId, Record);
772 DisposeResponse =
false;
780 ResponseState.HttpxResponse =
new HttpxResponseEventArgs(e, Response, ResponseState.State, Version, StatusCode, StatusMessage,
true,
true,
null);
782 Record =
new ClientChunkRecord(
this, ResponseState.HttpxResponse,
783 Response, ResponseState.DataCallback, ResponseState.State, StreamId, e.
From,
786 PendingRecord = await HttpxChunks.Add(e.
From +
" " + StreamId, Record);
788 DisposeResponse =
false;
794 string DigestBase64 = N2.InnerText;
796 ResponseState.HttpxResponse =
new HttpxResponseEventArgs(e, Response, ResponseState.State, Version, StatusCode, StatusMessage,
true,
true,
null);
798 Task
_ = Task.Run(() => ResponseState.Sha256Received(
this, DigestBase64,
E2e));
800 DisposeResponse =
false;
821 StatusMessage =
"Service Unavailable";
825 HttpxResponseEventArgs e2 = ResponseState.HttpxResponse ??
826 new HttpxResponseEventArgs(e, Response, ResponseState.State, Version, StatusCode, StatusMessage, HasData,
true, Data);
830 await ResponseState.Callback.Raise(
this, e2,
false);
832 if (!(PendingRecord is
null) && !(Record is
null))
833 await PendingRecord.Replay(Record);
840 ResponseState.Dispose();
852 await HttpxChunks.Cancel(To +
" " + StreamId);
854 StringBuilder Xml =
new StringBuilder();
856 Xml.Append(
"<cancel xmlns='");
858 Xml.Append(
"' streamId='");
859 Xml.Append(StreamId);
862 if (!(this.e2e is
null))
865 MessageType.Normal,
string.Empty, To, Xml.ToString(),
string.Empty,
string.Empty,
string.Empty,
866 string.Empty,
string.Empty,
null,
null);
869 await this.client.
SendMessage(
MessageType.Normal, To, Xml.ToString(),
string.Empty,
string.Empty,
string.Empty,
string.Empty,
string.Empty);
872 private async Task IbbClient_OnOpen(
object Sender, InBandBytestreams.ValidateStreamEventArgs e)
874 string Key = e.From +
" " + e.StreamId;
876 if (await HttpxChunks.Contains(Key))
877 e.AcceptStream(this.IbbDataReceived, this.IbbStreamClosed,
new object[] { Key, -1,
true,
null });
880 private async Task IbbDataReceived(
object Sender, InBandBytestreams.DataReceivedEventArgs e)
882 object[] P = (
object[])e.
State;
883 string Key = (
string)P[0];
885 bool ConstantBuffer = (bool)P[2];
886 byte[] PrevData = (
byte[])P[3];
888 if (await HttpxChunks.Received(Key, Nr,
false, ConstantBuffer, PrevData))
892 P[2] = e.ConstantBuffer;
897 private async Task IbbStreamClosed(
object Sender, InBandBytestreams.StreamClosedEventArgs e)
899 object[] P = (
object[])e.
State;
900 string Key = (
string)P[0];
902 bool ConstantBuffer = (bool)P[2];
903 byte[] PrevData = (
byte[])P[3];
905 if (e.Reason == InBandBytestreams.CloseReason.Done)
907 await HttpxChunks.Received(Key, Nr,
true, ConstantBuffer, PrevData);
911 await HttpxChunks.Cancel(Key);
914 private async Task Socks5Proxy_OnOpen(
object Sender, P2P.SOCKS5.ValidateStreamEventArgs e)
916 string Key = e.From +
" " + e.StreamId;
918 if (await HttpxChunks.TryGetRecord(Key,
false) is ClientChunkRecord ClientRec)
923 e.AcceptStream(this.Socks5DataReceived, this.Socks5StreamClosed,
new Socks5Receiver(Key, e.StreamId,
924 ClientRec.
From, ClientRec.To, ClientRec.E2e, ClientRec.EndpointReference, ClientRec.SymmetricCipher));
928 private class Socks5Receiver
931 public string StreamId;
934 public string EndpointReference;
936 public int State = 0;
937 public int BlockSize;
943 public Socks5Receiver(
string Key,
string StreamId,
string From,
string To,
bool E2e,
string EndpointReference,
947 this.StreamId = StreamId;
951 this.EndpointReference = EndpointReference;
952 this.SymmetricCipher = SymmetricCipher;
956 private async Task Socks5DataReceived(
object Sender, P2P.SOCKS5.DataReceivedEventArgs e)
958 Socks5Receiver Rx = (Socks5Receiver)e.
State;
959 ChunkRecord Rec = await HttpxChunks.TryGetRecord(Rx.Key,
false);
964 this.client.
Information(e.Count.ToString() +
" bytes received over SOCKS5 stream " + Rx.Key +
".");
966 byte[] Buffer = e.Buffer;
967 int Offset = e.Offset;
976 Rx.BlockSize = Buffer[Offset++];
983 Rx.BlockSize |= Buffer[Offset++];
986 if (Rx.BlockSize == 0)
988 await HttpxChunks.Cancel(Rx.Key);
989 await Rec.ChunkReceived(Rx.Nr++,
true,
true, Array.Empty<
byte>());
990 await e.Stream.DisposeAsync();
996 if (Rx.Block is
null || Rx.Block.Length != Rx.BlockSize)
997 Rx.Block =
new byte[Rx.BlockSize];
1003 d = Math.Min(Count, Rx.BlockSize - Rx.BlockPos);
1005 System.Buffer.BlockCopy(Buffer, Offset, Rx.Block, Rx.BlockPos, d);
1010 if (Rx.BlockPos >= Rx.BlockSize)
1014 string Id = Rec.NextId().ToString();
1015 Rx.Block = await this.e2e.Decrypt(Rx.EndpointReference, Id, Rx.StreamId, Rx.From, Rx.To, Rx.Block, Rx.SymmetricCipher);
1016 if (Rx.Block is
null)
1018 string Message =
"Decryption of chunk " + Rx.Nr.ToString() +
" failed.";
1019#if LOG_SOCKS5_EVENTS
1020 this.client.Error(Message);
1022 await Rec.Fail(Message);
1023 await e.Stream.DisposeAsync();
1028#if LOG_SOCKS5_EVENTS
1029 this.client.
Information(
"Chunk " + Rx.Nr.ToString() +
" received and forwarded.");
1031 await Rec.ChunkReceived(Rx.Nr++,
false,
false, Rx.Block);
1040#if LOG_SOCKS5_EVENTS
1041 this.client.
Warning(e.Count.ToString() +
" bytes received over SOCKS5 stream " + Rx.Key +
" and discarded.");
1043 await e.Stream.DisposeAsync();
1047 private async Task Socks5StreamClosed(
object Sender, P2P.SOCKS5.StreamEventArgs e)
1049#if LOG_SOCKS5_EVENTS
1052 Socks5Receiver Rx = (Socks5Receiver)e.
State;
1053 ChunkRecord Rec = await HttpxChunks.TryGetRecord(Rx.Key,
true);
1056 await Rec.ChunkReceived(Rx.Nr++,
true,
true, Array.Empty<
byte>());
1067 public Task
GetJwtToken(
int Seconds, EventHandlerAsync<TokenResponseEventArgs> Callback,
object State)
1079 public Task
GetJwtToken(
string Address,
int Seconds, EventHandlerAsync<TokenResponseEventArgs> Callback,
object State)
1081 StringBuilder Xml =
new StringBuilder();
1083 Xml.Append(
"<jwt xmlns='");
1085 Xml.Append(
"' seconds='");
1086 Xml.Append(Seconds.ToString());
1089 return this.client.
SendIqGet(Address, Xml.ToString(), async (Sender, e) =>
1091 string Token =
null;
1124 TaskCompletionSource<string> Result =
new TaskCompletionSource<string>();
1126 await this.
GetJwtToken(Address, Seconds, (Sender, e) =>
1129 Result.TrySetResult(e.Token);
1133 return Task.CompletedTask;
1136 return await Result.Task;
Helps with parsing of commong data types.
static string Encode(bool x)
Encodes a Boolean for use in XML and other formats.
Contains information about a response to a content request.
byte[] Encoded
Encoded object.
string ContentType
Internet Content-Type of encoded object.
void AssertOk()
Asserts response is OK.
Static class managing encoding and decoding of internet content.
static int DefaultTimeout
Default timeout of internet access methods, in milliseconds.
static Task< ContentResponse > EncodeAsync(object Object, Encoding Encoding, params string[] AcceptedContentTypes)
Encodes an object.
Helps with common XML-related tasks.
static string Attribute(XmlElement E, string Name)
Gets the value of an XML attribute.
static string Encode(string s)
Encodes a string for use in XML.
Generic exception, with meta-data for logging.
void Warning(string Warning)
Called to inform the viewer of a warning state.
void Information(string Comment)
Called to inform the viewer of something.
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repe...
Base class for all HTTP fields.
string Key
HTTP Field Name
string Value
HTTP Field Value
Represets a response of an HTTP client request.
void SetResponseStream(Stream ResponseStream)
Sets the response stream of the response. Can only be set, if not set before.
async Task DisposeAsync()
Closes the connection and disposes of all resources.
void SetHeader(string FieldName, string Value)
Sets a custom header field value.
Encoding Encoding
Gets the System.Text.Encoding in which the output is written.
Event arguments for responses to IQ queries.
string E2eReference
Reference to End-to-end encryption endpoint used.
string From
From address attribute
bool Ok
If the response is an OK result response (true), or an error response (false).
object State
State object passed to the original request.
XmppException StanzaError
Any stanza error returned.
IE2eSymmetricCipher E2eSymmetricCipher
Type of symmetric cipher used in E2E encryption.
XmlElement FirstElement
First child element of the Response element.
string To
To address attribute
HttpxClient(XmppClient Client, int MaxChunkSize)
HTTPX client.
InBandBytestreams.IbbClient IbbClient
In-band bytestream client, if supported.
Task POST(string To, string Resource, Stream DataStream, string ContentType, EventHandlerAsync< HttpxResponseEventArgs > Callback, EventHandlerAsync< HttpxResponseDataEventArgs > DataCallback, object State, params HttpField[] Headers)
Performs a HTTP POST request.
Task GetJwtToken(string Address, int Seconds, EventHandlerAsync< TokenResponseEventArgs > Callback, object State)
Gets a JWT token from a token factory addressed by Address .
HttpxClient(XmppClient Client, IEndToEndEncryption E2e, int MaxChunkSize)
HTTPX client.
const string NamespaceHeaders
http://jabber.org/protocol/shim
Task GetJwtToken(int Seconds, EventHandlerAsync< TokenResponseEventArgs > Callback, object State)
Gets a JWT token from the server to which the client is connceted. The JWT token encodes the current ...
async Task POST(string To, string Resource, object Data, EventHandlerAsync< HttpxResponseEventArgs > Callback, EventHandlerAsync< HttpxResponseDataEventArgs > DataCallback, object State, params HttpField[] Headers)
Performs a HTTP POST request.
IPostResource PostResource
If responses can be posted to a specific resource.
const string Namespace
urn:xmpp:http
override void Dispose()
Disposes of the extension.
const string NamespaceJwt
urn:xmpp:http
const string ExtensionId
String identifying the extension on the client.
async Task CancelTransfer(string To, string StreamId)
Requests the transfer of a stream to be cancelled.
Task GET(string To, string Resource, EventHandlerAsync< HttpxResponseEventArgs > Callback, EventHandlerAsync< HttpxResponseDataEventArgs > DataCallback, object State, params HttpField[] Headers)
Performs an HTTP GET request.
IEndToEndEncryption E2e
Optional end-to-end encryption interface to use in requests.
async Task< string > GetJwtTokenAsync(string Address, int Seconds)
Gets a JWT token from a token factory addressed by Address .
Task< string > GetJwtTokenAsync(int Seconds)
Gets a JWT token from the server to which the client is connceted. The JWT token encodes the current ...
override string[] Extensions
Implemented extensions.
Task Request(string To, string Method, string LocalResource, EventHandlerAsync< HttpxResponseEventArgs > Callback, EventHandlerAsync< HttpxResponseDataEventArgs > DataCallback, object State, params HttpField[] Headers)
Performs an HTTP request.
async Task Request(string To, string Method, string LocalResource, double HttpVersion, IEnumerable< HttpField > Headers, Stream DataStream, EventHandlerAsync< HttpxResponseEventArgs > Callback, EventHandlerAsync< HttpxResponseDataEventArgs > DataCallback, object State)
Performs an HTTP request.
P2P.SOCKS5.Socks5Proxy Socks5Proxy
SOCKS5 proxy, if supported.
async Task POST(string To, string Resource, byte[] Data, string ContentType, EventHandlerAsync< HttpxResponseEventArgs > Callback, EventHandlerAsync< HttpxResponseDataEventArgs > DataCallback, object State, params HttpField[] Headers)
Performs a HTTP POST request.
Event arguments for HTTPX responses.
Event arguments for Token responses.
Class sending and receiving binary streams over XMPP using XEP-0047: In-band Bytestreams: https://xmp...
Class managing a SOCKS5 proxy associated with the current XMPP server.
Manages an XMPP client connection. Implements XMPP, as defined in https://tools.ietf....
Task SendMessage(MessageType Type, string To, string CustomXml, string Body, string Subject, string Language, string ThreadId, string ParentThreadId)
Sends a simple chat message
string Domain
Current Domain.
Task< uint > SendIqSet(string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Sends an IQ Set request.
Task< uint > SendIqGet(string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Sends an IQ Get request.
Base class for XMPP Extensions.
XmppClient client
XMPP Client used by the extension.
void Exception(Exception Exception)
Called to inform the viewer of an exception state.
XmppClient Client
XMPP Client.
Manages a temporary stream. Contents is kept in-memory, if below a memory threshold,...
Represents an object that allows single concurrent writers but multiple concurrent readers....
virtual Task EndWrite()
Ends a writing session of the object. Must be called once for each call to BeginWrite or successful c...
virtual async Task< bool > TryBeginWrite(int Timeout)
Waits, at most Timeout milliseconds, until object ready for writing. Each successful call to TryBegi...
virtual void Dispose()
IDisposable.Dispose
Contains methods for simple hash calculations.
static byte[] ComputeSHA256Hash(byte[] Data)
Computes the SHA-256 hash of a block of binary data.
Interface for HTTP(S) Post-back resources. These can be used to allow HTTPX servers to HTTP POST back...
Task< string > GetUrl(EventHandlerAsync< PostBackEventArgs > Callback, object State)
Gets a Post-back URL
Interface for symmetric ciphers.
End-to-end encryption interface.
Task< uint > SendIqSet(XmppClient Client, E2ETransmission E2ETransmission, string To, string Xml, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Sends an IQ Set request.
bool TryGetSymmetricCipher(string LocalName, string Namespace, out IE2eSymmetricCipher Cipher)
Tries to get a symmetric cipher from a reference.
Task< byte[]> Decrypt(string EndpointReference, string Id, string Type, string From, string To, byte[] Data, IE2eSymmetricCipher SymmetricCipher)
Decrypts binary data received from an XMPP client out of band.
Task SendMessage(XmppClient Client, E2ETransmission E2ETransmission, QoSLevel QoS, MessageType Type, string Id, string To, string CustomXml, string Body, string Subject, string Language, string ThreadId, string ParentThreadId, EventHandlerAsync< DeliveryEventArgs > DeliveryCallback, object State)
Sends an end-to-end encrypted message, if possible. If recipient does not support end-to-end encrypti...
QoSLevel
Quality of Service Level for asynchronous messages. Support for QoS Levels must be supported by the r...
MessageType
Type of message received.
E2ETransmission
End-to-end encryption mode.