/* ----------------------------------------------------------------- */ /// /// GetAsync(T) /// /// <summary> /// HTTP 通信を実行し、変換結果を取得します。 /// </summary> /// /// <param name="client">HTTP クライアント</param> /// <param name="uri">レスポンス取得 URL</param> /// <param name="converter">変換用オブジェクト</param> /// /// <returns>変換結果</returns> /// /// <remarks> /// 例外の扱いについては、IContentConverter(T).IgnoreException の /// 設定に準じます。 /// </remarks> /// /* ----------------------------------------------------------------- */ public static async Task <T> GetAsync <T>(this HttpClient client, Uri uri, IContentConverter <T> converter) { try { using (var response = await client.GetAsync(uri)) { if (response.IsSuccessStatusCode) { await response.Content.LoadIntoBufferAsync(); var stream = await response.Content.ReadAsStreamAsync(); return(converter.Convert(stream)); } else { client.LogWarn($"StatusCode:{response.StatusCode}"); } } } catch (Exception err) { if (converter.IgnoreException) { client.LogWarn(err.ToString(), err); } else { throw; } } return(default(T)); }
public void Convert(Content content, object result) { if (this.Converter.GetTypeInfo().ImplementedInterfaces.Contains(typeof(IContentConverter))) { IContentConverter converter = Activator.CreateInstance(this.Converter) as IContentConverter; converter.Convert(content, result); } }
public object Convert(object result) { if (this.Converter.GetTypeInfo().ImplementedInterfaces.Contains(typeof(IContentConverter))) { IContentConverter converter = Activator.CreateInstance(this.Converter) as IContentConverter; return(converter.Convert(result)); } return(null); }
/// <summary> /// Checks if it is possible to convert content from one type to another. /// /// A shortest path algorithm maximizing conversion quality and shortening conversion distance is used to find sequences of converters, /// if a direct conversion is not possible. /// </summary> /// <param name="FromContentType">Existing content type.</param> /// <param name="ToContentType">Desired content type.</param> /// <param name="Converter">Converter that transforms content from type <paramref name="FromContentType"/> to type /// <paramref name="ToContentType"/>.</param> /// <returns>If a converter was found.</returns> public static bool CanConvert(string FromContentType, string ToContentType, out IContentConverter Converter) { lock (convertersByStep) { if (converters == null) { FindConverters(); } string PathKey = FromContentType + " -> " + ToContentType; if (convertersByStep.TryGetValue(PathKey, out Converter)) { return(Converter != null); } if (!convertersByFrom.TryGetValue(FromContentType, out List <IContentConverter> Converters)) { return(false); } LinkedList <ConversionStep> Queue = new LinkedList <ConversionStep>(); ConversionStep Step; foreach (IContentConverter C in Converters) { Step = new ConversionStep() { From = FromContentType, Converter = C, TotalGrade = C.ConversionGrade, Prev = null, Distance = 1 }; Queue.AddLast(Step); } Dictionary <string, ConversionStep> Possibilities = new Dictionary <string, ConversionStep>(); ConversionStep Best = null; Grade BestGrade = Grade.NotAtAll; int BestDistance = int.MaxValue; Grade StepGrade; int StepDistance; bool First; while (Queue.First != null) { Step = Queue.First.Value; Queue.RemoveFirst(); StepDistance = Step.Distance + 1; StepGrade = Step.Converter.ConversionGrade; if (Step.TotalGrade < StepGrade) { StepGrade = Step.TotalGrade; } foreach (string To in Step.Converter.ToContentTypes) { if (string.Compare(To, ToContentType, true) == 0) { if (StepGrade > BestGrade || StepGrade == BestGrade && StepDistance < BestDistance) { Best = Step; BestGrade = StepGrade; BestDistance = StepDistance; } } else { if (Possibilities.TryGetValue(To, out ConversionStep NextStep) && NextStep.TotalGrade >= StepGrade && NextStep.Distance <= StepDistance) { continue; } if (!convertersByFrom.TryGetValue(To, out Converters)) { continue; } First = true; foreach (IContentConverter C in Converters) { if (First) { Possibilities[To] = NextStep; First = false; } NextStep = new ConversionStep() { From = To, Converter = C, TotalGrade = StepGrade, Prev = Step, Distance = StepDistance }; Queue.AddLast(NextStep); } } } } if (Best != null) { List <KeyValuePair <string, IContentConverter> > List = new List <KeyValuePair <string, IContentConverter> >(); while (Best != null) { List.Insert(0, new KeyValuePair <string, IContentConverter>(Best.From, Best.Converter)); Best = Best.Prev; } Converter = new ConversionSequence(FromContentType, ToContentType, BestGrade, List.ToArray()); convertersByStep[PathKey] = Converter; return(true); } else { convertersByStep[PathKey] = null; Converter = null; return(false); } } }
private Stream CheckAcceptable(HttpRequest Request, HttpResponse Response, ref string ContentType, out bool Dynamic, string FullPath, string ResourceName) { HttpRequestHeader Header = Request.Header; Dynamic = false; if (Header.Accept != null) { bool Acceptable = Header.Accept.IsAcceptable(ContentType, out double Quality, out AcceptanceLevel TypeAcceptance, null); if ((!Acceptable || TypeAcceptance == AcceptanceLevel.Wildcard) && (this.allowTypeConversionFrom is null || (this.allowTypeConversionFrom.TryGetValue(ContentType, out bool Allowed) && Allowed))) { IContentConverter Converter = null; string NewContentType = null; foreach (AcceptRecord AcceptRecord in Header.Accept.Records) { NewContentType = AcceptRecord.Item; if (NewContentType.EndsWith("/*")) { NewContentType = null; continue; } if (InternetContent.CanConvert(ContentType, NewContentType, out Converter)) { Acceptable = true; break; } } if (Converter is null) { IContentConverter[] Converters = InternetContent.GetConverters(ContentType); if (Converters != null) { string BestContentType = null; double BestQuality = 0; IContentConverter Best = null; bool Found; foreach (IContentConverter Converter2 in InternetContent.Converters) { Found = false; foreach (string FromContentType in Converter2.FromContentTypes) { if (ContentType == FromContentType) { Found = true; break; } } if (!Found) { continue; } foreach (string ToContentType in Converter2.ToContentTypes) { if (Header.Accept.IsAcceptable(ToContentType, out double Quality2) && Quality > BestQuality) { BestContentType = ToContentType; BestQuality = Quality; Best = Converter2; } } } if (Best != null && (!Acceptable || BestQuality >= Quality)) { Acceptable = true; Converter = Best; NewContentType = BestContentType; } } } if (Acceptable && Converter != null) { Stream f2 = null; Stream f = File.Open(FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); bool Ok = false; try { f2 = f.Length < HttpClientConnection.MaxInmemoryMessageSize ? (Stream) new MemoryStream() : new TemporaryFile(); if (Request.Session != null) { Request.Session["Request"] = Request; Request.Session["Response"] = Response; } if (Converter.Convert(ContentType, f, FullPath, ResourceName, Request.Header.GetURL(false, false), NewContentType, f2, Request.Session)) { Dynamic = true; } ContentType = NewContentType; Ok = true; } finally { if (f2 is null) { f.Dispose(); } else if (!Ok) { f2.Dispose(); f.Dispose(); } else { f.Dispose(); f = f2; f.Position = 0; } } return(f); } } if (!Acceptable) { throw new NotAcceptableException(); } } return(null); }
/* ----------------------------------------------------------------- */ /// /// HttpMonitor /// /// <summary> /// オブジェクトを初期化します。 /// </summary> /// /// <param name="converter">変換用オブジェクト</param> /// /* ----------------------------------------------------------------- */ public HttpMonitor(IContentConverter <TValue> converter) : this(new ContentHandler <TValue>(converter)) { }
private Stream CheckAcceptable(HttpRequest Request, HttpResponse Response, ref string ContentType, out bool Dynamic, string FullPath, string ResourceName) { HttpRequestHeader Header = Request.Header; Dynamic = false; if (Header.Accept != null) { bool Acceptable = Header.Accept.IsAcceptable(ContentType, out double Quality, out ContentTypeAcceptance TypeAcceptance, null); if ((!Acceptable || TypeAcceptance == ContentTypeAcceptance.Wildcard) && (this.allowTypeConversionFrom == null || (this.allowTypeConversionFrom.TryGetValue(ContentType, out bool Allowed) && Allowed))) { IContentConverter Converter = null; string NewContentType = null; foreach (AcceptRecord AcceptRecord in Header.Accept.Records) { NewContentType = AcceptRecord.Item; if (NewContentType.EndsWith("/*")) { continue; } if (InternetContent.CanConvert(ContentType, NewContentType, out Converter)) { Acceptable = true; break; } } if (Acceptable && Converter != null) { Stream f2 = null; Stream f = File.OpenRead(FullPath); bool Ok = false; try { f2 = f.Length < HttpClientConnection.MaxInmemoryMessageSize ? (Stream) new MemoryStream() : new TemporaryFile(); if (Request.Session != null) { Request.Session["Request"] = Request; Request.Session["Response"] = Response; } if (Converter.Convert(ContentType, f, FullPath, ResourceName, Request.Header.GetURL(false, false), NewContentType, f2, Request.Session)) { Dynamic = true; } ContentType = NewContentType; Ok = true; } finally { if (f2 == null) { f.Dispose(); } else if (!Ok) { f2.Dispose(); f.Dispose(); } else { f.Dispose(); f = f2; f2 = null; f.Position = 0; } } return(f); } } if (!Acceptable) { throw new NotAcceptableException(); } } return(null); }
/* ----------------------------------------------------------------- */ /// /// ContentHandler /// /// <summary> /// オブジェクトを初期化します。 /// </summary> /// /// <param name="converter">変換用オブジェクト</param> /// /* ----------------------------------------------------------------- */ public ContentHandler(IContentConverter <TValue> converter) : this() { Converter = converter; }
public static void SetContentConverter(DependencyObject depo, IContentConverter value) => depo.SetValue(ContentConverterProperty, value);