PageRenderTime 9ms CodeModel.GetById 1ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/BlogEngine/DotNetSlave.BusinessLogic/XmlSafeResolver.cs

#
C# | 109 lines | 54 code | 15 blank | 40 comment | 7 complexity | 27df2923ae93bd034af1c91628e866b8 MD5 | raw file
  1namespace BlogEngine.Core
  2{
  3    using System;
  4    using System.IO;
  5    using System.Net;
  6    using System.Xml;
  7
  8    /// <summary>
  9    /// Derived XmlUrlResolver class designed to prevent security problems with
 10    ///     dangerous XML input, by limiting the amount of data that can be retrieved.
 11    /// </summary>
 12    public class XmlSafeResolver : XmlUrlResolver
 13    {
 14        #region Constants and Fields
 15
 16        /// <summary>
 17        /// The buffer size. 1 KB.
 18        /// </summary>
 19        private const int BufferSize = 1024;
 20
 21        /// <summary>
 22        /// The max response size. 1 MB.
 23        /// </summary>
 24        private const int MaxResponseSize = 1024 * 1024;
 25
 26        /// <summary>
 27        /// The timeout. 10 seconds.
 28        /// </summary>
 29        private const int Timeout = 10000;
 30
 31        #endregion
 32
 33        #region Public Methods
 34
 35        /// <summary>
 36        /// Maps a URI to an object containing the actual resource.
 37        /// </summary>
 38        /// <param name="absoluteUri">
 39        /// The URI returned from <see cref="M:System.Xml.XmlResolver.ResolveUri(System.Uri,System.String)"/>
 40        /// </param>
 41        /// <param name="role">
 42        /// The current implementation does not use this parameter when resolving URIs. This is provided for future extensibility purposes. For example, this can be mapped to the xlink:role and used as an implementation specific argument in other scenarios.
 43        /// </param>
 44        /// <param name="typeOfObjectToReturn">
 45        /// The type of object to return. The current implementation only returns System.IO.Stream objects.
 46        /// </param>
 47        /// <returns>
 48        /// A System.IO.Stream object or null if a type other than stream is specified.
 49        /// </returns>
 50        /// <exception cref="T:System.Xml.XmlException">
 51        /// <paramref name="typeOfObjectToReturn"/> is neither null nor a Stream type.
 52        /// </exception>
 53        /// <exception cref="T:System.UriFormatException">
 54        /// The specified URI is not an absolute URI.
 55        /// </exception>
 56        /// <exception cref="T:System.ArgumentNullException">
 57        /// <paramref name="absoluteUri"/> is null.
 58        /// </exception>
 59        /// <exception cref="T:System.Exception">
 60        /// There is a runtime error (for example, an interrupted server connection).
 61        /// </exception>
 62        public override object GetEntity(Uri absoluteUri, string role, Type typeOfObjectToReturn)
 63        {
 64            if (absoluteUri.IsLoopback)
 65            {
 66                return null;
 67            }
 68
 69            var request = WebRequest.Create(absoluteUri);
 70            request.Timeout = Timeout;
 71
 72            var response = request.GetResponse();
 73            if (response == null)
 74            {
 75                throw new XmlException("Could not resolve external entity");
 76            }
 77
 78            var responseStream = response.GetResponseStream();
 79            if (responseStream == null)
 80            {
 81                throw new XmlException("Could not resolve external entity");
 82            }
 83
 84            responseStream.ReadTimeout = Timeout;
 85
 86            var copyStream = new MemoryStream();
 87            var buffer = new byte[BufferSize];
 88            int bytesRead;
 89            var totalBytesRead = 0;
 90            do
 91            {
 92                bytesRead = responseStream.Read(buffer, 0, buffer.Length);
 93                totalBytesRead += bytesRead;
 94                if (totalBytesRead > MaxResponseSize)
 95                {
 96                    throw new XmlException("Could not resolve external entity");
 97                }
 98
 99                copyStream.Write(buffer, 0, bytesRead);
100            }
101            while (bytesRead > 0);
102
103            copyStream.Seek(0, SeekOrigin.Begin);
104            return copyStream;
105        }
106
107        #endregion
108    }
109}