PageRenderTime 28ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/referencesource/System.Web/HttpException.cs

https://github.com/pruiz/mono
C# | 700 lines | 402 code | 161 blank | 137 comment | 50 complexity | 1e3b70666bc30d6deb7ea36355c06b39 MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. //------------------------------------------------------------------------------
  2. // <copyright file="HttpException.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. //------------------------------------------------------------------------------
  6. /*
  7. * Exception thrown by ASP.NET managed runtime
  8. *
  9. * Copyright (c) 1998 Microsoft Corporation
  10. */
  11. namespace System.Web {
  12. using System.IO;
  13. using System.Runtime.InteropServices;
  14. using System.Runtime.Serialization;
  15. using System.Collections;
  16. using System.Collections.Specialized;
  17. using System.Configuration;
  18. using System.Diagnostics.CodeAnalysis;
  19. using System.Security;
  20. using System.Globalization;
  21. using System.CodeDom.Compiler;
  22. using System.Security.Permissions;
  23. using System.Web.Hosting;
  24. using System.Web.Management;
  25. using System.Web.Util;
  26. /// <devdoc>
  27. /// <para> Enables ASP.NET
  28. /// to send exception information.</para>
  29. /// </devdoc>
  30. [Serializable]
  31. public class HttpException : ExternalException {
  32. private const int FACILITY_WIN32 = 7;
  33. private int _httpCode;
  34. private ErrorFormatter _errorFormatter;
  35. private int _webEventCode = WebEventCodes.UndefinedEventCode;
  36. // N.B. The last error code can be lost if we were to
  37. // call UnsafeNativeMethods.GetLastError from this function
  38. // and it were not yet jitted.
  39. internal static int HResultFromLastError(int lastError) {
  40. int hr;
  41. if (lastError < 0) {
  42. hr = lastError;
  43. }
  44. else {
  45. hr = (int)(((uint)lastError & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000);
  46. }
  47. return hr;
  48. }
  49. /// <devdoc>
  50. /// <para>Creates a new Exception based on the previous Exception. </para>
  51. /// </devdoc>
  52. public static HttpException CreateFromLastError(String message) {
  53. return new HttpException(message, HResultFromLastError(Marshal.GetLastWin32Error()));
  54. }
  55. /// <devdoc>
  56. /// <para> Default constructor.</para>
  57. /// </devdoc>
  58. public HttpException() {}
  59. /// <devdoc>
  60. /// <para>
  61. /// Construct an exception using error message.
  62. /// </para>
  63. /// </devdoc>
  64. public HttpException(String message)
  65. : base(message) {
  66. }
  67. internal HttpException(String message, Exception innerException, int code)
  68. : base(message, innerException) {
  69. _webEventCode = code;
  70. }
  71. /// <devdoc>
  72. /// <para>Construct an exception using error message and hr.</para>
  73. /// </devdoc>
  74. public HttpException(String message, int hr)
  75. : base(message) {
  76. HResult = hr;
  77. }
  78. /// <devdoc>
  79. /// <para>Construct an exception using error message, HTTP code,
  80. /// and innerException
  81. /// .</para>
  82. /// </devdoc>
  83. public HttpException(String message, Exception innerException)
  84. : base(message, innerException) {
  85. }
  86. /// <devdoc>
  87. /// <para>Construct an exception using HTTP error code, error message,
  88. /// and innerException
  89. /// .</para>
  90. /// </devdoc>
  91. public HttpException(int httpCode, String message, Exception innerException)
  92. : base(message, innerException) {
  93. _httpCode = httpCode;
  94. }
  95. /// <devdoc>
  96. /// <para>Construct an
  97. /// exception using HTTP error code and error message.</para>
  98. /// </devdoc>
  99. public HttpException(int httpCode, String message)
  100. : base(message) {
  101. _httpCode = httpCode;
  102. }
  103. /// <devdoc>
  104. /// <para> Construct an exception
  105. /// using HTTP error code, error message, and hr.</para>
  106. /// </devdoc>
  107. public HttpException(int httpCode, String message, int hr)
  108. : base(message) {
  109. HResult = hr;
  110. _httpCode = httpCode;
  111. }
  112. /// <devdoc>
  113. /// <para> Contructor used for derialization.</para>
  114. /// </devdoc>
  115. protected HttpException(SerializationInfo info, StreamingContext context)
  116. :base(info, context) {
  117. _httpCode = info.GetInt32("_httpCode");
  118. }
  119. /// <devdoc>
  120. /// <para>Serialize the object.</para>
  121. /// </devdoc>
  122. //[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]
  123. [SuppressMessage("Microsoft.Security", "CA2110:SecureGetObjectDataOverrides", Justification = "Base class has demand")]
  124. public override void GetObjectData(SerializationInfo info, StreamingContext context)
  125. {
  126. base.GetObjectData(info, context);
  127. info.AddValue("_httpCode", _httpCode);
  128. }
  129. /*
  130. * If we have an Http code (non-zero), return it. Otherwise, return
  131. * the inner exception's code. If there isn't one, return 500.
  132. */
  133. /// <devdoc>
  134. /// <para>HTTP return code to send back to client. If there is a
  135. /// non-zero Http code, it is returned. Otherwise, the System.HttpException.innerException
  136. /// code is returned. If
  137. /// there isn't an inner exception, error code 500 is returned.</para>
  138. /// </devdoc>
  139. public int GetHttpCode() {
  140. return GetHttpCodeForException(this);
  141. }
  142. internal void SetFormatter(ErrorFormatter errorFormatter) {
  143. _errorFormatter = errorFormatter;
  144. }
  145. internal static int GetHttpCodeForException(Exception e) {
  146. if (e is HttpException) {
  147. HttpException he = (HttpException)e;
  148. // If the HttpException specifies an HTTP code, use it
  149. if (he._httpCode > 0)
  150. return he._httpCode;
  151. }
  152. /*
  153. 404 conversion is done in HttpAplpication.MapHttpHandler
  154. else if (e is FileNotFoundException || e is DirectoryNotFoundException)
  155. {
  156. code = 404;
  157. }
  158. */
  159. else if (e is UnauthorizedAccessException) {
  160. return 401;
  161. }
  162. else if (e is PathTooLongException) {
  163. return 414;
  164. }
  165. // If there is an inner exception, try to get the code from it
  166. if (e.InnerException != null)
  167. return GetHttpCodeForException(e.InnerException);
  168. // If all else fails, use 500
  169. return 500;
  170. }
  171. /*
  172. * Return the formatter associated with this exception
  173. */
  174. internal static ErrorFormatter GetErrorFormatter(Exception e) {
  175. Exception inner = e.InnerException;
  176. ErrorFormatter nestedFormatter = null;
  177. // First, see if the inner exception has a formatter
  178. if (inner != null) {
  179. nestedFormatter = GetErrorFormatter(inner);
  180. if (nestedFormatter != null)
  181. return nestedFormatter;
  182. if (inner is ConfigurationException)
  183. {
  184. ConfigurationException ce = inner as ConfigurationException;
  185. if (ce != null && ce.Filename != null)
  186. nestedFormatter = new ConfigErrorFormatter((ConfigurationException)inner);
  187. }
  188. else if (inner is SecurityException)
  189. nestedFormatter = new SecurityErrorFormatter(inner);
  190. }
  191. // If it does, return it rather than our own
  192. if (nestedFormatter != null)
  193. return nestedFormatter;
  194. HttpException httpExc = e as HttpException;
  195. if (httpExc != null)
  196. return httpExc._errorFormatter;
  197. return null;
  198. }
  199. /// <devdoc>
  200. /// <para>[To be supplied.]</para>
  201. /// </devdoc>
  202. public string GetHtmlErrorMessage() {
  203. ErrorFormatter formatter = GetErrorFormatter(this);
  204. if (formatter == null) return null;
  205. return formatter.GetHtmlErrorMessage();
  206. }
  207. public int WebEventCode {
  208. get { return _webEventCode; }
  209. internal set { _webEventCode = value; }
  210. }
  211. }
  212. /// <devdoc>
  213. /// <para> Exception thrown when a generic error occurs.</para>
  214. /// </devdoc>
  215. [Serializable]
  216. public sealed class HttpUnhandledException : HttpException {
  217. public HttpUnhandledException() {}
  218. public HttpUnhandledException(String message)
  219. : base(message) {
  220. }
  221. public HttpUnhandledException(string message, Exception innerException)
  222. : base(message, innerException) {
  223. SetFormatter(new UnhandledErrorFormatter(innerException, message, null));
  224. }
  225. /// <internalonly/>
  226. internal HttpUnhandledException(string message, string postMessage, Exception innerException)
  227. : base(message, innerException) {
  228. SetFormatter(new UnhandledErrorFormatter(innerException, message, postMessage));
  229. }
  230. private HttpUnhandledException(SerializationInfo info, StreamingContext context)
  231. :base(info, context) {
  232. }
  233. }
  234. /// <devdoc>
  235. /// <para> Exception thrown when a compilation error occurs.</para>
  236. /// </devdoc>
  237. [Serializable]
  238. public sealed class HttpCompileException : HttpException {
  239. private CompilerResults _results;
  240. private string _sourceCode;
  241. public HttpCompileException() {
  242. }
  243. public HttpCompileException(string message) : base(message) {
  244. }
  245. public HttpCompileException(String message, Exception innerException) : base(message, innerException) {
  246. }
  247. public HttpCompileException(CompilerResults results, string sourceCode) {
  248. _results = results;
  249. _sourceCode = sourceCode;
  250. SetFormatter(new DynamicCompileErrorFormatter(this));
  251. }
  252. private HttpCompileException(SerializationInfo info, StreamingContext context)
  253. :base(info, context) {
  254. _results = (CompilerResults) info.GetValue("_results", typeof(CompilerResults));
  255. _sourceCode = info.GetString("_sourceCode");
  256. }
  257. // Determines whether the compile exception should be cached
  258. private bool _dontCache;
  259. internal bool DontCache {
  260. get { return _dontCache; }
  261. set { _dontCache = value; }
  262. }
  263. // The virtualpath depdencies for current buildresult.
  264. private ICollection _virtualPathDependencies;
  265. internal ICollection VirtualPathDependencies {
  266. get { return _virtualPathDependencies; }
  267. set { _virtualPathDependencies = value; }
  268. }
  269. /// <devdoc>
  270. /// <para>Serialize the object.</para>
  271. /// </devdoc>
  272. [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]
  273. public override void GetObjectData(SerializationInfo info, StreamingContext context)
  274. {
  275. base.GetObjectData(info, context);
  276. info.AddValue("_results", _results);
  277. info.AddValue("_sourceCode", _sourceCode);
  278. }
  279. private const string compileErrorFormat = "{0}({1}): error {2}: {3}";
  280. /// <devdoc>
  281. /// <para> The first compilation error.</para>
  282. /// </devdoc>
  283. public override string Message {
  284. get {
  285. // Return the first compile error as the exception message
  286. CompilerError e = FirstCompileError;
  287. if (e == null)
  288. return base.Message;
  289. string message = String.Format(CultureInfo.CurrentCulture, compileErrorFormat,
  290. e.FileName, e.Line, e.ErrorNumber, e.ErrorText);
  291. return message;
  292. }
  293. }
  294. /// <devdoc>
  295. /// <para> The CompilerResults object describing the compile error.</para>
  296. /// </devdoc>
  297. public CompilerResults Results {
  298. [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.High)]
  299. get {
  300. return _results;
  301. }
  302. }
  303. internal CompilerResults ResultsWithoutDemand {
  304. get {
  305. return _results;
  306. }
  307. }
  308. /// <devdoc>
  309. /// <para> The source code that was compiled.</para>
  310. /// </devdoc>
  311. public string SourceCode {
  312. [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.High)]
  313. get {
  314. return _sourceCode;
  315. }
  316. }
  317. internal string SourceCodeWithoutDemand {
  318. get {
  319. return _sourceCode;
  320. }
  321. }
  322. // Return the first compile error, or null if there isn't one
  323. internal CompilerError FirstCompileError {
  324. get {
  325. if (_results == null || !_results.Errors.HasErrors)
  326. return null;
  327. CompilerError e = null;
  328. foreach (CompilerError error in _results.Errors) {
  329. // Ignore warnings
  330. if (error.IsWarning) continue;
  331. // If we found an error that's not in the generated code, use it
  332. if (HttpRuntime.CodegenDirInternal != null && error.FileName != null &&
  333. !StringUtil.StringStartsWith(error.FileName, HttpRuntime.CodegenDirInternal)) {
  334. e = error;
  335. break;
  336. }
  337. // The current error is in the generated code. Keep track of
  338. // it if it's the first one, but keep on looking in case we find another
  339. // one that's not in the generated code (ASURT 62600)
  340. if (e == null)
  341. e = error;
  342. }
  343. return e;
  344. }
  345. }
  346. }
  347. /// <devdoc>
  348. /// <para> Exception thrown when a parse error occurs.</para>
  349. /// </devdoc>
  350. [Serializable]
  351. public sealed class HttpParseException : HttpException {
  352. private VirtualPath _virtualPath;
  353. private int _line;
  354. private ParserErrorCollection _parserErrors;
  355. public HttpParseException() {
  356. }
  357. public HttpParseException(string message) : base(message) {
  358. }
  359. public HttpParseException(String message, Exception innerException) : base(message, innerException) {
  360. }
  361. public HttpParseException(string message, Exception innerException, string virtualPath,
  362. string sourceCode, int line) : this(message, innerException,
  363. System.Web.VirtualPath.CreateAllowNull(virtualPath), sourceCode, line) {}
  364. internal HttpParseException(string message, Exception innerException, VirtualPath virtualPath,
  365. string sourceCode, int line)
  366. : base(message, innerException) {
  367. _virtualPath = virtualPath;
  368. _line = line;
  369. string formatterMessage;
  370. if (innerException != null)
  371. formatterMessage = innerException.Message;
  372. else
  373. formatterMessage = message;
  374. SetFormatter(new ParseErrorFormatter(this, System.Web.VirtualPath.GetVirtualPathString(virtualPath), sourceCode,
  375. line, formatterMessage));
  376. }
  377. private HttpParseException(SerializationInfo info, StreamingContext context)
  378. :base(info, context) {
  379. _virtualPath = (VirtualPath)info.GetValue("_virtualPath", typeof(VirtualPath));
  380. _line = info.GetInt32("_line");
  381. _parserErrors = (ParserErrorCollection)info.GetValue("_parserErrors", typeof(ParserErrorCollection));
  382. }
  383. /// <devdoc>
  384. /// <para>Serialize the object.</para>
  385. /// </devdoc>
  386. [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter=true)]
  387. public override void GetObjectData(SerializationInfo info, StreamingContext context)
  388. {
  389. base.GetObjectData(info, context);
  390. info.AddValue("_virtualPath", _virtualPath);
  391. info.AddValue("_line", _line);
  392. info.AddValue("_parserErrors", _parserErrors);
  393. }
  394. /// <devdoc>
  395. /// <para> The physical path to source file that has the error.</para>
  396. /// </devdoc>
  397. public string FileName {
  398. get {
  399. string physicalPath = _virtualPath.MapPathInternal();
  400. if (physicalPath == null)
  401. return null;
  402. // Demand path discovery before returning the path (ASURT 123798)
  403. InternalSecurityPermissions.PathDiscovery(physicalPath).Demand();
  404. return physicalPath;
  405. }
  406. }
  407. /// <devdoc>
  408. /// <para> The virtual path to source file that has the error.</para>
  409. /// </devdoc>
  410. public string VirtualPath {
  411. get {
  412. return System.Web.VirtualPath.GetVirtualPathString(_virtualPath);
  413. }
  414. }
  415. internal VirtualPath VirtualPathObject {
  416. get {
  417. return _virtualPath;
  418. }
  419. }
  420. /// <devdoc>
  421. /// <para> The CompilerResults object describing the compile error.</para>
  422. /// </devdoc>
  423. public int Line {
  424. get { return _line;}
  425. }
  426. // The set of parser errors
  427. public ParserErrorCollection ParserErrors {
  428. get {
  429. if (_parserErrors == null) {
  430. _parserErrors = new ParserErrorCollection();
  431. ParserError thisError = new ParserError(Message, _virtualPath, _line);
  432. _parserErrors.Add(thisError);
  433. }
  434. return _parserErrors;
  435. }
  436. }
  437. }
  438. /// <devdoc>
  439. /// <para> Exception thrown when a potentially unsafe input string is detected (ASURT 122278)</para>
  440. /// </devdoc>
  441. [Serializable]
  442. public sealed class HttpRequestValidationException : HttpException {
  443. public HttpRequestValidationException() {
  444. }
  445. public HttpRequestValidationException(string message) : base(message) {
  446. SetFormatter(new UnhandledErrorFormatter(
  447. this, SR.GetString(SR.Dangerous_input_detected_descr), null));
  448. }
  449. public HttpRequestValidationException(String message, Exception innerException) : base(message, innerException) {
  450. }
  451. private HttpRequestValidationException(SerializationInfo info, StreamingContext context)
  452. :base(info, context) {
  453. }
  454. }
  455. [Serializable]
  456. public sealed class ParserError {
  457. private int _line;
  458. private VirtualPath _virtualPath;
  459. private string _errorText;
  460. private Exception _exception;
  461. public ParserError() {
  462. }
  463. public ParserError(string errorText, string virtualPath, int line)
  464. : this(errorText, System.Web.VirtualPath.CreateAllowNull(virtualPath), line) {
  465. }
  466. internal ParserError(string errorText, VirtualPath virtualPath, int line) {
  467. _virtualPath = virtualPath;
  468. _line = line;
  469. _errorText = errorText;
  470. }
  471. // The original exception that introduces the Parser Error
  472. internal Exception Exception {
  473. get { return _exception; }
  474. set { _exception = value; }
  475. }
  476. // The virtualPath where the parser error occurs.
  477. public string VirtualPath {
  478. get { return System.Web.VirtualPath.GetVirtualPathString(_virtualPath); }
  479. set { _virtualPath = System.Web.VirtualPath.Create(value); }
  480. }
  481. // The description error text of the error.
  482. public string ErrorText {
  483. get { return _errorText; }
  484. set { _errorText = value; }
  485. }
  486. // The line where the parser error occurs.
  487. public int Line {
  488. get { return _line; }
  489. set { _line = value; }
  490. }
  491. }
  492. [Serializable]
  493. public sealed class ParserErrorCollection : CollectionBase {
  494. public ParserErrorCollection() {
  495. }
  496. public ParserErrorCollection(ParserError[] value) {
  497. this.AddRange(value);
  498. }
  499. public ParserError this[int index] {
  500. get { return ((ParserError)List[index]); }
  501. set { List[index] = value; }
  502. }
  503. public int Add(ParserError value) {
  504. return List.Add(value);
  505. }
  506. public void AddRange(ParserError[] value) {
  507. if (value == null) {
  508. throw new ArgumentNullException("value");
  509. }
  510. for (int i = 0; i < value.Length; i++) {
  511. this.Add(value[i]);
  512. }
  513. }
  514. public void AddRange(ParserErrorCollection value) {
  515. if (value == null) {
  516. throw new ArgumentNullException("value");
  517. }
  518. foreach(ParserError parserError in value) {
  519. this.Add(parserError);
  520. }
  521. }
  522. public bool Contains(ParserError value) {
  523. return List.Contains(value);
  524. }
  525. public void CopyTo(ParserError[] array, int index) {
  526. List.CopyTo(array, index);
  527. }
  528. public int IndexOf(ParserError value) {
  529. return List.IndexOf(value);
  530. }
  531. public void Insert(int index, ParserError value) {
  532. List.Insert(index, value);
  533. }
  534. public void Remove(ParserError value) {
  535. List.Remove(value);
  536. }
  537. }
  538. }