1#define LOG_SOCKS5_EVENTS
4using System.Collections.Generic;
6using System.Runtime.ExceptionServices;
8using System.Threading.Tasks;
51 private readonly
int maxChunkSize;
59 : this(
Client, null, MaxChunkSize)
73 this.maxChunkSize = MaxChunkSize;
75 HttpxChunks.RegisterChunkReceiver(this.
client);
81 public override string[]
Extensions =>
new string[] { ExtensionId };
89 set => this.e2e = value;
97 get => this.ibbClient;
100 if (!(this.ibbClient is
null))
101 this.ibbClient.OnOpen -= this.IbbClient_OnOpen;
103 this.ibbClient = value;
104 this.ibbClient.OnOpen += this.IbbClient_OnOpen;
113 get => this.socks5Proxy;
116 if (!(this.socks5Proxy is
null))
117 this.socks5Proxy.OnOpen -= this.Socks5Proxy_OnOpen;
119 this.socks5Proxy = value;
120 this.socks5Proxy.OnOpen += this.Socks5Proxy_OnOpen;
129 get => this.postResource;
130 set => this.postResource = value;
138 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)
171 await this.
POST(To, Resource, P.Key, P.Value, Callback, DataCallback, State, Headers);
185 public async Task
POST(
string To,
string Resource,
byte[] Data,
string ContentType,
186 EventHandlerAsync<HttpxResponseEventArgs> Callback, EventHandlerAsync<HttpxResponseDataEventArgs> DataCallback,
187 object State, params
HttpField[] Headers)
189 MemoryStream DataStream =
new MemoryStream(Data);
195 DataStream?.Dispose();
198 return Callback.Raise(Sender, e);
201 await this.
POST(To, Resource, DataStream, ContentType, ResponseReceived, DataCallback, State, Headers);
205 DataStream?.Dispose();
206 ExceptionDispatchInfo.Capture(ex).Throw();
221 public Task
POST(
string To,
string Resource, Stream DataStream,
string ContentType,
222 EventHandlerAsync<HttpxResponseEventArgs> Callback, EventHandlerAsync<HttpxResponseDataEventArgs> DataCallback,
223 object State, params
HttpField[] Headers)
225 List<HttpField> Headers2 =
new List<HttpField>()
227 new HttpField(
"Content-Type", ContentType)
230 if (!(Headers is
null))
234 if (Field.
Key !=
"Content-Type")
239 return this.
Request(To,
"POST", Resource, 1.1, Headers2, DataStream, Callback, DataCallback, State);
252 public Task
Request(
string To,
string Method,
string LocalResource, EventHandlerAsync<HttpxResponseEventArgs> Callback,
253 EventHandlerAsync<HttpxResponseDataEventArgs> DataCallback,
object State, params
HttpField[] Headers)
255 return this.
Request(To, Method, LocalResource, 1.1, Headers,
null, Callback, DataCallback, State);
270 public async Task
Request(
string To,
string Method,
string LocalResource,
double HttpVersion, IEnumerable<HttpField> Headers,
271 Stream DataStream, EventHandlerAsync<HttpxResponseEventArgs> Callback, EventHandlerAsync<HttpxResponseDataEventArgs> DataCallback,
object State)
275 StringBuilder Xml =
new StringBuilder();
276 ResponseState ResponseState =
new ResponseState()
279 DataCallback = DataCallback,
283 Xml.Append(
"<req xmlns='");
285 Xml.Append(
"' method='");
287 Xml.Append(
"' resource='");
289 Xml.Append(
"' version='");
290 Xml.Append(HttpVersion.ToString(
"F1").Replace(System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator,
"."));
291 Xml.Append(
"' maxChunkSize='");
292 Xml.Append(this.maxChunkSize.ToString());
294 if (!(this.postResource is
null))
296 string Resource = await this.postResource.
GetUrl(this.ResponsePostbackHandler, ResponseState);
298 Xml.Append(
"' post='");
301 ResponseState.PreparePostBackCall(this.e2e, Resource, this.
client);
304 Xml.Append(
"' sipub='false' ibb='");
306 Xml.Append(
"' s5='");
308 Xml.Append(
"' jingle='false'>");
310 Xml.Append(
"<headers xmlns='");
314 foreach (
HttpField HeaderField
in Headers)
316 Xml.Append(
"<header name='");
320 Xml.Append(
"</header>");
322 Xml.Append(
"</headers>");
324 string StreamId =
null;
326 if (!(DataStream is
null))
328 if (DataStream.Length <
this.maxChunkSize)
330 int c = (int)DataStream.Length;
331 byte[] Data =
new byte[c];
333 DataStream.Position = 0;
334 await DataStream.ReadAllAsync(Data, 0, c);
336 Xml.Append(
"<data><base64>");
337 Xml.Append(Convert.ToBase64String(Data));
338 Xml.Append(
"</base64></data>");
342 StreamId = Guid.NewGuid().ToString().Replace(
"-",
string.Empty);
344 Xml.Append(
"<data><chunkedBase64 streamId='");
345 Xml.Append(StreamId);
346 Xml.Append(
"'/></data>");
350 Xml.Append(
"</req>");
352 await this.SendIqSet(To, Xml.ToString(), ResponseState);
354 if (!
string.IsNullOrEmpty(StreamId))
356 byte[] Data =
new byte[this.maxChunkSize];
358 long Len = DataStream.Length;
362 DataStream.Position = 0;
366 if (Pos + this.maxChunkSize <= Len)
367 i = this.maxChunkSize;
369 i = (int)(Len - Pos);
371 await DataStream.ReadAllAsync(Data, 0, i);
376 Xml.Append(
"<chunk xmlns='");
378 Xml.Append(
"' streamId='");
379 Xml.Append(StreamId);
380 Xml.Append(
"' nr='");
381 Xml.Append(Nr.ToString());
384 Xml.Append(
"' last='true");
387 Xml.Append(Convert.ToBase64String(Data, 0, i));
388 Xml.Append(
"</chunk>");
391 await this.SendChunk(To, Xml.ToString(), ResponseState);
396 private async Task SendIqSet(
string To,
string Xml,
object ResponseState)
398 TaskCompletionSource<bool> StanzaSent =
new TaskCompletionSource<bool>();
399 Task FlagStanzaAsSent(
object Sender, EventArgs e)
401 StanzaSent.TrySetResult(
true);
402 return Task.CompletedTask;
405 if (!(this.e2e is
null))
408 this.ResponseHandler, ResponseState, 60000, 0, FlagStanzaAsSent);
412 await this.
client.
SendIqSet(To, Xml, this.ResponseHandler, ResponseState,
413 60000, 0, FlagStanzaAsSent);
416 Task _ = Task.Delay(10000).ContinueWith((_2) =>
417 StanzaSent.TrySetException(
new TimeoutException(
"Unable to send HTTPX request.")));
419 await StanzaSent.Task;
422 private async Task SendChunk(
string To,
string Xml,
object ResponseState)
424 TaskCompletionSource<bool> StanzaSent =
new TaskCompletionSource<bool>();
425 Task FlagStanzaAsSent(
object Sender, EventArgs e)
427 StanzaSent.TrySetResult(
true);
428 return Task.CompletedTask;
431 if (!(this.e2e is
null))
434 MessageType.Normal,
string.Empty, To, Xml.ToString(),
string.Empty,
string.Empty,
435 string.Empty,
string.Empty,
string.Empty, FlagStanzaAsSent, ResponseState);
440 string.Empty,
string.Empty,
string.Empty,
string.Empty,
string.Empty, FlagStanzaAsSent, ResponseState);
443 Task _ = Task.Delay(10000).ContinueWith((_2) =>
444 StanzaSent.TrySetException(
new TimeoutException(
"Unable to send HTTPX data chunk.")));
446 await StanzaSent.Task;
449 private class ResponseState : IDisposable
451 public EventHandlerAsync<HttpxResponseEventArgs> Callback;
452 public EventHandlerAsync<HttpxResponseDataEventArgs> DataCallback;
453 public HttpxResponseEventArgs HttpxResponse =
null;
456 private string sha256 =
null;
457 private string id =
null;
458 private string from =
null;
459 private string to =
null;
460 private string endpointReference =
null;
461 private string symmetricCipherReference =
null;
462 private Stream data =
null;
464 private bool e2e =
false;
465 private bool disposeData =
false;
466 private bool disposed =
false;
473 this.endpointSecurity = EndpointSecurity;
478 public async Task PostDataReceived(
object Sender, Stream Data,
string From,
string To,
string EndpointReference,
string SymmetricCipherReference)
485 await this.client.Error(
"Unable to get access to HTTPX client. Dropping posted response.");
493 this.endpointReference = EndpointReference;
494 this.symmetricCipherReference = SymmetricCipherReference;
496 if (this.sha256 is
null)
499 await Data.CopyToAsync(this.data);
500 this.disposeData =
true;
502 await this.client.
Information(
"HTTP(S) POST received. Waiting for HTTPX response.");
506 await this.client.
Information(
"HTTP(S) POST received.");
507 string Msg = await this.CheckPostedData(Sender, Data);
508 if (!
string.IsNullOrEmpty(Msg))
514 if (!(this.synchObj is
null))
519 public async Task Sha256Received(
object Sender,
string Sha256,
bool E2e)
526 await this.client.Error(
"Unable to get access to HTTPX client. Dropping posted response.");
532 this.sha256 = Sha256;
535 if (!(this.data is
null))
536 await this.CheckPostedData(Sender, this.data);
540 if (!(this.synchObj is
null))
545 private async Task<string> CheckPostedData(
object Sender, Stream Data)
549 string CipherLocalName;
550 string CipherNamespace;
557 int i = this.symmetricCipherReference.IndexOf(
'#');
561 CipherLocalName = this.symmetricCipherReference;
562 CipherNamespace =
string.Empty;
566 CipherLocalName = this.symmetricCipherReference.Substring(i + 1);
567 CipherNamespace = this.symmetricCipherReference.Substring(0, i);
572 await this.client.Error(Msg =
"Symmetric cipher not understood: " + this.symmetricCipherReference);
576 Stream Decrypted = await this.endpointSecurity.
Decrypt(this.endpointReference, this.
id,
"POST", this.from, this.to, Data, SymmetricCipher);
577 if (Decrypted is
null)
579 StringBuilder sb =
new StringBuilder();
581 sb.Append(
"Unable to decrypt POSTed payload. Endpoint: ");
582 sb.Append(this.endpointReference);
585 sb.Append(
", Type: POST, From: ");
586 sb.Append(this.from);
589 sb.Append(
", Cipher: ");
590 sb.Append(this.symmetricCipherReference);
591 sb.Append(
", Bytes: ");
592 sb.Append(Data.Length.ToString());
594 await this.client.Error(Msg = sb.ToString());
598 if (this.disposeData)
599 this.data?.Dispose();
601 this.data = Data = Decrypted;
602 this.disposeData =
true;
607 string DigestBase64 = Convert.ToBase64String(Digest);
609 if (DigestBase64 == this.sha256)
611 await this.client.
Information(
"POSTed response validated and accepted.");
613 long Count = Data.Length;
614 int BufSize = (int)Math.Min(65536, Count);
615 byte[] Buf =
new byte[BufSize];
623 Array.Resize(ref Buf, (
int)Count);
624 BufSize = (int)Count;
627 if (BufSize != await Data.ReadAsync(Buf, 0, BufSize))
628 throw new IOException(
"Unexpected end of file.");
632 await this.DataCallback.Raise(Sender,
new HttpxResponseDataEventArgs(this.HttpxResponse, Buf,
string.Empty, Count <= 0, this.State),
false);
637 await this.client.Error(Msg =
"Dropping POSTed response, as SHA-256 digest did not match reported digest in response.");
649 public void Dispose()
653 this.disposed =
true;
655 this.synchObj =
null;
657 if (this.disposeData)
659 this.data?.Dispose();
666 private Task ResponsePostbackHandler(
object Sender, PostBackEventArgs e)
668 ResponseState ResponseState = (ResponseState)e.State;
669 return ResponseState.PostDataReceived(
this, e.Data, e.From, e.To, e.EndpointReference, e.SymmetricCipherReference);
676 string StatusMessage;
679 ResponseState ResponseState = (ResponseState)e.
State;
681 bool HasData =
false;
682 bool DisposeResponse =
true;
684 if (e.
Ok && !(E is
null) && E.LocalName ==
"resp" && E.NamespaceURI ==
Namespace)
691 foreach (XmlNode N
in E.ChildNodes)
696 foreach (XmlNode N2
in N.ChildNodes)
698 switch (N2.LocalName)
702 string Value = N2.InnerText;
711 foreach (XmlNode N2
in N.ChildNodes)
713 switch (N2.LocalName)
716 MemoryStream ms =
new MemoryStream();
718 Data = Response.
Encoding.GetBytes(N2.InnerText);
719 ms.Write(Data, 0, Data.Length);
725 ms =
new MemoryStream();
727 Data = Response.
Encoding.GetBytes(N2.InnerText);
728 ms.Write(Data, 0, Data.Length);
734 ms =
new MemoryStream();
736 Data = Convert.FromBase64String(N2.InnerText);
737 ms.Write(Data, 0, Data.Length);
742 case "chunkedBase64":
743 string StreamId =
XML.
Attribute((XmlElement)N2,
"streamId");
745 ResponseState.HttpxResponse =
new HttpxResponseEventArgs(e, Response, ResponseState.State, Version, StatusCode, StatusMessage,
true,
null);
747 HttpxChunks.chunkedStreams.Add(e.
From +
" " + StreamId,
new ClientChunkRecord(
this,
748 ResponseState.HttpxResponse, Response, ResponseState.DataCallback, ResponseState.State,
749 StreamId, e.
From, e.
To,
false,
null,
null));
751 DisposeResponse =
false;
758 ResponseState.HttpxResponse =
new HttpxResponseEventArgs(e, Response, ResponseState.State, Version, StatusCode, StatusMessage,
true,
null);
760 HttpxChunks.chunkedStreams.Add(e.
From +
" " + StreamId,
new ClientChunkRecord(
this,
761 ResponseState.HttpxResponse, Response, ResponseState.DataCallback, ResponseState.State,
762 StreamId, e.
From, e.
To,
false,
null,
null));
764 DisposeResponse =
false;
772 ResponseState.HttpxResponse =
new HttpxResponseEventArgs(e, Response, ResponseState.State, Version, StatusCode, StatusMessage,
true,
null);
774 HttpxChunks.chunkedStreams.Add(e.
From +
" " + StreamId,
new ClientChunkRecord(
this,
775 ResponseState.HttpxResponse, Response, ResponseState.DataCallback, ResponseState.State,
778 DisposeResponse =
false;
784 string DigestBase64 = N2.InnerText;
786 ResponseState.HttpxResponse =
new HttpxResponseEventArgs(e, Response, ResponseState.State, Version, StatusCode, StatusMessage,
true,
null);
788 Task _ = Task.Run(() => ResponseState.Sha256Received(
this, DigestBase64,
E2e));
790 DisposeResponse =
false;
811 StatusMessage =
"Service Unavailable";
815 HttpxResponseEventArgs e2 = ResponseState.HttpxResponse ??
816 new HttpxResponseEventArgs(e, Response, ResponseState.State, Version, StatusCode, StatusMessage, HasData, Data);
820 await ResponseState.Callback.Raise(
this, e2,
false);
827 ResponseState.Dispose();
839 HttpxChunks.chunkedStreams.Remove(To +
" " + StreamId);
841 StringBuilder Xml =
new StringBuilder();
843 Xml.Append(
"<cancel xmlns='");
845 Xml.Append(
"' streamId='");
846 Xml.Append(StreamId);
849 if (!(this.e2e is
null))
852 MessageType.Normal,
string.Empty, To, Xml.ToString(),
string.Empty,
string.Empty,
string.Empty,
853 string.Empty,
string.Empty,
null,
null);
856 return this.client.
SendMessage(
MessageType.Normal, To, Xml.ToString(),
string.Empty,
string.Empty,
string.Empty,
string.Empty,
string.Empty);
859 private Task IbbClient_OnOpen(
object Sender, InBandBytestreams.ValidateStreamEventArgs e)
861 string Key = e.From +
" " + e.StreamId;
863 if (HttpxChunks.chunkedStreams.ContainsKey(Key))
864 e.AcceptStream(this.IbbDataReceived, this.IbbStreamClosed,
new object[] { Key, -1,
null });
866 return Task.CompletedTask;
869 private async Task IbbDataReceived(
object Sender, InBandBytestreams.DataReceivedEventArgs e)
871 object[] P = (
object[])e.
State;
872 string Key = (
string)P[0];
874 byte[] PrevData = (
byte[])P[2];
876 if (HttpxChunks.chunkedStreams.TryGetValue(Key, out ChunkRecord Rec))
878 if (!(PrevData is
null))
879 await Rec.ChunkReceived(Nr,
false, PrevData);
887 private async Task IbbStreamClosed(
object Sender, InBandBytestreams.StreamClosedEventArgs e)
889 object[] P = (
object[])e.
State;
890 string Key = (
string)P[0];
892 byte[] PrevData = (
byte[])P[2];
894 if (HttpxChunks.chunkedStreams.TryGetValue(Key, out ChunkRecord Rec))
896 if (e.Reason == InBandBytestreams.CloseReason.Done)
898 if (!(PrevData is
null))
899 await Rec.ChunkReceived(Nr,
true, PrevData);
901 await Rec.ChunkReceived(Nr,
true,
new byte[0]);
906 HttpxChunks.chunkedStreams.Remove(Key);
910 private async Task Socks5Proxy_OnOpen(
object Sender, P2P.SOCKS5.ValidateStreamEventArgs e)
912 string Key = e.From +
" " + e.StreamId;
913 ClientChunkRecord ClientRec;
915 if (HttpxChunks.chunkedStreams.TryGetValue(Key, out ChunkRecord Rec))
917 ClientRec = Rec as ClientChunkRecord;
919 if (!(ClientRec is
null))
922 await this.client.
Information(
"Accepting SOCKS5 stream from " + e.
From);
924 e.AcceptStream(this.Socks5DataReceived, this.Socks5StreamClosed,
new Socks5Receiver(Key, e.StreamId,
925 ClientRec.from, ClientRec.to, ClientRec.e2e, ClientRec.endpointReference, ClientRec.symmetricCipher));
930 private class Socks5Receiver
933 public string StreamId;
936 public string EndpointReference;
938 public int State = 0;
939 public int BlockSize;
945 public Socks5Receiver(
string Key,
string StreamId,
string From,
string To,
bool E2e,
string EndpointReference,
949 this.StreamId = StreamId;
953 this.EndpointReference = EndpointReference;
954 this.SymmetricCipher = SymmetricCipher;
958 private async Task Socks5DataReceived(
object Sender, P2P.SOCKS5.DataReceivedEventArgs e)
960 Socks5Receiver Rx = (Socks5Receiver)e.
State;
962 if (HttpxChunks.chunkedStreams.TryGetValue(Rx.Key, out ChunkRecord Rec))
965 await this.client.
Information(e.Count.ToString() +
" bytes received over SOCKS5 stream " + Rx.Key +
".");
967 byte[] Buffer = e.Buffer;
968 int Offset = e.Offset;
977 Rx.BlockSize = Buffer[Offset++];
984 Rx.BlockSize |= Buffer[Offset++];
987 if (Rx.BlockSize == 0)
989 HttpxChunks.chunkedStreams.Remove(Rx.Key);
990 await Rec.ChunkReceived(Rx.Nr++,
true,
new byte[0]);
997 if (Rx.Block is
null || Rx.Block.Length != Rx.BlockSize)
998 Rx.Block =
new byte[Rx.BlockSize];
1004 d = Math.Min(Count, Rx.BlockSize - Rx.BlockPos);
1006 Array.Copy(Buffer, Offset, Rx.Block, Rx.BlockPos, d);
1011 if (Rx.BlockPos >= Rx.BlockSize)
1015 string Id = Rec.NextId().ToString();
1016 Rx.Block = await this.e2e.Decrypt(Rx.EndpointReference, Id, Rx.StreamId, Rx.From, Rx.To, Rx.Block, Rx.SymmetricCipher);
1017 if (Rx.Block is
null)
1019 string Message =
"Decryption of chunk " + Rx.Nr.ToString() +
" failed.";
1020#if LOG_SOCKS5_EVENTS
1021 await this.client.Error(Message);
1023 await Rec.Fail(Message);
1029#if LOG_SOCKS5_EVENTS
1030 await this.client.
Information(
"Chunk " + Rx.Nr.ToString() +
" received and forwarded.");
1032 await Rec.ChunkReceived(Rx.Nr++,
false, Rx.Block);
1041#if LOG_SOCKS5_EVENTS
1042 await this.client.
Warning(e.Count.ToString() +
" bytes received over SOCKS5 stream " + Rx.Key +
" and discarded.");
1048 private async Task Socks5StreamClosed(
object Sender, P2P.SOCKS5.StreamEventArgs e)
1050#if LOG_SOCKS5_EVENTS
1051 await this.client.
Information(
"SOCKS5 stream closed.");
1053 Socks5Receiver Rx = (Socks5Receiver)e.
State;
1055 if (HttpxChunks.chunkedStreams.TryGetValue(Rx.Key, out ChunkRecord Rec))
1057 HttpxChunks.chunkedStreams.Remove(Rx.Key);
1058 await Rec.ChunkReceived(Rx.Nr++,
true,
new byte[0]);
1070 public Task
GetJwtToken(
int Seconds, EventHandlerAsync<TokenResponseEventArgs> Callback,
object State)
1082 public Task
GetJwtToken(
string Address,
int Seconds, EventHandlerAsync<TokenResponseEventArgs> Callback,
object State)
1084 StringBuilder Xml =
new StringBuilder();
1086 Xml.Append(
"<jwt xmlns='");
1088 Xml.Append(
"' seconds='");
1089 Xml.Append(Seconds.ToString());
1092 return this.client.
SendIqGet(Address, Xml.ToString(), async (Sender, e) =>
1094 string Token =
null;
1127 TaskCompletionSource<string> Result =
new TaskCompletionSource<string>();
1129 await this.
GetJwtToken(Address, Seconds, (Sender, e) =>
1132 Result.TrySetResult(e.Token);
1136 return Task.CompletedTask;
1139 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.
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.
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.
Task Information(string Comment)
Called to inform the viewer of something.
Task Warning(string Warning)
Called to inform the viewer of a warning state.
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 ...
Task CancelTransfer(string To, string StreamId)
Requests the transfer of a stream to be cancelled.
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.
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.
Task 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.