//----------------------------------------------------------------------- // // Copyright (c) Andrew Arnott. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.Messaging { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.Serialization.Json; using System.Text; using System.Threading.Tasks; using System.Web; using System.Xml; using DotNetOpenAuth.Configuration; using Validation; /// /// Derivation of ChannelBase that adds desktop-specific behavior. /// public abstract class Channel : ChannelBase { /// /// A default set of XML dictionary reader quotas that are relatively safe from causing unbounded memory consumption. /// internal static readonly XmlDictionaryReaderQuotas DefaultUntrustedXmlDictionaryReaderQuotas = new XmlDictionaryReaderQuotas { MaxArrayLength = 1, MaxDepth = 2, MaxBytesPerRead = 8 * 1024, MaxStringContentLength = 16 * 1024, }; /// /// Initializes a new instance of the class. /// /// A class prepared to analyze incoming messages and indicate what concrete /// message types can deserialize from it. /// The binding elements to use in sending and receiving messages. /// The order they are provided is used for outgoing messgaes, and reversed for incoming messages. /// The host factories. protected Channel(IMessageFactory messageTypeProvider, IChannelBindingElement[] bindingElements, IHostFactories hostFactories) : base(messageTypeProvider, bindingElements, hostFactories) { this.XmlDictionaryReaderQuotas = DefaultUntrustedXmlDictionaryReaderQuotas; this.MaximumIndirectMessageUrlLength = Configuration.DotNetOpenAuthSection.Messaging.MaximumIndirectMessageUrlLength; this.MaximumClockSkew = DotNetOpenAuthSection.Messaging.MaximumClockSkew; this.MaximumMessageLifetimeNoSkew = Configuration.DotNetOpenAuthSection.Messaging.MaximumMessageLifetime; } /// /// Gets the HTTP context for the current HTTP request. /// /// An HttpContextBase instance. [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Allocates memory")] protected internal virtual HttpContextBase GetHttpContext() { RequiresEx.ValidState(HttpContext.Current != null, MessagingStrings.HttpContextRequired); return new HttpContextWrapper(HttpContext.Current); } /// /// Gets the current HTTP request being processed. /// /// The HttpRequestInfo for the current request. /// /// Requires an context. /// /// Thrown if HttpContext.Current == null. [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Costly call should not be a property.")] protected internal virtual HttpRequestBase GetRequestFromContext() { RequiresEx.ValidState(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired); Assumes.True(HttpContext.Current.Request.Url != null); Assumes.True(HttpContext.Current.Request.RawUrl != null); return new HttpRequestWrapper(HttpContext.Current.Request); } /// /// Serializes the given message as a JSON string. /// /// The message to serialize. /// A JSON string. [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "This Dispose is safe.")] [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "No apparent problem. False positive?")] protected virtual string SerializeAsJson(IMessage message) { Requires.NotNull(message, "message"); return MessagingUtilities.SerializeAsJson(message, this.MessageDescriptions); } /// /// Deserializes from flat data from a JSON object. /// /// A JSON string. /// The simple "key":"value" pairs from a JSON-encoded object. [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "No apparent problem. False positive?")] protected virtual IDictionary DeserializeFromJson(string json) { Requires.NotNullOrEmpty(json, "json"); var dictionary = new Dictionary(); using (var jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json), this.XmlDictionaryReaderQuotas)) { MessageSerializer.DeserializeJsonAsFlatDictionary(dictionary, jsonReader); } return dictionary; } } }