PageRenderTime 42ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/BlogEngine/DotNetSlave.BusinessLogic/XmlSafeResolver.cs

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