Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
InternetContent.cs
1using System;
2using System.Reflection;
3using System.Collections.Generic;
4using System.Text;
5using System.Threading.Tasks;
8using System.Security.Cryptography.X509Certificates;
10
11namespace Waher.Content
12{
16 public static class InternetContent
17 {
21 public static readonly Encoding ISO_8859_1 = Encoding.GetEncoding("ISO-8859-1");
22
23 private static string[] canEncodeContentTypes = null;
24 private static string[] canEncodeFileExtensions = null;
25 private static string[] canDecodeContentTypes = null;
26 private static string[] canDecodeFileExtensions = null;
27 private static string[] canGetUriSchemes = null;
28 private static string[] canPostToUriSchemes = null;
29 private static string[] canPutToUriSchemes = null;
30 private static string[] canDeleteToUriSchemes = null;
31 private static string[] canHeadUriSchemes = null;
32 private static IContentEncoder[] encoders = null;
33 private static IContentDecoder[] decoders = null;
34 private static IContentConverter[] converters = null;
35 private static IContentGetter[] getters = null;
36 private static IContentPoster[] posters = null;
37 private static IContentPutter[] putters = null;
38 private static IContentDeleter[] deleters = null;
39 private static IContentHeader[] headers = null;
40 private readonly static Dictionary<string, KeyValuePair<Grade, IContentDecoder>> decoderByContentType =
41 new Dictionary<string, KeyValuePair<Grade, IContentDecoder>>(StringComparer.CurrentCultureIgnoreCase);
42 private readonly static Dictionary<string, KeyValuePair<Grade, IContentEncoder>> encodersByType =
43 new Dictionary<string, KeyValuePair<Grade, IContentEncoder>>();
44 private readonly static Dictionary<string, string> contentTypeByFileExtensions = new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);
45 private readonly static Dictionary<string, string> fileExtensionsByContentType = new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);
46 private readonly static Dictionary<string, IContentConverter> convertersByStep = new Dictionary<string, IContentConverter>(StringComparer.CurrentCultureIgnoreCase);
47 private readonly static Dictionary<string, List<IContentConverter>> convertersByFrom = new Dictionary<string, List<IContentConverter>>();
48 private readonly static Dictionary<string, IContentGetter[]> gettersByScheme = new Dictionary<string, IContentGetter[]>(StringComparer.CurrentCultureIgnoreCase);
49 private readonly static Dictionary<string, IContentPoster[]> postersByScheme = new Dictionary<string, IContentPoster[]>(StringComparer.CurrentCultureIgnoreCase);
50 private readonly static Dictionary<string, IContentPutter[]> puttersByScheme = new Dictionary<string, IContentPutter[]>(StringComparer.CurrentCultureIgnoreCase);
51 private readonly static Dictionary<string, IContentDeleter[]> deletersByScheme = new Dictionary<string, IContentDeleter[]>(StringComparer.CurrentCultureIgnoreCase);
52 private readonly static Dictionary<string, IContentHeader[]> headersByScheme = new Dictionary<string, IContentHeader[]>(StringComparer.CurrentCultureIgnoreCase);
53
54 static InternetContent()
55 {
56 Types.OnInvalidated += Types_OnInvalidated;
57 }
58
59 private static void Types_OnInvalidated(object Sender, EventArgs e)
60 {
61 canEncodeContentTypes = null;
62 canEncodeFileExtensions = null;
63 canDecodeContentTypes = null;
64 canDecodeFileExtensions = null;
65 canGetUriSchemes = null;
66 encoders = null;
67 decoders = null;
68 converters = null;
69 getters = null;
70 headers = null;
71 posters = null;
72 putters = null;
73 deleters = null;
74
75 lock (decoderByContentType)
76 {
77 decoderByContentType.Clear();
78 }
79
80 lock (encodersByType)
81 {
82 encodersByType.Clear();
83 }
84
85 lock (contentTypeByFileExtensions)
86 {
87 contentTypeByFileExtensions.Clear();
88 }
89
90 lock (fileExtensionsByContentType)
91 {
92 fileExtensionsByContentType.Clear();
93 }
94
95 lock (convertersByStep)
96 {
97 convertersByStep.Clear();
98 convertersByFrom.Clear();
99 }
100
101 lock (gettersByScheme)
102 {
103 gettersByScheme.Clear();
104 }
105
106 lock (headersByScheme)
107 {
108 headersByScheme.Clear();
109 }
110
111 lock (postersByScheme)
112 {
113 postersByScheme.Clear();
114 }
115
116 lock (puttersByScheme)
117 {
118 puttersByScheme.Clear();
119 }
120
121 lock (deletersByScheme)
122 {
123 deletersByScheme.Clear();
124 }
125 }
126
127 #region Encoding
128
132 public static string[] CanEncodeContentTypes
133 {
134 get
135 {
136 if (canEncodeContentTypes is null)
137 {
138 SortedDictionary<string, bool> ContentTypes = new SortedDictionary<string, bool>();
139
140 foreach (IContentEncoder Encoder in Encoders)
141 {
142 foreach (string ContentType in Encoder.ContentTypes)
143 ContentTypes[ContentType] = true;
144 }
145
146 string[] Types = new string[ContentTypes.Count];
147 ContentTypes.Keys.CopyTo(Types, 0);
148
149 canEncodeContentTypes = Types;
150 }
151
152 return canEncodeContentTypes;
153 }
154 }
155
159 public static string[] CanEncodeFileExtensions
160 {
161 get
162 {
163 if (canEncodeFileExtensions is null)
164 {
165 SortedDictionary<string, bool> FileExtensions = new SortedDictionary<string, bool>();
166
167 foreach (IContentEncoder Encoder in Encoders)
168 {
169 foreach (string FileExtension in Encoder.FileExtensions)
170 FileExtensions[FileExtension] = true;
171 }
172
173 string[] Types = new string[FileExtensions.Count];
174 FileExtensions.Keys.CopyTo(Types, 0);
175
176 canEncodeFileExtensions = Types;
177 }
178
179 return canEncodeFileExtensions;
180 }
181 }
182
186 public static IContentEncoder[] Encoders
187 {
188 get
189 {
190 if (encoders is null)
191 {
192 List<IContentEncoder> Encoders = new List<IContentEncoder>();
193 IContentEncoder Encoder;
194 Type[] EncoderTypes = Types.GetTypesImplementingInterface(typeof(IContentEncoder));
195
196 foreach (Type T in EncoderTypes)
197 {
198 ConstructorInfo CI = Types.GetDefaultConstructor(T);
199 if (CI is null)
200 continue;
201
202 try
203 {
204 Encoder = (IContentEncoder)CI.Invoke(Types.NoParameters);
205 }
206 catch (Exception)
207 {
208 continue;
209 }
210
211 Encoders.Add(Encoder);
212 }
213
214 encoders = Encoders.ToArray();
215 }
216
217 return encoders;
218 }
219 }
220
229 public static bool Encodes(object Object, out Grade Grade, out IContentEncoder Encoder, params string[] AcceptedContentTypes)
230 {
231 string Key;
232
233 if (AcceptedContentTypes is null || AcceptedContentTypes.Length == 0)
234 Key = Object.GetType().FullName;
235 else
236 {
237 StringBuilder sb = new StringBuilder();
238
239 sb.Append(Object.GetType().FullName);
240
241 foreach (string Accepted in AcceptedContentTypes)
242 {
243 sb.Append('|');
244 sb.Append(Accepted);
245 }
246
247 Key = sb.ToString();
248 }
249
250 lock (encodersByType)
251 {
252 if (encodersByType.TryGetValue(Key, out KeyValuePair<Grade, IContentEncoder> P))
253 {
254 Grade = P.Key;
255 Encoder = P.Value;
256
257 if (!(Encoder is null))
258 return true;
259
260 if (Object is CustomEncoding)
261 {
262 Encoder = new CustomEncoder();
263 return true;
264 }
265
266 return false;
267 }
268 }
269
270 Grade = Grade.NotAtAll;
271 Encoder = null;
272
273 foreach (IContentEncoder Encoder2 in Encoders)
274 {
275 if (Encoder2.Encodes(Object, out Grade Grade2, AcceptedContentTypes) && Grade2 > Grade)
276 {
277 Grade = Grade2;
278 Encoder = Encoder2;
279 }
280 }
281
282 lock (encodersByType)
283 {
284 encodersByType[Key] = new KeyValuePair<Grade, IContentEncoder>(Grade, Encoder);
285 }
286
287 if (!(Encoder is null))
288 return true;
289
290 if (Object is CustomEncoding)
291 {
292 Encoder = new CustomEncoder();
293 return true;
294 }
295
296 return false;
297 }
298
308 [Obsolete("Use the EncodeAsync method for more efficient processing of content including asynchronous processing elements in parallel environments.")]
309 public static byte[] Encode(object Object, Encoding Encoding, out string ContentType, params string[] AcceptedContentTypes)
310 {
311 KeyValuePair<byte[], string> P = EncodeAsync(Object, Encoding, AcceptedContentTypes).Result;
312 ContentType = P.Value;
313 return P.Key;
314 }
315
324 public static Task<KeyValuePair<byte[], string>> EncodeAsync(object Object, Encoding Encoding, params string[] AcceptedContentTypes)
325 {
326 if (!Encodes(Object, out Grade _, out IContentEncoder Encoder, AcceptedContentTypes))
327 throw new ArgumentException("No encoder found to encode objects of type " + (Object?.GetType()?.FullName) + ".", nameof(Object));
328
329 return Encoder.EncodeAsync(Object, Encoding);
330 }
331
337 public static bool IsAccepted(string ContentType, params string[] AcceptedContentTypes)
338 {
339 if (AcceptedContentTypes.Length == 0)
340 return true;
341 else
342 return Array.IndexOf(AcceptedContentTypes, ContentType) >= 0;
343 }
344
350 public static bool IsAccepted(string[] ContentTypes, params string[] AcceptedContentTypes)
351 {
352 return IsAccepted(ContentTypes, out string _, AcceptedContentTypes);
353 }
354
361 public static bool IsAccepted(string[] ContentTypes, out string ContentType, params string[] AcceptedContentTypes)
362 {
363 if (ContentTypes.Length == 0)
364 throw new ArgumentException("Empty list of content types not permitted.", nameof(ContentTypes));
365
366 if ((AcceptedContentTypes?.Length ?? 0) == 0)
367 {
368 ContentType = ContentTypes[0];
369 return true;
370 }
371
372 foreach (string ContentType2 in ContentTypes)
373 {
374 if (IsAccepted(ContentType2, AcceptedContentTypes))
375 {
376 ContentType = ContentType2;
377 return true;
378 }
379 }
380
381 ContentType = null;
382 return false;
383 }
384
385 #endregion
386
387 #region Decoding
388
392 public static string[] CanDecodeContentTypes
393 {
394 get
395 {
396 if (canDecodeContentTypes is null)
397 {
398 SortedDictionary<string, bool> ContentTypes = new SortedDictionary<string, bool>();
399
400 foreach (IContentDecoder Decoder in Decoders)
401 {
402 foreach (string ContentType in Decoder.ContentTypes)
403 ContentTypes[ContentType] = true;
404 }
405
406 string[] Types = new string[ContentTypes.Count];
407 ContentTypes.Keys.CopyTo(Types, 0);
408
409 canDecodeContentTypes = Types;
410 }
411
412 return canDecodeContentTypes;
413 }
414 }
415
419 public static string[] CanDecodeFileExtensions
420 {
421 get
422 {
423 if (canDecodeFileExtensions is null)
424 {
425 SortedDictionary<string, bool> FileExtensions = new SortedDictionary<string, bool>();
426
427 foreach (IContentDecoder Decoder in Decoders)
428 {
429 foreach (string FileExtension in Decoder.FileExtensions)
430 FileExtensions[FileExtension] = true;
431 }
432
433 string[] Types = new string[FileExtensions.Count];
434 FileExtensions.Keys.CopyTo(Types, 0);
435
436 canDecodeFileExtensions = Types;
437 }
438
439 return canDecodeFileExtensions;
440 }
441 }
442
446 public static IContentDecoder[] Decoders
447 {
448 get
449 {
450 if (decoders is null)
451 {
452 List<IContentDecoder> Decoders = new List<IContentDecoder>();
453 IContentDecoder Decoder;
454 Type[] DecoderTypes = Types.GetTypesImplementingInterface(typeof(IContentDecoder));
455
456 foreach (Type T in DecoderTypes)
457 {
458 ConstructorInfo CI = Types.GetDefaultConstructor(T);
459 if (CI is null)
460 continue;
461
462 try
463 {
464 Decoder = (IContentDecoder)CI.Invoke(Types.NoParameters);
465 }
466 catch (Exception)
467 {
468 continue;
469 }
470
471 Decoders.Add(Decoder);
472 }
473
474 decoders = Decoders.ToArray();
475 }
476
477 return decoders;
478 }
479 }
480
488 public static bool Decodes(string ContentType, out Grade Grade, out IContentDecoder Decoder)
489 {
490 lock (decoderByContentType)
491 {
492 if (decoderByContentType.TryGetValue(ContentType, out KeyValuePair<Grade, IContentDecoder> P))
493 {
494 Grade = P.Key;
495 Decoder = P.Value;
496
497 return !(Decoder is null);
498 }
499 }
500
501 Grade = Grade.NotAtAll;
502 Decoder = null;
503
504 foreach (IContentDecoder Decoder2 in Decoders)
505 {
506 if (Decoder2.Decodes(ContentType, out Grade Grade2) && Grade2 > Grade)
507 {
508 Grade = Grade2;
509 Decoder = Decoder2;
510 }
511 }
512
513 lock (decoderByContentType)
514 {
515 decoderByContentType[ContentType] = new KeyValuePair<Grade, IContentDecoder>(Grade, Decoder);
516 }
517
518 return !(Decoder is null);
519 }
520
531 [Obsolete("Use the DecoceAsync method for more efficient processing of content including asynchronous processing elements in parallel environments.")]
532 public static object Decode(string ContentType, byte[] Data, Encoding Encoding, KeyValuePair<string, string>[] Fields, Uri BaseUri)
533 {
534 return DecodeAsync(ContentType, Data, Encoding, Fields, BaseUri).Result;
535 }
536
547 public static Task<object> DecodeAsync(string ContentType, byte[] Data, Encoding Encoding, KeyValuePair<string, string>[] Fields, Uri BaseUri)
548 {
549 if (!Decodes(ContentType, out Grade _, out IContentDecoder Decoder))
550 throw new ArgumentException("No decoder found to decode objects of type " + ContentType + ".", nameof(ContentType));
551
552 return Decoder.DecodeAsync(ContentType, Data, Encoding, Fields, BaseUri);
553 }
554
563 [Obsolete("Use the DecoceAsync method for more efficient processing of content including asynchronous processing elements in parallel environments.")]
564 public static object Decode(string ContentType, byte[] Data, Uri BaseUri)
565 {
566 return DecodeAsync(ContentType, Data, BaseUri).Result;
567 }
568
577 public static Task<object> DecodeAsync(string ContentType, byte[] Data, Uri BaseUri)
578 {
579 Encoding Encoding = null;
580 KeyValuePair<string, string>[] Fields;
581 int i;
582
583 i = ContentType.IndexOf(';');
584 if (i > 0)
585 {
586 Fields = CommonTypes.ParseFieldValues(ContentType.Substring(i + 1).TrimStart());
587 ContentType = ContentType.Substring(0, i).TrimEnd();
588
589 foreach (KeyValuePair<string, string> Field in Fields)
590 {
591 if (string.Compare(Field.Key, "CHARSET", true) == 0)
592 Encoding = GetEncoding(Field.Value);
593 }
594 }
595 else
596 Fields = new KeyValuePair<string, string>[0];
597
598 return DecodeAsync(ContentType, Data, Encoding, Fields, BaseUri);
599 }
600
606 public static Encoding GetEncoding(string CharacterSet)
607 {
608 if (string.IsNullOrEmpty(CharacterSet))
609 return null;
610
611 // Reference: http://www.iana.org/assignments/character-sets/character-sets.xhtml
612 switch (CharacterSet.ToUpper())
613 {
614 case "ASCII":
615 case "US-ASCII":
616 return Encoding.ASCII;
617
618 case "UTF-16LE":
619 case "UTF-16":
620 return Encoding.Unicode;
621
622 case "UTF-16BE":
623 return Encoding.BigEndianUnicode;
624
625 case "UTF-32":
626 case "UTF-32LE":
627 return Encoding.UTF32;
628
629 case "UNICODE-1-1-UTF-7":
630 case "UTF-7":
631 return Encoding.UTF7;
632
633 case "UTF-8":
634 return Encoding.UTF8;
635
636 default:
637 return Encoding.GetEncoding(CharacterSet);
638 }
639 }
640
641 #endregion
642
643 #region File extensions
644
652 public static string GetContentType(string FileExtension)
653 {
654 if (TryGetContentType(FileExtension, out string ContentType))
655 return ContentType;
656 else
658 }
659
666 public static bool TryGetContentType(string FileExtension, out string ContentType)
667 {
668 FileExtension = FileExtension.ToLower();
669 if (FileExtension.StartsWith("."))
670 FileExtension = FileExtension.Substring(1);
671
672 lock (contentTypeByFileExtensions)
673 {
674 if (contentTypeByFileExtensions.TryGetValue(FileExtension, out ContentType))
675 return true;
676 }
677
678 foreach (IContentDecoder Decoder in Decoders)
679 {
680 if (Decoder.TryGetContentType(FileExtension, out ContentType))
681 {
682 lock (contentTypeByFileExtensions)
683 {
684 contentTypeByFileExtensions[FileExtension] = ContentType;
685 }
686
687 return true;
688 }
689 }
690
691 foreach (IContentEncoder Encoder in Encoders)
692 {
693 if (Encoder.TryGetContentType(FileExtension, out ContentType))
694 {
695 lock (contentTypeByFileExtensions)
696 {
697 contentTypeByFileExtensions[FileExtension] = ContentType;
698 }
699
700 return true;
701 }
702 }
703
704 return false;
705 }
706
714 public static string GetFileExtension(string ContentType)
715 {
716 if (TryGetFileExtension(ContentType, out string FileExtension))
717 return FileExtension;
718 else
719 return "bin";
720 }
721
728 public static bool TryGetFileExtension(string ContentType, out string FileExtension)
729 {
730 ContentType = ContentType.ToLower();
731
732 lock (fileExtensionsByContentType)
733 {
734 if (fileExtensionsByContentType.TryGetValue(ContentType, out FileExtension))
735 return true;
736 }
737
738 foreach (IContentDecoder Decoder in Decoders)
739 {
740 if (Decoder.TryGetFileExtension(ContentType, out FileExtension))
741 {
742 lock (fileExtensionsByContentType)
743 {
744 fileExtensionsByContentType[ContentType] = FileExtension;
745 }
746
747 return true;
748 }
749 }
750
751 foreach (IContentEncoder Encoder in Encoders)
752 {
753 if (Encoder.TryGetFileExtension(ContentType, out FileExtension))
754 {
755 lock (fileExtensionsByContentType)
756 {
757 fileExtensionsByContentType[ContentType] = FileExtension;
758 }
759
760 return true;
761 }
762 }
763
764 return false;
765 }
766
767 #endregion
768
769 #region Content Conversion
770
771
776 {
777 get
778 {
779 if (converters is null)
780 FindConverters();
781
782 return converters;
783 }
784 }
785
797 public static bool CanConvert(string FromContentType, string ToContentType, out IContentConverter Converter)
798 {
799 lock (convertersByStep)
800 {
801 if (converters is null)
802 FindConverters();
803
804 string PathKey = FromContentType + " -> " + ToContentType;
805 if (convertersByStep.TryGetValue(PathKey, out Converter))
806 return !(Converter is null);
807
808 if (!convertersByFrom.TryGetValue(FromContentType, out List<IContentConverter> Converters))
809 return false;
810
811 LinkedList<ConversionStep> Queue = new LinkedList<ConversionStep>();
812 ConversionStep Step;
813
814 foreach (IContentConverter C in Converters)
815 {
816 Step = new ConversionStep()
817 {
818 From = FromContentType,
819 Converter = C,
820 TotalGrade = C.ConversionGrade,
821 Prev = null,
822 Distance = 1
823 };
824
825 Queue.AddLast(Step);
826 }
827
828 Dictionary<string, ConversionStep> Possibilities = new Dictionary<string, ConversionStep>();
829 ConversionStep Best = null;
830 Grade BestGrade = Grade.NotAtAll;
831 int BestDistance = int.MaxValue;
832 Grade StepGrade;
833 int StepDistance;
834 bool First;
835
836 while (!(Queue.First is null))
837 {
838 Step = Queue.First.Value;
839 Queue.RemoveFirst();
840
841 StepDistance = Step.Distance + 1;
842 StepGrade = Step.Converter.ConversionGrade;
843 if (Step.TotalGrade < StepGrade)
844 StepGrade = Step.TotalGrade;
845
846 foreach (string To in Step.Converter.ToContentTypes)
847 {
848 if (string.Compare(To, ToContentType, true) == 0 || To == "*")
849 {
850 if (StepGrade > BestGrade || StepGrade == BestGrade && StepDistance < BestDistance)
851 {
852 Best = Step;
853 BestGrade = StepGrade;
854 BestDistance = StepDistance;
855 }
856 }
857 else
858 {
859 if (Possibilities.TryGetValue(To, out ConversionStep NextStep) && NextStep.TotalGrade >= StepGrade && NextStep.Distance <= StepDistance)
860 continue;
861
862 if (!convertersByFrom.TryGetValue(To, out Converters))
863 continue;
864
865 First = true;
866 foreach (IContentConverter C in Converters)
867 {
868 NextStep = new ConversionStep()
869 {
870 From = To,
871 Converter = C,
872 TotalGrade = StepGrade,
873 Prev = Step,
874 Distance = StepDistance
875 };
876
877 if (First)
878 {
879 Possibilities[To] = NextStep;
880 First = false;
881 }
882
883 Queue.AddLast(NextStep);
884 }
885 }
886 }
887 }
888
889 if (!(Best is null))
890 {
891 List<KeyValuePair<string, IContentConverter>> List = new List<KeyValuePair<string, IContentConverter>>();
892
893 while (!(Best is null))
894 {
895 List.Insert(0, new KeyValuePair<string, IContentConverter>(Best.From, Best.Converter));
896 Best = Best.Prev;
897 }
898
899 Converter = new ConversionSequence(FromContentType, ToContentType, BestGrade, List.ToArray());
900 convertersByStep[PathKey] = Converter;
901 return true;
902 }
903 else
904 {
905 convertersByStep[PathKey] = null;
906 Converter = null;
907 return false;
908 }
909 }
910 }
911
912 private class ConversionStep
913 {
914 public IContentConverter Converter;
915 public Grade TotalGrade;
916 public ConversionStep Prev;
917 public string From;
918 public int Distance;
919 }
920
921 private static void FindConverters()
922 {
923 List<IContentConverter> Converters = new List<IContentConverter>();
924 IContentConverter Converter;
925 Type[] ConverterTypes = Types.GetTypesImplementingInterface(typeof(IContentConverter));
926
927 convertersByStep.Clear();
928 convertersByFrom.Clear();
929
930 lock (convertersByStep)
931 {
932 foreach (Type T in ConverterTypes)
933 {
934 ConstructorInfo CI = Types.GetDefaultConstructor(T);
935 if (CI is null)
936 continue;
937
938 try
939 {
940 Converter = (IContentConverter)CI.Invoke(Types.NoParameters);
941 }
942 catch (Exception)
943 {
944 continue;
945 }
946
947 Converters.Add(Converter);
948
949 foreach (string From in Converter.FromContentTypes)
950 {
951 if (!convertersByFrom.TryGetValue(From, out List<IContentConverter> List))
952 {
953 List = new List<IContentConverter>();
954 convertersByFrom[From] = List;
955 }
956
957 List.Add(Converter);
958
959 foreach (string To in Converter.ToContentTypes)
960 {
961 if (To != "*")
962 convertersByStep[From + " -> " + To] = Converter;
963 }
964 }
965 }
966 }
967
968 converters = Converters.ToArray();
969 }
970
976 public static IContentConverter[] GetConverters(string FromContentType)
977 {
978 lock (convertersByStep)
979 {
980 if (converters is null)
981 FindConverters();
982
983 if (!convertersByFrom.TryGetValue(FromContentType, out List<IContentConverter> Converters))
984 return null;
985
986 return Converters.ToArray();
987 }
988 }
989
990 #endregion
991
992 #region Getting resources
993
997 public static string[] CanGetUriSchemes
998 {
999 get
1000 {
1001 if (canGetUriSchemes is null)
1002 {
1003 SortedDictionary<string, bool> UriSchemes = new SortedDictionary<string, bool>();
1004
1005 foreach (IContentGetter Getter in Getters)
1006 {
1007 foreach (string Scheme in Getter.UriSchemes)
1008 UriSchemes[Scheme] = true;
1009 }
1010
1011 string[] Schemes = new string[UriSchemes.Count];
1012 UriSchemes.Keys.CopyTo(Schemes, 0);
1013
1014 canGetUriSchemes = Schemes;
1015 }
1016
1017 return canGetUriSchemes;
1018 }
1019 }
1020
1024 public static IContentGetter[] Getters
1025 {
1026 get
1027 {
1028 if (getters is null)
1029 BuildGetters();
1030
1031 return getters;
1032 }
1033 }
1034
1035 private static void BuildGetters()
1036 {
1037 List<IContentGetter> Getters = new List<IContentGetter>();
1038 Type[] GetterTypes = Types.GetTypesImplementingInterface(typeof(IContentGetter));
1039 Dictionary<string, List<IContentGetter>> ByScheme = new Dictionary<string, List<IContentGetter>>();
1040 IContentGetter Getter;
1041
1042 foreach (Type T in GetterTypes)
1043 {
1044 ConstructorInfo CI = Types.GetDefaultConstructor(T);
1045 if (CI is null)
1046 continue;
1047
1048 try
1049 {
1050 Getter = (IContentGetter)CI.Invoke(Types.NoParameters);
1051 }
1052 catch (Exception)
1053 {
1054 continue;
1055 }
1056
1057 Getters.Add(Getter);
1058
1059 foreach (string Schema in Getter.UriSchemes)
1060 {
1061 if (!ByScheme.TryGetValue(Schema, out List<IContentGetter> List))
1062 {
1063 List = new List<IContentGetter>();
1064 ByScheme[Schema] = List;
1065 }
1066
1067 List.Add(Getter);
1068 }
1069 }
1070
1071 lock (gettersByScheme)
1072 {
1073 foreach (KeyValuePair<string, List<IContentGetter>> P in ByScheme)
1074 gettersByScheme[P.Key] = P.Value.ToArray();
1075 }
1076
1077 getters = Getters.ToArray();
1078 }
1079
1087 public static bool CanGet(Uri Uri, out Grade Grade, out IContentGetter Getter)
1088 {
1089 if (Uri is null)
1090 throw new ArgumentNullException("URI cannot be null.", nameof(Uri));
1091
1092 if (getters is null)
1093 BuildGetters();
1094
1096
1097 lock (gettersByScheme)
1098 {
1099 if (Uri is null || !gettersByScheme.TryGetValue(Uri.Scheme, out Getters))
1100 {
1101 Getter = null;
1102 Grade = Grade.NotAtAll;
1103 return false;
1104 }
1105 }
1106
1107 Grade = Grade.NotAtAll;
1108 Getter = null;
1109
1110 foreach (IContentGetter Getter2 in Getters)
1111 {
1112 if (Getter2.CanGet(Uri, out Grade Grade2) && Grade2 > Grade)
1113 {
1114 Grade = Grade2;
1115 Getter = Getter2;
1116 }
1117 }
1118
1119 return !(Getter is null);
1120 }
1121
1128 public static Task<object> GetAsync(Uri Uri, params KeyValuePair<string, string>[] Headers)
1129 {
1130 return GetAsync(Uri, null, null, Headers);
1131 }
1132
1140 public static Task<object> GetAsync(Uri Uri, X509Certificate Certificate, params KeyValuePair<string, string>[] Headers)
1141 {
1142 return GetAsync(Uri, Certificate, null, Headers);
1143 }
1144
1153 public static Task<object> GetAsync(Uri Uri, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator,
1154 params KeyValuePair<string, string>[] Headers)
1155 {
1156 if (!CanGet(Uri, out Grade _, out IContentGetter Getter))
1157 throw new ArgumentException("URI Scheme not recognized (GET): " + Uri.Scheme, nameof(Uri));
1158
1159 return Getter.GetAsync(Uri, Certificate, RemoteCertificateValidator, Headers);
1160 }
1161
1169 public static Task<object> GetAsync(Uri Uri, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1170 {
1171 return GetAsync(Uri, null, null, TimeoutMs, Headers);
1172 }
1173
1182 public static Task<object> GetAsync(Uri Uri, X509Certificate Certificate, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1183 {
1184 return GetAsync(Uri, Certificate, null, TimeoutMs, Headers);
1185 }
1186
1196 public static Task<object> GetAsync(Uri Uri, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator,
1197 int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1198 {
1199 if (!CanGet(Uri, out Grade _, out IContentGetter Getter))
1200 throw new ArgumentException("URI Scheme not recognized (GET): " + Uri.Scheme, nameof(Uri));
1201
1202 return Getter.GetAsync(Uri, Certificate, RemoteCertificateValidator, TimeoutMs, Headers);
1203 }
1204
1211 public static Task<KeyValuePair<string, TemporaryStream>> GetTempStreamAsync(Uri Uri, params KeyValuePair<string, string>[] Headers)
1212 {
1213 return GetTempStreamAsync(Uri, null, null, Headers);
1214 }
1215
1223 public static Task<KeyValuePair<string, TemporaryStream>> GetTempStreamAsync(Uri Uri, X509Certificate Certificate, params KeyValuePair<string, string>[] Headers)
1224 {
1225 return GetTempStreamAsync(Uri, Certificate, null, Headers);
1226 }
1227
1236 public static Task<KeyValuePair<string, TemporaryStream>> GetTempStreamAsync(Uri Uri, X509Certificate Certificate,
1237 RemoteCertificateEventHandler RemoteCertificateValidator, params KeyValuePair<string, string>[] Headers)
1238 {
1239 if (!CanGet(Uri, out Grade _, out IContentGetter Getter))
1240 throw new ArgumentException("URI Scheme not recognized (GET): " + Uri.Scheme, nameof(Uri));
1241
1242 return Getter.GetTempStreamAsync(Uri, Certificate, RemoteCertificateValidator, Headers);
1243 }
1244
1252 public static Task<KeyValuePair<string, TemporaryStream>> GetTempStreamAsync(Uri Uri, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1253 {
1254 return GetTempStreamAsync(Uri, null, null, TimeoutMs, Headers);
1255 }
1256
1265 public static Task<KeyValuePair<string, TemporaryStream>> GetTempStreamAsync(Uri Uri, X509Certificate Certificate, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1266 {
1267 return GetTempStreamAsync(Uri, Certificate, null, TimeoutMs, Headers);
1268 }
1269
1279 public static Task<KeyValuePair<string, TemporaryStream>> GetTempStreamAsync(Uri Uri, X509Certificate Certificate,
1280 RemoteCertificateEventHandler RemoteCertificateValidator, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1281 {
1282 if (!CanGet(Uri, out Grade _, out IContentGetter Getter))
1283 throw new ArgumentException("URI Scheme not recognized (GET): " + Uri.Scheme, nameof(Uri));
1284
1285 return Getter.GetTempStreamAsync(Uri, Certificate, RemoteCertificateValidator, TimeoutMs, Headers);
1286 }
1287
1288 #endregion
1289
1290 #region Posting to resources
1291
1295 public static string[] CanPostToUriSchemes
1296 {
1297 get
1298 {
1299 if (canPostToUriSchemes is null)
1300 {
1301 SortedDictionary<string, bool> UriSchemes = new SortedDictionary<string, bool>();
1302
1303 foreach (IContentPoster Poster in Posters)
1304 {
1305 foreach (string Scheme in Poster.UriSchemes)
1306 UriSchemes[Scheme] = true;
1307 }
1308
1309 string[] Schemes = new string[UriSchemes.Count];
1310 UriSchemes.Keys.CopyTo(Schemes, 0);
1311
1312 canPostToUriSchemes = Schemes;
1313 }
1314
1315 return canPostToUriSchemes;
1316 }
1317 }
1318
1322 public static IContentPoster[] Posters
1323 {
1324 get
1325 {
1326 if (posters is null)
1327 BuildPosters();
1328
1329 return posters;
1330 }
1331 }
1332
1333 private static void BuildPosters()
1334 {
1335 List<IContentPoster> Posters = new List<IContentPoster>();
1336 Type[] PosterTypes = Types.GetTypesImplementingInterface(typeof(IContentPoster));
1337 Dictionary<string, List<IContentPoster>> ByScheme = new Dictionary<string, List<IContentPoster>>();
1338 IContentPoster Poster;
1339
1340 foreach (Type T in PosterTypes)
1341 {
1342 ConstructorInfo CI = Types.GetDefaultConstructor(T);
1343 if (CI is null)
1344 continue;
1345
1346 try
1347 {
1348 Poster = (IContentPoster)CI.Invoke(Types.NoParameters);
1349 }
1350 catch (Exception)
1351 {
1352 continue;
1353 }
1354
1355 Posters.Add(Poster);
1356
1357 foreach (string Schema in Poster.UriSchemes)
1358 {
1359 if (!ByScheme.TryGetValue(Schema, out List<IContentPoster> List))
1360 {
1361 List = new List<IContentPoster>();
1362 ByScheme[Schema] = List;
1363 }
1364
1365 List.Add(Poster);
1366 }
1367 }
1368
1369 lock (postersByScheme)
1370 {
1371 foreach (KeyValuePair<string, List<IContentPoster>> P in ByScheme)
1372 postersByScheme[P.Key] = P.Value.ToArray();
1373 }
1374
1375 posters = Posters.ToArray();
1376 }
1377
1385 public static bool CanPost(Uri Uri, out Grade Grade, out IContentPoster Poster)
1386 {
1387 if (Uri is null)
1388 throw new ArgumentNullException("URI cannot be null.", nameof(Uri));
1389
1390 if (posters is null)
1391 BuildPosters();
1392
1394
1395 lock (postersByScheme)
1396 {
1397 if (Uri is null || !postersByScheme.TryGetValue(Uri.Scheme, out Posters))
1398 {
1399 Poster = null;
1400 Grade = Grade.NotAtAll;
1401 return false;
1402 }
1403 }
1404
1405 Grade = Grade.NotAtAll;
1406 Poster = null;
1407
1408 foreach (IContentPoster Poster2 in Posters)
1409 {
1410 if (Poster2.CanPost(Uri, out Grade Grade2) && Grade2 > Grade)
1411 {
1412 Grade = Grade2;
1413 Poster = Poster2;
1414 }
1415 }
1416
1417 return !(Poster is null);
1418 }
1419
1427 public static Task<object> PostAsync(Uri Uri, object Data, params KeyValuePair<string, string>[] Headers)
1428 {
1429 return PostAsync(Uri, Data, null, null, Headers);
1430 }
1431
1440 public static Task<object> PostAsync(Uri Uri, object Data, X509Certificate Certificate, params KeyValuePair<string, string>[] Headers)
1441 {
1442 return PostAsync(Uri, Data, Certificate, null, Headers);
1443 }
1444
1454 public static Task<object> PostAsync(Uri Uri, object Data, X509Certificate Certificate,
1455 RemoteCertificateEventHandler RemoteCertificateValidator, params KeyValuePair<string, string>[] Headers)
1456 {
1457 if (!CanPost(Uri, out Grade _, out IContentPoster Poster))
1458 throw new ArgumentException("URI Scheme not recognized (POST): " + Uri.Scheme, nameof(Uri));
1459
1460 return Poster.PostAsync(Uri, Data, Certificate, RemoteCertificateValidator, Headers);
1461 }
1462
1471 public static Task<object> PostAsync(Uri Uri, object Data, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1472 {
1473 return PostAsync(Uri, Data, null, null, TimeoutMs, Headers);
1474 }
1475
1485 public static Task<object> PostAsync(Uri Uri, object Data, X509Certificate Certificate, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1486 {
1487 return PostAsync(Uri, Data, Certificate, null, TimeoutMs, Headers);
1488 }
1489
1500 public static Task<object> PostAsync(Uri Uri, object Data, X509Certificate Certificate,
1501 RemoteCertificateEventHandler RemoteCertificateValidator, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1502 {
1503 if (!CanPost(Uri, out Grade _, out IContentPoster Poster))
1504 throw new ArgumentException("URI Scheme not recognized (POST): " + Uri.Scheme, nameof(Uri));
1505
1506 return Poster.PostAsync(Uri, Data, Certificate, RemoteCertificateValidator, TimeoutMs, Headers);
1507 }
1508
1517 public static Task<KeyValuePair<byte[], string>> PostAsync(Uri Uri, byte[] EncodedData, string ContentType, params KeyValuePair<string, string>[] Headers)
1518 {
1519 return PostAsync(Uri, EncodedData, ContentType, null, null, Headers);
1520 }
1521
1531 public static Task<KeyValuePair<byte[], string>> PostAsync(Uri Uri, byte[] EncodedData, string ContentType,
1532 X509Certificate Certificate, params KeyValuePair<string, string>[] Headers)
1533 {
1534 return PostAsync(Uri, EncodedData, ContentType, Certificate, null, Headers);
1535 }
1536
1547 public static Task<KeyValuePair<byte[], string>> PostAsync(Uri Uri, byte[] EncodedData, string ContentType,
1548 X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, params KeyValuePair<string, string>[] Headers)
1549 {
1550 if (!CanPost(Uri, out Grade _, out IContentPoster Poster))
1551 throw new ArgumentException("URI Scheme not recognized (POST): " + Uri.Scheme, nameof(Uri));
1552
1553 return Poster.PostAsync(Uri, EncodedData, ContentType, Certificate, RemoteCertificateValidator, Headers);
1554 }
1555
1565 public static Task<KeyValuePair<byte[], string>> PostAsync(Uri Uri, byte[] EncodedData, string ContentType, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1566 {
1567 return PostAsync(Uri, EncodedData, ContentType, null, null, TimeoutMs, Headers);
1568 }
1569
1580 public static Task<KeyValuePair<byte[], string>> PostAsync(Uri Uri, byte[] EncodedData, string ContentType,
1581 X509Certificate Certificate, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1582 {
1583 return PostAsync(Uri, EncodedData, ContentType, Certificate, null, TimeoutMs, Headers);
1584 }
1585
1597 public static Task<KeyValuePair<byte[], string>> PostAsync(Uri Uri, byte[] EncodedData, string ContentType,
1598 X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, int TimeoutMs,
1599 params KeyValuePair<string, string>[] Headers)
1600 {
1601 if (!CanPost(Uri, out Grade _, out IContentPoster Poster))
1602 throw new ArgumentException("URI Scheme not recognized (POST): " + Uri.Scheme, nameof(Uri));
1603
1604 return Poster.PostAsync(Uri, EncodedData, ContentType, Certificate, RemoteCertificateValidator, TimeoutMs, Headers);
1605 }
1606
1607 #endregion
1608
1609 #region Putting to resources
1610
1614 public static string[] CanPutToUriSchemes
1615 {
1616 get
1617 {
1618 if (canPutToUriSchemes is null)
1619 {
1620 SortedDictionary<string, bool> UriSchemes = new SortedDictionary<string, bool>();
1621
1622 foreach (IContentPutter Putter in Putters)
1623 {
1624 foreach (string Scheme in Putter.UriSchemes)
1625 UriSchemes[Scheme] = true;
1626 }
1627
1628 string[] Schemes = new string[UriSchemes.Count];
1629 UriSchemes.Keys.CopyTo(Schemes, 0);
1630
1631 canPutToUriSchemes = Schemes;
1632 }
1633
1634 return canPutToUriSchemes;
1635 }
1636 }
1637
1641 public static IContentPutter[] Putters
1642 {
1643 get
1644 {
1645 if (putters is null)
1646 BuildPutters();
1647
1648 return putters;
1649 }
1650 }
1651
1652 private static void BuildPutters()
1653 {
1654 List<IContentPutter> Putters = new List<IContentPutter>();
1655 Type[] PutterTypes = Types.GetTypesImplementingInterface(typeof(IContentPutter));
1656 Dictionary<string, List<IContentPutter>> ByScheme = new Dictionary<string, List<IContentPutter>>();
1657 IContentPutter Putter;
1658
1659 foreach (Type T in PutterTypes)
1660 {
1661 ConstructorInfo CI = Types.GetDefaultConstructor(T);
1662 if (CI is null)
1663 continue;
1664
1665 try
1666 {
1667 Putter = (IContentPutter)CI.Invoke(Types.NoParameters);
1668 }
1669 catch (Exception)
1670 {
1671 continue;
1672 }
1673
1674 Putters.Add(Putter);
1675
1676 foreach (string Schema in Putter.UriSchemes)
1677 {
1678 if (!ByScheme.TryGetValue(Schema, out List<IContentPutter> List))
1679 {
1680 List = new List<IContentPutter>();
1681 ByScheme[Schema] = List;
1682 }
1683
1684 List.Add(Putter);
1685 }
1686 }
1687
1688 lock (puttersByScheme)
1689 {
1690 foreach (KeyValuePair<string, List<IContentPutter>> P in ByScheme)
1691 puttersByScheme[P.Key] = P.Value.ToArray();
1692 }
1693
1694 putters = Putters.ToArray();
1695 }
1696
1704 public static bool CanPut(Uri Uri, out Grade Grade, out IContentPutter Putter)
1705 {
1706 if (Uri is null)
1707 throw new ArgumentNullException("URI cannot be null.", nameof(Uri));
1708
1709 if (putters is null)
1710 BuildPutters();
1711
1713
1714 lock (puttersByScheme)
1715 {
1716 if (Uri is null || !puttersByScheme.TryGetValue(Uri.Scheme, out Putters))
1717 {
1718 Putter = null;
1719 Grade = Grade.NotAtAll;
1720 return false;
1721 }
1722 }
1723
1724 Grade = Grade.NotAtAll;
1725 Putter = null;
1726
1727 foreach (IContentPutter Putter2 in Putters)
1728 {
1729 if (Putter2.CanPut(Uri, out Grade Grade2) && Grade2 > Grade)
1730 {
1731 Grade = Grade2;
1732 Putter = Putter2;
1733 }
1734 }
1735
1736 return !(Putter is null);
1737 }
1738
1746 public static Task<object> PutAsync(Uri Uri, object Data, params KeyValuePair<string, string>[] Headers)
1747 {
1748 return PutAsync(Uri, Data, null, null, Headers);
1749 }
1750
1759 public static Task<object> PutAsync(Uri Uri, object Data, X509Certificate Certificate, params KeyValuePair<string, string>[] Headers)
1760 {
1761 return PutAsync(Uri, Data, Certificate, null, Headers);
1762 }
1763
1773 public static Task<object> PutAsync(Uri Uri, object Data, X509Certificate Certificate,
1774 RemoteCertificateEventHandler RemoteCertificateValidator, params KeyValuePair<string, string>[] Headers)
1775 {
1776 if (!CanPut(Uri, out Grade _, out IContentPutter Putter))
1777 throw new ArgumentException("URI Scheme not recognized (PUT): " + Uri.Scheme, nameof(Uri));
1778
1779 return Putter.PutAsync(Uri, Data, Certificate, RemoteCertificateValidator, Headers);
1780 }
1781
1790 public static Task<object> PutAsync(Uri Uri, object Data, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1791 {
1792 return PutAsync(Uri, Data, null, null, TimeoutMs, Headers);
1793 }
1794
1804 public static Task<object> PutAsync(Uri Uri, object Data, X509Certificate Certificate, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1805 {
1806 return PutAsync(Uri, Data, Certificate, null, TimeoutMs, Headers);
1807 }
1808
1819 public static Task<object> PutAsync(Uri Uri, object Data, X509Certificate Certificate,
1820 RemoteCertificateEventHandler RemoteCertificateValidator, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1821 {
1822 if (!CanPut(Uri, out Grade _, out IContentPutter Putter))
1823 throw new ArgumentException("URI Scheme not recognized (PUT): " + Uri.Scheme, nameof(Uri));
1824
1825 return Putter.PutAsync(Uri, Data, Certificate, RemoteCertificateValidator, TimeoutMs, Headers);
1826 }
1827
1836 public static Task<KeyValuePair<byte[], string>> PutAsync(Uri Uri, byte[] EncodedData, string ContentType, params KeyValuePair<string, string>[] Headers)
1837 {
1838 return PutAsync(Uri, EncodedData, ContentType, null, null, Headers);
1839 }
1840
1850 public static Task<KeyValuePair<byte[], string>> PutAsync(Uri Uri, byte[] EncodedData, string ContentType, X509Certificate Certificate, params KeyValuePair<string, string>[] Headers)
1851 {
1852 return PutAsync(Uri, EncodedData, ContentType, Certificate, null, Headers);
1853 }
1854
1865 public static Task<KeyValuePair<byte[], string>> PutAsync(Uri Uri, byte[] EncodedData, string ContentType,
1866 X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, params KeyValuePair<string, string>[] Headers)
1867 {
1868 if (!CanPut(Uri, out Grade _, out IContentPutter Putter))
1869 throw new ArgumentException("URI Scheme not recognized (PUT): " + Uri.Scheme, nameof(Uri));
1870
1871 return Putter.PutAsync(Uri, EncodedData, ContentType, Certificate, RemoteCertificateValidator, Headers);
1872 }
1873
1883 public static Task<KeyValuePair<byte[], string>> PutAsync(Uri Uri, byte[] EncodedData, string ContentType, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1884 {
1885 return PutAsync(Uri, EncodedData, ContentType, null, null, TimeoutMs, Headers);
1886 }
1887
1898 public static Task<KeyValuePair<byte[], string>> PutAsync(Uri Uri, byte[] EncodedData, string ContentType, X509Certificate Certificate, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1899 {
1900 return PutAsync(Uri, EncodedData, ContentType, Certificate, null, TimeoutMs, Headers);
1901 }
1902
1914 public static Task<KeyValuePair<byte[], string>> PutAsync(Uri Uri, byte[] EncodedData, string ContentType,
1915 X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
1916 {
1917 if (!CanPut(Uri, out Grade _, out IContentPutter Putter))
1918 throw new ArgumentException("URI Scheme not recognized (PUT): " + Uri.Scheme, nameof(Uri));
1919
1920 return Putter.PutAsync(Uri, EncodedData, ContentType, Certificate, RemoteCertificateValidator, TimeoutMs, Headers);
1921 }
1922
1923 #endregion
1924
1925 #region Deleting to resources
1926
1930 public static string[] CanDeleteToUriSchemes
1931 {
1932 get
1933 {
1934 if (canDeleteToUriSchemes is null)
1935 {
1936 SortedDictionary<string, bool> UriSchemes = new SortedDictionary<string, bool>();
1937
1938 foreach (IContentDeleter Deleter in Deleters)
1939 {
1940 foreach (string Scheme in Deleter.UriSchemes)
1941 UriSchemes[Scheme] = true;
1942 }
1943
1944 string[] Schemes = new string[UriSchemes.Count];
1945 UriSchemes.Keys.CopyTo(Schemes, 0);
1946
1947 canDeleteToUriSchemes = Schemes;
1948 }
1949
1950 return canDeleteToUriSchemes;
1951 }
1952 }
1953
1958 {
1959 get
1960 {
1961 if (deleters is null)
1962 BuildDeleters();
1963
1964 return deleters;
1965 }
1966 }
1967
1968 private static void BuildDeleters()
1969 {
1970 List<IContentDeleter> Deleters = new List<IContentDeleter>();
1971 Type[] DeleterTypes = Types.GetTypesImplementingInterface(typeof(IContentDeleter));
1972 Dictionary<string, List<IContentDeleter>> ByScheme = new Dictionary<string, List<IContentDeleter>>();
1973 IContentDeleter Deleter;
1974
1975 foreach (Type T in DeleterTypes)
1976 {
1977 ConstructorInfo CI = Types.GetDefaultConstructor(T);
1978 if (CI is null)
1979 continue;
1980
1981 try
1982 {
1983 Deleter = (IContentDeleter)CI.Invoke(Types.NoParameters);
1984 }
1985 catch (Exception)
1986 {
1987 continue;
1988 }
1989
1990 Deleters.Add(Deleter);
1991
1992 foreach (string Schema in Deleter.UriSchemes)
1993 {
1994 if (!ByScheme.TryGetValue(Schema, out List<IContentDeleter> List))
1995 {
1996 List = new List<IContentDeleter>();
1997 ByScheme[Schema] = List;
1998 }
1999
2000 List.Add(Deleter);
2001 }
2002 }
2003
2004 lock (deletersByScheme)
2005 {
2006 foreach (KeyValuePair<string, List<IContentDeleter>> P in ByScheme)
2007 deletersByScheme[P.Key] = P.Value.ToArray();
2008 }
2009
2010 deleters = Deleters.ToArray();
2011 }
2012
2020 public static bool CanDelete(Uri Uri, out Grade Grade, out IContentDeleter Deleter)
2021 {
2022 if (Uri is null)
2023 throw new ArgumentNullException("URI cannot be null.", nameof(Uri));
2024
2025 if (deleters is null)
2026 BuildDeleters();
2027
2029
2030 lock (deletersByScheme)
2031 {
2032 if (Uri is null || !deletersByScheme.TryGetValue(Uri.Scheme, out Deleters))
2033 {
2034 Deleter = null;
2035 Grade = Grade.NotAtAll;
2036 return false;
2037 }
2038 }
2039
2040 Grade = Grade.NotAtAll;
2041 Deleter = null;
2042
2043 foreach (IContentDeleter Deleter2 in Deleters)
2044 {
2045 if (Deleter2.CanDelete(Uri, out Grade Grade2) && Grade2 > Grade)
2046 {
2047 Grade = Grade2;
2048 Deleter = Deleter2;
2049 }
2050 }
2051
2052 return !(Deleter is null);
2053 }
2054
2061 public static Task<object> DeleteAsync(Uri Uri, params KeyValuePair<string, string>[] Headers)
2062 {
2063 return DeleteAsync(Uri, null, null, Headers);
2064 }
2065
2073 public static Task<object> DeleteAsync(Uri Uri, X509Certificate Certificate, params KeyValuePair<string, string>[] Headers)
2074 {
2075 return DeleteAsync(Uri, Certificate, null, Headers);
2076 }
2077
2086 public static Task<object> DeleteAsync(Uri Uri, X509Certificate Certificate,
2087 RemoteCertificateEventHandler RemoteCertificateValidator, params KeyValuePair<string, string>[] Headers)
2088 {
2089 if (!CanDelete(Uri, out Grade _, out IContentDeleter Deleter))
2090 throw new ArgumentException("URI Scheme not recognized (DELETE): " + Uri.Scheme, nameof(Uri));
2091
2092 return Deleter.DeleteAsync(Uri, Certificate, RemoteCertificateValidator, Headers);
2093 }
2094
2102 public static Task<object> DeleteAsync(Uri Uri, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
2103 {
2104 return DeleteAsync(Uri, null, null, TimeoutMs, Headers);
2105 }
2106
2115 public static Task<object> DeleteAsync(Uri Uri, X509Certificate Certificate, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
2116 {
2117 return DeleteAsync(Uri, Certificate, null, TimeoutMs, Headers);
2118 }
2119
2129 public static Task<object> DeleteAsync(Uri Uri, X509Certificate Certificate,
2130 RemoteCertificateEventHandler RemoteCertificateValidator, int TimeoutMs,
2131 params KeyValuePair<string, string>[] Headers)
2132 {
2133 if (!CanDelete(Uri, out Grade _, out IContentDeleter Deleter))
2134 throw new ArgumentException("URI Scheme not recognized (DELETE): " + Uri.Scheme, nameof(Uri));
2135
2136 return Deleter.DeleteAsync(Uri, Certificate, RemoteCertificateValidator, TimeoutMs, Headers);
2137 }
2138
2139 #endregion
2140
2141 #region Getting headers of resources
2142
2146 public static string[] CanHeadUriSchemes
2147 {
2148 get
2149 {
2150 if (canHeadUriSchemes is null)
2151 {
2152 SortedDictionary<string, bool> UriSchemes = new SortedDictionary<string, bool>();
2153
2154 foreach (IContentHeader Header in Headers)
2155 {
2156 foreach (string Scheme in Header.UriSchemes)
2157 UriSchemes[Scheme] = true;
2158 }
2159
2160 string[] Schemes = new string[UriSchemes.Count];
2161 UriSchemes.Keys.CopyTo(Schemes, 0);
2162
2163 canHeadUriSchemes = Schemes;
2164 }
2165
2166 return canHeadUriSchemes;
2167 }
2168 }
2169
2173 public static IContentHeader[] Headers
2174 {
2175 get
2176 {
2177 if (headers is null)
2178 BuildHeaders();
2179
2180 return headers;
2181 }
2182 }
2183
2184 private static void BuildHeaders()
2185 {
2186 List<IContentHeader> Headers = new List<IContentHeader>();
2187 Type[] HeaderTypes = Types.GetTypesImplementingInterface(typeof(IContentHeader));
2188 Dictionary<string, List<IContentHeader>> ByScheme = new Dictionary<string, List<IContentHeader>>();
2189 IContentHeader Header;
2190
2191 foreach (Type T in HeaderTypes)
2192 {
2193 ConstructorInfo CI = Types.GetDefaultConstructor(T);
2194 if (CI is null)
2195 continue;
2196
2197 try
2198 {
2199 Header = (IContentHeader)CI.Invoke(Types.NoParameters);
2200 }
2201 catch (Exception)
2202 {
2203 continue;
2204 }
2205
2206 Headers.Add(Header);
2207
2208 foreach (string Schema in Header.UriSchemes)
2209 {
2210 if (!ByScheme.TryGetValue(Schema, out List<IContentHeader> List))
2211 {
2212 List = new List<IContentHeader>();
2213 ByScheme[Schema] = List;
2214 }
2215
2216 List.Add(Header);
2217 }
2218 }
2219
2220 lock (headersByScheme)
2221 {
2222 foreach (KeyValuePair<string, List<IContentHeader>> P in ByScheme)
2223 headersByScheme[P.Key] = P.Value.ToArray();
2224 }
2225
2226 headers = Headers.ToArray();
2227 }
2228
2236 public static bool CanHead(Uri Uri, out Grade Grade, out IContentHeader Header)
2237 {
2238 if (Uri is null)
2239 throw new ArgumentNullException("URI cannot be null.", nameof(Uri));
2240
2241 if (headers is null)
2242 BuildHeaders();
2243
2245
2246 lock (headersByScheme)
2247 {
2248 if (Uri is null || !headersByScheme.TryGetValue(Uri.Scheme, out Headers))
2249 {
2250 Header = null;
2251 Grade = Grade.NotAtAll;
2252 return false;
2253 }
2254 }
2255
2256 Grade = Grade.NotAtAll;
2257 Header = null;
2258
2259 foreach (IContentHeader Header2 in Headers)
2260 {
2261 if (Header2.CanHead(Uri, out Grade Grade2) && Grade2 > Grade)
2262 {
2263 Grade = Grade2;
2264 Header = Header2;
2265 }
2266 }
2267
2268 return !(Header is null);
2269 }
2270
2277 public static Task<object> HeadAsync(Uri Uri, params KeyValuePair<string, string>[] Headers)
2278 {
2279 return HeadAsync(Uri, null, null, Headers);
2280 }
2281
2289 public static Task<object> HeadAsync(Uri Uri, X509Certificate Certificate, params KeyValuePair<string, string>[] Headers)
2290 {
2291 return HeadAsync(Uri, Certificate, null, Headers);
2292 }
2293
2302 public static Task<object> HeadAsync(Uri Uri, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator,
2303 params KeyValuePair<string, string>[] Headers)
2304 {
2305 if (!CanHead(Uri, out Grade _, out IContentHeader Header))
2306 throw new ArgumentException("URI Scheme not recognized (HEAD): " + Uri.Scheme, nameof(Uri));
2307
2308 return Header.HeadAsync(Uri, Certificate, RemoteCertificateValidator, Headers);
2309 }
2310
2318 public static Task<object> HeadAsync(Uri Uri, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
2319 {
2320 return HeadAsync(Uri, null, null, TimeoutMs, Headers);
2321 }
2322
2331 public static Task<object> HeadAsync(Uri Uri, X509Certificate Certificate, int TimeoutMs, params KeyValuePair<string, string>[] Headers)
2332 {
2333 return HeadAsync(Uri, Certificate, null, TimeoutMs, Headers);
2334 }
2335
2345 public static Task<object> HeadAsync(Uri Uri, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator,
2346 int TimeoutMs, params KeyValuePair<string, string>[] Headers)
2347 {
2348 if (!CanHead(Uri, out Grade _, out IContentHeader Header))
2349 throw new ArgumentException("URI Scheme not recognized (HEAD): " + Uri.Scheme, nameof(Uri));
2350
2351 return Header.HeadAsync(Uri, Certificate, RemoteCertificateValidator, TimeoutMs, Headers);
2352 }
2353
2354 #endregion
2355 }
2356}
const string DefaultContentType
text/plain
Definition: BinaryCodec.cs:24
Encodes custom-encoded objects
A custom encoded object.
Helps with parsing of commong data types.
Definition: CommonTypes.cs:13
static KeyValuePair< string, string >[] ParseFieldValues(string Value)
Parses a set of comma or semicolon-separated field values, optionaly delimited by ' or " characters.
Definition: CommonTypes.cs:472
Static class managing encoding and decoding of internet content.
static Task< KeyValuePair< byte[], string > > PutAsync(Uri Uri, byte[] EncodedData, string ContentType, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Puts to a resource, using a Uniform Resource Identifier (or Locator).
static string[] CanDecodeContentTypes
Internet content types that can be decoded.
static bool IsAccepted(string ContentType, params string[] AcceptedContentTypes)
Checks if a given content type is acceptable.
static Task< KeyValuePair< byte[], string > > EncodeAsync(object Object, Encoding Encoding, params string[] AcceptedContentTypes)
Encodes an object.
static Task< KeyValuePair< string, TemporaryStream > > GetTempStreamAsync(Uri Uri, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Gets a (possibly big) resource, given its URI.
static Task< object > DeleteAsync(Uri Uri, X509Certificate Certificate, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Deletes a resource, using a Uniform Resource Identifier (or Locator).
static Task< object > DecodeAsync(string ContentType, byte[] Data, Encoding Encoding, KeyValuePair< string, string >[] Fields, Uri BaseUri)
Decodes an object.
static IContentConverter[] GetConverters(string FromContentType)
Gets available converters that can convert content from a given type.
static byte[] Encode(object Object, Encoding Encoding, out string ContentType, params string[] AcceptedContentTypes)
Encodes an object.
static Task< KeyValuePair< string, TemporaryStream > > GetTempStreamAsync(Uri Uri, X509Certificate Certificate, params KeyValuePair< string, string >[] Headers)
Gets a (possibly big) resource, given its URI.
static Task< KeyValuePair< byte[], string > > PutAsync(Uri Uri, byte[] EncodedData, string ContentType, X509Certificate Certificate, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Puts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< object > PutAsync(Uri Uri, object Data, params KeyValuePair< string, string >[] Headers)
Puts to a resource, using a Uniform Resource Identifier (or Locator).
static IContentHeader[] Headers
Available Internet Content Header-retrievers.
static Task< object > PostAsync(Uri Uri, object Data, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
static bool CanPost(Uri Uri, out Grade Grade, out IContentPoster Poster)
If a resource can be posted to, given its URI.
static Task< object > PutAsync(Uri Uri, object Data, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, params KeyValuePair< string, string >[] Headers)
Puts to a resource, using a Uniform Resource Identifier (or Locator).
static string GetFileExtension(string ContentType)
Gets the file extension of an item, given its content type. It uses the TryGetFileExtension to see if...
static Task< KeyValuePair< string, TemporaryStream > > GetTempStreamAsync(Uri Uri, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, params KeyValuePair< string, string >[] Headers)
Gets a (possibly big) resource, given its URI.
static Task< object > GetAsync(Uri Uri, params KeyValuePair< string, string >[] Headers)
Gets a resource, given its URI.
static Task< object > GetAsync(Uri Uri, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Gets a resource, given its URI.
static Task< object > PostAsync(Uri Uri, object Data, X509Certificate Certificate, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
static bool CanGet(Uri Uri, out Grade Grade, out IContentGetter Getter)
If a resource can be gotten, given its URI.
static Task< KeyValuePair< string, TemporaryStream > > GetTempStreamAsync(Uri Uri, X509Certificate Certificate, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Gets a (possibly big) resource, given its URI.
static IContentDecoder[] Decoders
Available Internet Content Decoders.
static bool Encodes(object Object, out Grade Grade, out IContentEncoder Encoder, params string[] AcceptedContentTypes)
If a given object can be encoded.
static Task< KeyValuePair< byte[], string > > PostAsync(Uri Uri, byte[] EncodedData, string ContentType, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
static string[] CanPutToUriSchemes
Internet URI Schemes that can be putted to.
static string[] CanDeleteToUriSchemes
Internet URI Schemes that can be deleted to.
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 IContentEncoder[] Encoders
Available Internet Content Encoders.
static Task< object > PutAsync(Uri Uri, object Data, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Puts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< object > HeadAsync(Uri Uri, params KeyValuePair< string, string >[] Headers)
Heads a resource, given its URI.
static bool CanConvert(string FromContentType, string ToContentType, out IContentConverter Converter)
Checks if it is possible to convert content from one type to another.
static Task< object > HeadAsync(Uri Uri, X509Certificate Certificate, params KeyValuePair< string, string >[] Headers)
Heads a resource, given its URI.
static Task< object > HeadAsync(Uri Uri, X509Certificate Certificate, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Heads a resource, given its URI.
static Task< object > PutAsync(Uri Uri, object Data, X509Certificate Certificate, params KeyValuePair< string, string >[] Headers)
Puts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< object > HeadAsync(Uri Uri, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Heads a resource, given its URI.
static IContentPutter[] Putters
Available Internet Content Putters.
static string[] CanHeadUriSchemes
Internet URI Schemes where it is possible to get headers.
static object Decode(string ContentType, byte[] Data, Uri BaseUri)
Decodes an object.
static IContentGetter[] Getters
Available Internet Content Getters.
static object Decode(string ContentType, byte[] Data, Encoding Encoding, KeyValuePair< string, string >[] Fields, Uri BaseUri)
Decodes an object.
static IContentDeleter[] Deleters
Available Internet Content Deleters.
static Task< object > DeleteAsync(Uri Uri, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Deletes a resource, using a Uniform Resource Identifier (or Locator).
static Task< KeyValuePair< byte[], string > > PostAsync(Uri Uri, byte[] EncodedData, string ContentType, X509Certificate Certificate, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
static string[] CanEncodeContentTypes
Internet content types that can be encoded.
static Task< object > DeleteAsync(Uri Uri, params KeyValuePair< string, string >[] Headers)
Deletes a resource, using a Uniform Resource Identifier (or Locator).
static Task< KeyValuePair< byte[], string > > PostAsync(Uri Uri, byte[] EncodedData, string ContentType, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
static readonly Encoding ISO_8859_1
ISO-8859-1 character encoding.
static bool Decodes(string ContentType, out Grade Grade, out IContentDecoder Decoder)
If an object with a given content type can be decoded.
static Task< object > PostAsync(Uri Uri, object Data, X509Certificate Certificate, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< KeyValuePair< string, TemporaryStream > > GetTempStreamAsync(Uri Uri, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Gets a (possibly big) resource, given its URI.
static IContentPoster[] Posters
Available Internet Content Posters.
static Task< object > GetAsync(Uri Uri, X509Certificate Certificate, params KeyValuePair< string, string >[] Headers)
Gets a resource, given its URI.
static Task< object > PutAsync(Uri Uri, object Data, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Puts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< object > HeadAsync(Uri Uri, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Heads a resource, given its URI.
static bool IsAccepted(string[] ContentTypes, out string ContentType, params string[] AcceptedContentTypes)
Checks if at least one content type in a set of content types is acceptable.
static Task< object > GetAsync(Uri Uri, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Gets a resource, given its URI.
static string[] CanDecodeFileExtensions
File extensions that can be decoded.
static Task< object > GetAsync(Uri Uri, X509Certificate Certificate, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Gets a resource, given its URI.
static bool CanPut(Uri Uri, out Grade Grade, out IContentPutter Putter)
If a resource can be putted to, given its URI.
static string[] CanPostToUriSchemes
Internet URI Schemes that can be posted to.
static Task< KeyValuePair< byte[], string > > PutAsync(Uri Uri, byte[] EncodedData, string ContentType, X509Certificate Certificate, params KeyValuePair< string, string >[] Headers)
Puts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< object > DeleteAsync(Uri Uri, X509Certificate Certificate, params KeyValuePair< string, string >[] Headers)
Deletes a resource, using a Uniform Resource Identifier (or Locator).
static Task< object > PostAsync(Uri Uri, object Data, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
static bool CanHead(Uri Uri, out Grade Grade, out IContentHeader Header)
If the headers of a resource can be gotten, given its URI.
static Task< object > PostAsync(Uri Uri, object Data, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< KeyValuePair< byte[], string > > PutAsync(Uri Uri, byte[] EncodedData, string ContentType, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Puts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< KeyValuePair< string, TemporaryStream > > GetTempStreamAsync(Uri Uri, params KeyValuePair< string, string >[] Headers)
Gets a (possibly big) resource, given its URI.
static Task< object > DeleteAsync(Uri Uri, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, params KeyValuePair< string, string >[] Headers)
Deletes a resource, using a Uniform Resource Identifier (or Locator).
static string[] CanGetUriSchemes
Internet URI Schemes that can be gotten.
static Task< object > HeadAsync(Uri Uri, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, params KeyValuePair< string, string >[] Headers)
Heads a resource, given its URI.
static Task< KeyValuePair< byte[], string > > PostAsync(Uri Uri, byte[] EncodedData, string ContentType, X509Certificate Certificate, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< KeyValuePair< byte[], string > > PostAsync(Uri Uri, byte[] EncodedData, string ContentType, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
static IContentConverter[] Converters
Available Internet Content Converters.
static Task< KeyValuePair< byte[], string > > PutAsync(Uri Uri, byte[] EncodedData, string ContentType, params KeyValuePair< string, string >[] Headers)
Puts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< object > PostAsync(Uri Uri, object Data, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< object > PutAsync(Uri Uri, object Data, X509Certificate Certificate, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Puts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< KeyValuePair< byte[], string > > PostAsync(Uri Uri, byte[] EncodedData, string ContentType, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, params KeyValuePair< string, string >[] Headers)
Posts to a resource, using a Uniform Resource Identifier (or Locator).
static Task< object > DeleteAsync(Uri Uri, int TimeoutMs, params KeyValuePair< string, string >[] Headers)
Deletes a resource, using a Uniform Resource Identifier (or Locator).
static Task< KeyValuePair< byte[], string > > PutAsync(Uri Uri, byte[] EncodedData, string ContentType, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, params KeyValuePair< string, string >[] Headers)
Puts to a resource, using a Uniform Resource Identifier (or Locator).
static bool IsAccepted(string[] ContentTypes, params string[] AcceptedContentTypes)
Checks if at least one content type in a set of content types is acceptable.
static bool CanDelete(Uri Uri, out Grade Grade, out IContentDeleter Deleter)
If a resource can be deleted to, given its URI.
static string[] CanEncodeFileExtensions
File extensions that can be encoded.
static bool TryGetContentType(string FileExtension, out string ContentType)
Tries to get the content type of an item, given its file extension.
static Task< object > DecodeAsync(string ContentType, byte[] Data, Uri BaseUri)
Decodes an object.
static Task< object > GetAsync(Uri Uri, X509Certificate Certificate, RemoteCertificateEventHandler RemoteCertificateValidator, params KeyValuePair< string, string >[] Headers)
Gets a resource, given its URI.
static Encoding GetEncoding(string CharacterSet)
Gets a character encoding from its name.
static bool TryGetFileExtension(string ContentType, out string FileExtension)
Tries to get the file extension of an item, given its content type.
Static class that dynamically manages types and interfaces available in the runtime environment.
Definition: Types.cs:14
static object[] NoParameters
Contains an empty array of parameter values.
Definition: Types.cs:548
static Type[] GetTypesImplementingInterface(string InterfaceFullName)
Gets all types implementing a given interface.
Definition: Types.cs:84
static ConstructorInfo GetDefaultConstructor(Type Type)
Gets the default constructor of a type, if one exists.
Definition: Types.cs:1630
Basic interface for Internet Content encoders. A class implementing this interface and having a defau...
Grade ConversionGrade
How well the content is converted.
string[] FromContentTypes
Converts content from these content types.
string[] ToContentTypes
Converts content to these content types. Return an array of "*" to signify content can be converted t...
Basic interface for Internet Content decoders. A class implementing this interface and having a defau...
bool Decodes(string ContentType, out Grade Grade)
If the decoder decodes an object with a given content type.
Basic interface for Internet Content deleters. A class implementing this interface and having a defau...
string[] UriSchemes
Supported URI schemes.
bool CanDelete(Uri Uri, out Grade Grade)
If the deleter is able to delete to a resource, given its URI.
Basic interface for Internet Content encoders. A class implementing this interface and having a defau...
bool Encodes(object Object, out Grade Grade, params string[] AcceptedContentTypes)
If the encoder encodes a given object.
Basic interface for Internet Content getters. A class implementing this interface and having a defaul...
bool CanGet(Uri Uri, out Grade Grade)
If the getter is able to get a resource, given its URI.
Basic interface for Internet Content headers. A class implementing this interface and having a defaul...
string[] UriSchemes
Supported URI schemes.
bool CanHead(Uri Uri, out Grade Grade)
If the getter is able to get headers of a resource, given its URI.
Basic interface for Internet Content posters. A class implementing this interface and having a defaul...
string[] UriSchemes
Supported URI schemes.
bool CanPost(Uri Uri, out Grade Grade)
If the poster is able to post to a resource, given its URI.
Basic interface for Internet Content putters. A class implementing this interface and having a defaul...
string[] UriSchemes
Supported URI schemes.
bool CanPut(Uri Uri, out Grade Grade)
If the putter is able to put to a resource, given its URI.
bool TryGetContentType(string FileExtension, out string ContentType)
Tries to get the content type of an item, given its file extension.
string[] ContentTypes
Supported content types.
bool TryGetFileExtension(string ContentType, out string FileExtension)
Tries to get the file extension of an item, given its Content-Type.
string[] FileExtensions
Supported file extensions.
delegate void RemoteCertificateEventHandler(object Sender, RemoteCertificateEventArgs e)
Delegate for remote certificate event handlers.
Grade
Grade enumeration
Definition: Grade.cs:7