Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
HttpxProxy.cs
1using System;
2using System.Collections.Generic;
3using System.Threading.Tasks;
4using Waher.Content;
5using Waher.Events;
10
12{
19 {
20 private readonly XmppClient defaultXmppClient;
21 private HttpxClient httpxClient;
22 private XmppServerlessMessaging serverlessMessaging;
23 private IHttpxCache httpxCache;
24 private IPostResource postResource = null;
25 private InBandBytestreams.IbbClient ibbClient = null;
26 private P2P.SOCKS5.Socks5Proxy socks5Proxy = null;
27 private bool disposed = false;
28
35 public HttpxProxy(string ResourceName, XmppClient DefaultXmppClient, int MaxChunkSize)
36 : this(ResourceName, DefaultXmppClient, MaxChunkSize, null, null)
37 {
38 }
39
48 : this(ResourceName, DefaultXmppClient, MaxChunkSize, ServerlessMessaging, null)
49 {
50 }
51
62 {
63 this.defaultXmppClient = DefaultXmppClient;
64 this.serverlessMessaging = ServerlessMessaging;
65 this.httpxCache = HttpxCache;
66
67 this.httpxClient = new HttpxClient(this.defaultXmppClient, MaxChunkSize)
68 {
69 PostResource = this.postResource
70 };
71 }
72
76 public void Dispose()
77 {
78 this.httpxClient?.Dispose();
79 this.httpxClient = null;
80 this.disposed = true;
81 }
82
86 public bool Disposed => this.disposed;
87
92 {
93 get => this.postResource;
94 set
95 {
96 this.postResource = value;
97
98 if (!(this.httpxClient is null))
99 this.httpxClient.PostResource = value;
100 }
101 }
102
107 {
108 get => this.serverlessMessaging;
109 set
110 {
111 if (!(this.serverlessMessaging is null) && this.serverlessMessaging != value)
112 throw new Exception("Property already set.");
113
114 this.serverlessMessaging = value;
115 }
116 }
117
122 {
123 get => this.httpxCache;
124 set
125 {
126 if (!(this.httpxCache is null) && this.httpxCache != value)
127 throw new Exception("Property already set.");
128
129 this.httpxCache = value;
130 }
131 }
132
136 public XmppClient DefaultXmppClient => this.defaultXmppClient;
137
141 public HttpxClient DefaultHttpxClient => this.httpxClient;
142
147 {
148 get => this.ibbClient;
149 set
150 {
151 this.ibbClient = value;
152
153 if (!(this.httpxClient is null))
154 this.httpxClient.IbbClient = value;
155 }
156 }
157
162 {
163 get => this.socks5Proxy;
164 set
165 {
166 this.socks5Proxy = value;
167
168 if (!(this.httpxClient is null))
169 this.httpxClient.Socks5Proxy = value;
170 }
171 }
172
176 public override bool HandlesSubPaths
177 {
178 get
179 {
180 return true;
181 }
182 }
183
187 public override bool UserSessions
188 {
189 get
190 {
191 return false;
192 }
193 }
194
195 private async Task Request(string Method, HttpRequest Request, HttpResponse Response)
196 {
197 try
198 {
199 string Url = Request.SubPath;
200 if (Url.StartsWith("/"))
201 Url = Url.Substring(1);
202
203 if (!Url.StartsWith("httpx://", StringComparison.OrdinalIgnoreCase))
204 throw new BadRequestException("Invalid URI. Must use httpx URI scheme.");
205
206 int i = Url.IndexOf('/', 8);
207 if (i < 0)
208 throw new BadRequestException("Invalid URI.");
209
210 string BareJID = Url.Substring(8, i - 8);
211 string LocalUrl = Url.Substring(i);
212
213 IHttpxCachedResource CachedResource;
214
215 if (Method == "GET" && !(this.httpxCache is null))
216 {
217 if (!((CachedResource = await this.httpxCache.TryGetCachedResource(BareJID, LocalUrl)) is null))
218 {
219 if (!(Request.Header.IfNoneMatch is null))
220 {
221 if (!(CachedResource.ETag is null) && Request.Header.IfNoneMatch.Value == CachedResource.ETag)
222 throw new NotModifiedException();
223 }
224 else if (!(Request.Header.IfModifiedSince is null))
225 {
226 DateTimeOffset? Limit;
227
228 if ((Limit = Request.Header.IfModifiedSince.Timestamp).HasValue &&
229 HttpFolderResource.LessOrEqual(CachedResource.LastModified.UtcDateTime, Limit.Value.ToUniversalTime()))
230 {
231 throw new NotModifiedException();
232 }
233 }
234
235 await HttpFolderResource.SendResponse(CachedResource.FileName, CachedResource.ContentType, CachedResource.ETag,
236 CachedResource.LastModified.UtcDateTime, Response, Request);
237
238 return;
239 }
240 }
241
242 RosterItem Item = this.defaultXmppClient.GetRosterItem(BareJID);
243 if (Item is null)
244 {
245 if (!XmppClient.BareJidRegEx.IsMatch(BareJID))
246 throw new BadRequestException("Invalid Bare JID.");
247
248 // TODO: Request presence subscription, if user authenticated and request valid.
249
250 throw new ConflictException("No approved presence subscription with " + BareJID + ".");
251 }
252 else
253 {
254 foreach (PresenceEventArgs e in Item.Resources)
255 {
256 // TODO: Select one based on features.
257
258 if (!(this.serverlessMessaging is null))
259 {
260 await this.serverlessMessaging.GetPeerConnection(e.From, this.SendP2P, new SendP2pRec()
261 {
262 item = Item,
263 method = Method,
264 fullJID = e.From,
265 localUrl = LocalUrl,
266 request = Request,
267 response = Response
268 });
269 }
270 else
271 await this.SendRequest(this.httpxClient, e.From, Method, BareJID, LocalUrl, Request, Response);
272
273 return;
274 }
275
276 throw new ServiceUnavailableException(BareJID + " not online.");
277 }
278 }
279 catch (Exception ex)
280 {
281 await Response.SendResponse(ex);
282 }
283 }
284
294 public async Task<GetClientResponse> GetClientAsync(Uri Uri)
295 {
296 if (string.Compare(Uri.Scheme, HttpxGetter.HttpxUriScheme, true) != 0)
297 throw new ArgumentException("URI must use URI Scheme HTTPX.", nameof(Uri));
298
299 string BareJID = Uri.UserInfo + "@" + Uri.Authority;
300 string LocalUrl = Uri.PathAndQuery + Uri.Fragment;
301
302 RosterItem Item = this.defaultXmppClient.GetRosterItem(BareJID);
303 if (Item is null)
304 {
305 if (BareJID.IndexOf('@') < 0) // Server or component hosts HTTPX interface
306 {
307 return new GetClientResponse()
308 {
309 BareJid = BareJID,
310 FullJid = BareJID,
312 LocalUrl = LocalUrl
313 };
314 }
315
316 if (!XmppClient.BareJidRegEx.IsMatch(BareJID))
317 throw new BadRequestException("Invalid Bare JID.");
318
319 // TODO: Request presence subscription, if user authenticated and request valid.
320
321 throw new ConflictException("No approved presence subscription with " + BareJID + ".");
322 }
323 else
324 {
325 TaskCompletionSource<HttpxClient> Result = new TaskCompletionSource<HttpxClient>();
326
327 foreach (PresenceEventArgs e in Item.Resources)
328 {
329 if (!(this.serverlessMessaging is null))
330 {
331 await this.serverlessMessaging.GetPeerConnection(e.From, (sender, e2) =>
332 {
333 if (e2.Client is null)
334 Result.TrySetResult(this.httpxClient);
335 else
336 {
337 if (e2.Client.SupportsFeature(HttpxClient.Namespace) &&
338 e2.Client.TryGetTag("HttpxClient", out object Obj) &&
339 Obj is HttpxClient Client)
340 {
341 Result.TrySetResult(Client);
342 }
343 else
344 Result.TrySetResult(this.httpxClient);
345 }
346
347 return Task.CompletedTask;
348 }, null);
349 }
350 else
351 Result.TrySetResult(this.httpxClient);
352
353 HttpxClient Client2 = await Result.Task;
354
355 return new GetClientResponse()
356 {
357 FullJid = e.From,
358 BareJid = BareJID,
359 LocalUrl = LocalUrl,
360 HttpxClient = Client2
361 };
362 }
363
364 throw new ServiceUnavailableException(BareJID + " not online.");
365 }
366 }
367
368 private class SendP2pRec
369 {
370 public RosterItem item;
371 public string method;
372 public string fullJID;
373 public string localUrl;
374 public HttpRequest request;
375 public HttpResponse response;
376 }
377
378 private async Task SendP2P(object Sender, PeerConnectionEventArgs e)
379 {
380 SendP2pRec Rec = (SendP2pRec)e.State;
381
382 try
383 {
384 if (e.Client is null)
385 {
386 await this.SendRequest(this.httpxClient, Rec.fullJID, Rec.method, XmppClient.GetBareJID(Rec.fullJID),
387 Rec.localUrl, Rec.request, Rec.response);
388 }
389 else
390 {
391 if (e.Client.SupportsFeature(HttpxClient.Namespace) &&
392 e.Client.TryGetTag("HttpxClient", out object Obj) &&
393 Obj is HttpxClient Client)
394 {
395 await this.SendRequest(Client, Rec.fullJID, Rec.method, XmppClient.GetBareJID(Rec.fullJID),
396 Rec.localUrl, Rec.request, Rec.response);
397 }
398 else
399 {
400 await this.SendRequest(this.httpxClient, Rec.fullJID, Rec.method, XmppClient.GetBareJID(Rec.fullJID),
401 Rec.localUrl, Rec.request, Rec.response);
402 }
403 }
404 }
405 catch (Exception ex)
406 {
407 await Rec.response.SendResponse(ex);
408 }
409 }
410
411 private Task SendRequest(HttpxClient HttpxClient, string To, string Method, string BareJID, string LocalUrl,
412 HttpRequest Request, HttpResponse Response)
413 {
414 LinkedList<HttpField> Headers = new LinkedList<HttpField>();
415
416 foreach (HttpField Header in Request.Header)
417 {
418 switch (Header.Key.ToLower())
419 {
420 case "host":
421 Headers.AddLast(new HttpField("Host", BareJID));
422 break;
423
424 case "cookie":
425 case "set-cookie":
426 // Do not forward cookies.
427 break;
428
429 default:
430 Headers.AddLast(Header);
431 break;
432 }
433 }
434
435 ReadoutState State = new ReadoutState(Response, BareJID, LocalUrl)
436 {
437 Cacheable = (Method == "GET" && !(this.httpxCache is null))
438 };
439
440 string s = LocalUrl;
441 int i = s.IndexOf('.');
442 if (i > 0)
443 {
444 s = s.Substring(i + 1);
445 i = s.IndexOfAny(new char[] { '?', '#' });
446 if (i > 0)
447 s = s.Substring(0, i);
448
449 if (this.httpxCache.CanCache(BareJID, LocalUrl, InternetContent.GetContentType(s)))
450 {
451 LinkedListNode<HttpField> Loop = Headers.First;
452 LinkedListNode<HttpField> Next;
453
454 while (!(Loop is null))
455 {
456 Next = Loop.Next;
457
458 switch (Loop.Value.Key.ToLower())
459 {
460 case "if-match":
461 case "if-modified-since":
462 case "if-none-match":
463 case "if-range":
464 case "if-unmodified-since":
465 Headers.Remove(Loop);
466 break;
467 }
468
469 Loop = Next;
470 }
471 }
472 }
473
474 return HttpxClient.Request(To, Method, LocalUrl, Request.Header.HttpVersion, Headers, Request.HasData ? Request.DataStream : null,
475 this.RequestResponse, this.ResponseData, State);
476 }
477
478 private async Task RequestResponse(object Sender, HttpxResponseEventArgs e)
479 {
480 ReadoutState State2 = (ReadoutState)e.State;
481
482 State2.Response.StatusCode = e.StatusCode;
483 State2.Response.StatusMessage = e.StatusMessage;
484
485 if (!(e.HttpResponse is null))
486 {
487 foreach (KeyValuePair<string, string> Field in e.HttpResponse.GetHeaders())
488 {
489 switch (Field.Key.ToLower())
490 {
491 case "cookie":
492 case "set-cookie":
493 // Do not forward cookies.
494 break;
495
496 case "content-type":
497 State2.ContentType = Field.Value;
498 State2.Response.SetHeader(Field.Key, Field.Value);
499 break;
500
501 case "etag":
502 State2.ETag = Field.Value;
503 State2.Response.SetHeader(Field.Key, Field.Value);
504 break;
505
506 case "last-modified":
507 DateTimeOffset TP;
508 if (CommonTypes.TryParseRfc822(Field.Value, out TP))
509 State2.LastModified = TP;
510 State2.Response.SetHeader(Field.Key, Field.Value);
511 break;
512
513 case "expires":
514 if (CommonTypes.TryParseRfc822(Field.Value, out TP))
515 State2.Expires = TP;
516 State2.Response.SetHeader(Field.Key, Field.Value);
517 break;
518
519 case "cache-control":
520 State2.CacheControl = Field.Value;
521 State2.Response.SetHeader(Field.Key, Field.Value);
522 break;
523
524 case "pragma":
525 State2.Pragma = Field.Value;
526 State2.Response.SetHeader(Field.Key, Field.Value);
527 break;
528
529 default:
530 State2.Response.SetHeader(Field.Key, Field.Value);
531 break;
532 }
533 }
534 }
535
536 if (!e.HasData)
537 await State2.Response.SendResponse();
538 else
539 {
540 if (e.StatusCode == 200 && State2.Cacheable && State2.CanCache &&
541 this.httpxCache.CanCache(State2.BareJid, State2.LocalResource, State2.ContentType))
542 {
543 State2.TempOutput = new TemporaryStream();
544 }
545
546 if (!(e.Data is null))
547 await this.BinaryDataReceived(State2, true, e.Data);
548 }
549 }
550
551 private Task ResponseData(object Sender, HttpxResponseDataEventArgs e)
552 {
553 ReadoutState State2 = (ReadoutState)e.State;
554
555 return this.BinaryDataReceived(State2, e.Last, e.Data);
556 }
557
558 private async Task BinaryDataReceived(ReadoutState State2, bool Last, byte[] Data)
559 {
560 try
561 {
562 await State2.Response.Write(Data);
563 }
564 catch (Exception)
565 {
566 State2.Dispose();
567 return;
568 }
569
570 State2.TempOutput?.Write(Data, 0, Data.Length);
571
572 if (Last)
573 {
574 await State2.Response.SendResponse();
575 this.AddToCacheAsync(State2);
576 }
577 }
578
579 private async void AddToCacheAsync(ReadoutState State)
580 {
581 try
582 {
583 if (!(State.TempOutput is null))
584 {
585 State.TempOutput.Position = 0;
586
587 await this.httpxCache.AddToCache(State.BareJid, State.LocalResource, State.ContentType, State.ETag,
588 State.LastModified.Value, State.Expires, State.TempOutput);
589 }
590 }
591 catch (Exception ex)
592 {
593 Log.Exception(ex);
594 }
595 finally
596 {
597 try
598 {
599 State.Dispose();
600 }
601 catch (Exception ex2)
602 {
603 Log.Exception(ex2);
604 }
605 }
606 }
607
608 private class ReadoutState : IDisposable
609 {
610 public bool Cacheable = false;
611 public HttpResponse Response;
612 public string ETag = null;
613 public string BareJid = null;
614 public string LocalResource = null;
615 public string ContentType = null;
616 public string CacheControl = null;
617 public string Pragma = null;
618 public DateTimeOffset? Expires = null;
619 public DateTimeOffset? LastModified = null;
620 public TemporaryStream TempOutput = null;
621
622 public ReadoutState(HttpResponse Response, string BareJid, string LocalResource)
623 {
624 this.Response = Response;
625 this.BareJid = BareJid;
626 this.LocalResource = LocalResource;
627 }
628
629 public bool CanCache
630 {
631 get
632 {
633 if (this.ETag is null || !this.LastModified.HasValue)
634 return false;
635
636 if (!(this.CacheControl is null))
637 {
638 if ((this.CacheControl.Contains("no-cache") || this.CacheControl.Contains("no-store")))
639 return false;
640
641 if (!this.Expires.HasValue)
642 {
643 string s = this.CacheControl;
644 int i = s.IndexOf("max-age");
645 int c = s.Length;
646 char ch;
647
648 while (i < c && ((ch = s[i]) <= ' ' || ch == '=' || ch == 160))
649 i++;
650
651 int j = i;
652
653 while (j < c && (ch = s[j]) >= '0' && ch <= '9')
654 j++;
655
656 if (j > i && int.TryParse(s.Substring(i, j - i), out j))
657 this.Expires = DateTimeOffset.UtcNow.AddSeconds(j);
658 }
659 }
660
661 if (!(this.Pragma is null) && this.Pragma.Contains("no-cache"))
662 return false;
663
664 return true;
665 }
666 }
667
668 public void Dispose()
669 {
670 if (!(this.TempOutput is null))
671 {
672 this.TempOutput.Dispose();
673 this.TempOutput = null;
674 }
675 }
676 }
677
681 public bool AllowsGET
682 {
683 get { return true; }
684 }
685
692 public Task GET(HttpRequest Request, HttpResponse Response)
693 {
694 return this.Request("GET", Request, Response);
695 }
696
704 public Task GET(HttpRequest Request, HttpResponse Response, ByteRangeInterval FirstInterval)
705 {
706 return this.Request("GET", Request, Response);
707 }
708
715 public override Task OPTIONS(HttpRequest Request, HttpResponse Response)
716 {
717 return this.Request("OPTIONS", Request, Response);
718 }
719
723 public bool AllowsPOST
724 {
725 get { return true; }
726 }
727
734 public Task POST(HttpRequest Request, HttpResponse Response)
735 {
736 return this.Request("POST", Request, Response);
737 }
738
746 public Task POST(HttpRequest Request, HttpResponse Response, ContentByteRangeInterval Interval)
747 {
748 return this.Request("POST", Request, Response);
749 }
750
754 public bool AllowsPUT
755 {
756 get { return true; }
757 }
758
765 public Task PUT(HttpRequest Request, HttpResponse Response)
766 {
767 return this.Request("PUT", Request, Response);
768 }
769
777 public Task PUT(HttpRequest Request, HttpResponse Response, ContentByteRangeInterval Interval)
778 {
779 return this.Request("PUT", Request, Response);
780 }
781
785 public bool AllowsPATCH
786 {
787 get { return true; }
788 }
789
796 public Task PATCH(HttpRequest Request, HttpResponse Response)
797 {
798 return this.Request("PATCH", Request, Response);
799 }
800
808 public Task PATCH(HttpRequest Request, HttpResponse Response, ContentByteRangeInterval Interval)
809 {
810 return this.Request("PATCH", Request, Response);
811 }
812
816 public bool AllowsTRACE
817 {
818 get { return true; }
819 }
820
827 public Task TRACE(HttpRequest Request, HttpResponse Response)
828 {
829 return this.Request("TRACE", Request, Response);
830 }
831
835 public bool AllowsDELETE
836 {
837 get { return true; }
838 }
839
846 public Task DELETE(HttpRequest Request, HttpResponse Response)
847 {
848 return this.Request("DELETE", Request, Response);
849 }
850 }
851}
Helps with parsing of commong data types.
Definition: CommonTypes.cs:13
static bool TryParseRfc822(string s, out DateTimeOffset Value)
Parses a date and time value encoded according to RFC 822, §5.
Definition: CommonTypes.cs:170
Static class managing encoding and decoding of internet content.
static string GetContentType(string FileExtension)
Gets the content type of an item, given its file extension. It uses the TryGetContentType to see if a...
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 request could not be understood by the server due to malformed syntax. The client SHOULD NOT repe...
Represents a range in a ranged HTTP request or response.
The request could not be completed due to a conflict with the current state of the resource....
Represents a content range in a ranged HTTP request or response.
Base class for all asynchronous HTTP resources. An asynchronous resource responds outside of the meth...
Base class for all HTTP fields.
Definition: HttpField.cs:7
string Key
HTTP Field Name
Definition: HttpField.cs:25
Publishes a folder with all its files and subfolders through HTTP GET, with optional support for PUT,...
static Task SendResponse(string FullPath, string ContentType, string ETag, DateTime LastModified, HttpResponse Response)
Sends a file-based response back to the client.
static bool LessOrEqual(DateTime LastModified, DateTimeOffset Limit)
Computes LastModified <=Limit . The normal <= operator behaved strangely, and did not get the equalit...
HttpFieldIfModifiedSince IfModifiedSince
If-Modified-Since HTTP Field header. (RFC 2616, §14.25)
HttpFieldIfNoneMatch IfNoneMatch
If-None-Match HTTP Field header. (RFC 2616, §14.26)
Represents an HTTP request.
Definition: HttpRequest.cs:18
Stream DataStream
Data stream, if data is available, or null if data is not available.
Definition: HttpRequest.cs:139
HttpRequestHeader Header
Request header.
Definition: HttpRequest.cs:134
bool HasData
If the request has data.
Definition: HttpRequest.cs:74
string SubPath
Sub-path. If a resource is found handling the request, this property contains the trailing sub-path o...
Definition: HttpRequest.cs:146
string ResourceName
Name of resource.
Represets a response of an HTTP client request.
Definition: HttpResponse.cs:21
async Task SendResponse()
Sends the response back to the client. If the resource is synchronous, there's no need to call this m...
If the client has performed a conditional GET request and access is allowed, but the document has not...
The server is currently unable to handle the request due to a temporary overloading or maintenance of...
Event arguments for presence events.
string From
From where the presence was received.
Response to the HttpxProxy.GetClientAsync(Uri) method call.
override void Dispose()
Disposes of the extension.
Definition: HttpxClient.cs:134
Content Getter, retrieving content using the HTTPX URI Scheme.
Definition: HttpxGetter.cs:21
Implements a Proxy resource that allows Web clients to fetch HTTP-based resources over HTTPX.
Definition: HttpxProxy.cs:19
HttpxProxy(string ResourceName, XmppClient DefaultXmppClient, int MaxChunkSize, XmppServerlessMessaging ServerlessMessaging, IHttpxCache HttpxCache)
Implements a Proxy resource that allows Web clients to fetch HTTP-based resources over HTTPX.
Definition: HttpxProxy.cs:60
override Task OPTIONS(HttpRequest Request, HttpResponse Response)
Executes the OPTIONS method on the resource.
Definition: HttpxProxy.cs:715
Task TRACE(HttpRequest Request, HttpResponse Response)
Executes the TRACE method on the resource.
Definition: HttpxProxy.cs:827
XmppServerlessMessaging ServerlessMessaging
Serverless messaging manager.
Definition: HttpxProxy.cs:107
Task POST(HttpRequest Request, HttpResponse Response)
Executes the POST method on the resource.
Definition: HttpxProxy.cs:734
Task PUT(HttpRequest Request, HttpResponse Response, ContentByteRangeInterval Interval)
Executes the ranged PUT method on the resource.
Definition: HttpxProxy.cs:777
InBandBytestreams.IbbClient IbbClient
In-band bytestream client, if supported.
Definition: HttpxProxy.cs:147
Task PUT(HttpRequest Request, HttpResponse Response)
Executes the PUT method on the resource.
Definition: HttpxProxy.cs:765
Task GET(HttpRequest Request, HttpResponse Response)
Executes the GET method on the resource.
Definition: HttpxProxy.cs:692
Task DELETE(HttpRequest Request, HttpResponse Response)
Executes the DELETE method on the resource.
Definition: HttpxProxy.cs:846
Task PATCH(HttpRequest Request, HttpResponse Response)
Executes the PATCH method on the resource.
Definition: HttpxProxy.cs:796
HttpxClient DefaultHttpxClient
Default HTTPX client.
Definition: HttpxProxy.cs:141
bool Disposed
If the proxy has been disposed.
Definition: HttpxProxy.cs:86
P2P.SOCKS5.Socks5Proxy Socks5Proxy
SOCKS5 proxy, if supported.
Definition: HttpxProxy.cs:162
IHttpxCache HttpxCache
Reference to the HTTPX Cache manager.
Definition: HttpxProxy.cs:122
Task PATCH(HttpRequest Request, HttpResponse Response, ContentByteRangeInterval Interval)
Executes the ranged PATCH method on the resource.
Definition: HttpxProxy.cs:808
HttpxProxy(string ResourceName, XmppClient DefaultXmppClient, int MaxChunkSize)
Implements a Proxy resource that allows Web clients to fetch HTTP-based resources over HTTPX.
Definition: HttpxProxy.cs:35
async Task< GetClientResponse > GetClientAsync(Uri Uri)
Gets a corresponding HttpxClient appropriate for a given request.
Definition: HttpxProxy.cs:294
override bool UserSessions
If the resource uses user sessions.
Definition: HttpxProxy.cs:188
HttpxProxy(string ResourceName, XmppClient DefaultXmppClient, int MaxChunkSize, XmppServerlessMessaging ServerlessMessaging)
Implements a Proxy resource that allows Web clients to fetch HTTP-based resources over HTTPX.
Definition: HttpxProxy.cs:47
void Dispose()
IDisposable.Dispose
Definition: HttpxProxy.cs:76
IPostResource PostResource
Post resource for responses.
Definition: HttpxProxy.cs:92
override bool HandlesSubPaths
If the resource handles sub-paths.
Definition: HttpxProxy.cs:177
Task GET(HttpRequest Request, HttpResponse Response, ByteRangeInterval FirstInterval)
Executes the ranged GET method on the resource.
Definition: HttpxProxy.cs:704
Task POST(HttpRequest Request, HttpResponse Response, ContentByteRangeInterval Interval)
Executes the ranged POST method on the resource.
Definition: HttpxProxy.cs:746
XmppClient DefaultXmppClient
Default XMPP client.
Definition: HttpxProxy.cs:136
Class sending and receiving binary streams over XMPP using XEP-0047: In-band Bytestreams: https://xmp...
Definition: IbbClient.cs:20
object State
State object passed to the original request.
XmppClient Client
XMPP client, if aquired, or null otherwise.
Class managing a SOCKS5 proxy associated with the current XMPP server.
Definition: Socks5Proxy.cs:19
Class managing peer-to-peer serveless XMPP communication.
Task GetPeerConnection(string FullJID, EventHandlerAsync< PeerConnectionEventArgs > Callback, object State)
Gets a peer XMPP connection.
Maintains information about an item in the roster.
Definition: RosterItem.cs:75
PresenceEventArgs[] Resources
Active resources utilized by contact.
Definition: RosterItem.cs:300
Manages an XMPP client connection. Implements XMPP, as defined in https://tools.ietf....
Definition: XmppClient.cs:59
static string GetBareJID(string JID)
Gets the Bare JID from a JID, which may be a Full JID.
Definition: XmppClient.cs:6901
static readonly Regex BareJidRegEx
Regular expression for Bare JIDs
Definition: XmppClient.cs:188
bool SupportsFeature(string Feature)
Checks if a feature is supported by the client.
Definition: XmppClient.cs:2993
bool TryGetTag(string TagName, out object Tag)
Tries to get a tag from the client. Tags can be used to attached application specific objects to the ...
Definition: XmppClient.cs:7207
Manages a temporary stream. Contents is kept in-memory, if below a memory threshold,...
override void Dispose(bool disposing)
Releases the unmanaged resources used by the System.IO.Stream and optionally releases the managed res...
DELETE Interface for HTTP resources.
GET Interface for HTTP resources.
Ranged GET Interface for HTTP resources.
PATCH Interface for HTTP resources.
Ranged PATCH Interface for HTTP resources.
POST Interface for HTTP resources.
Ranged POST Interface for HTTP resources.
PUT Interface for HTTP resources.
Ranged PUT Interface for HTTP resources.
TRACE Interface for HTTP resources.
Interface for HTTPX caches. HTTPX caches can improve performance by storing resources locally.
Definition: IHttpxCache.cs:11
bool CanCache(string BareJid, string LocalResource, string ContentType)
Checks if content from a remote resource can be cached.
Task< IHttpxCachedResource > TryGetCachedResource(string BareJid, string LocalResource)
Tries to get a reference to the resource from the local cache.
Task AddToCache(string BareJid, string LocalResource, string ContentType, string ETag, DateTimeOffset LastModified, DateTimeOffset? Expires, Stream Content)
Adds content to the cache.
Interface for HTTPX Cache resource items.
string FileName
Name of file of local resource.
DateTimeOffset LastModified
When resource was last modified on remote peer.
Interface for HTTP(S) Post-back resources. These can be used to allow HTTPX servers to HTTP POST back...
ContentType
DTLS Record content type.
Definition: Enumerations.cs:11