//-----------------------------------------------------------------------
//
// 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;
}
}
}