Merge pull request #3386 from alexanderkyte/nunit_lite_return_status
[mono.git] / mcs / class / referencesource / System.Web / Util / RequestValidator.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="RequestValidator.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6
7 /*
8  * Base class providing extensibility hooks for custom request validation
9  *
10  * Copyright (c) 2009 Microsoft Corporation
11  */
12
13 namespace System.Web.Util {
14     using System;
15     using System.Diagnostics.CodeAnalysis;
16     using System.Threading;
17     using System.Web;
18     using System.Web.Configuration;
19
20     public class RequestValidator {
21
22         private static RequestValidator _customValidator;
23
24         private static readonly Lazy<RequestValidator> _customValidatorResolver =
25             new Lazy<RequestValidator>(GetCustomValidatorFromConfig);
26
27         public static RequestValidator Current {
28             get {
29                 if (_customValidator == null) {
30                     _customValidator = _customValidatorResolver.Value;
31                 }
32                 return _customValidator;
33             }
34             set {
35                 if (value == null) {
36                     throw new ArgumentNullException("value");
37                 }
38                 _customValidator = value;
39             }
40         }
41
42         private static RequestValidator GetCustomValidatorFromConfig() {
43             // App since this is static per AppDomain
44             RuntimeConfig config = RuntimeConfig.GetAppConfig();
45             HttpRuntimeSection runtimeSection = config.HttpRuntime;
46             string validatorTypeName = runtimeSection.RequestValidationType;
47
48             // validate the type
49             Type validatorType = ConfigUtil.GetType(validatorTypeName, "requestValidationType", runtimeSection);
50             ConfigUtil.CheckBaseType(typeof(RequestValidator) /* expectedBaseType */, validatorType, "requestValidationType", runtimeSection);
51
52             // instantiate
53             RequestValidator validator = (RequestValidator)HttpRuntime.CreatePublicInstance(validatorType);
54             return validator;
55         }
56
57         internal static void InitializeOnFirstRequest() {
58             // instantiate the validator if it hasn't already been created
59             RequestValidator validator = _customValidatorResolver.Value;
60         }
61
62         // Public entry point to the IsValidRequestString method. That method shipped protected, and making it public would
63         // unfortunately be a breaking change. Having a public entry point allows third parties to write wrapper classes
64         // around RequestValidator instances.
65         [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters",
66                  Justification = "This is an appropriate way to return multiple pieces of data.")]
67         public bool InvokeIsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex) {
68             return IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
69         }
70
71         private static bool IsAtoZ(char c) {
72             return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
73         }
74
75         [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters",
76                  Justification = "This is an appropriate way to return multiple pieces of data.")]
77         protected internal virtual bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex) {
78             if (requestValidationSource == RequestValidationSource.Headers) {
79                 validationFailureIndex = 0;
80                 return true; // Ignore Headers collection in the default implementation
81             }
82             return !CrossSiteScriptingValidation.IsDangerousString(value, out validationFailureIndex);
83         }
84
85     }
86 }