Asp.net cookie的处理流程深入分析(2)


internal class ISAPIWorkerRequestInProcForIIS7 : ISAPIWorkerRequestInProcForIIS6
internal class ISAPIWorkerRequestInProcForIIS6 : ISAPIWorkerRequestInProc
internal class ISAPIWorkerRequestInProc : ISAPIWorkerRequest
internal abstract class ISAPIWorkerRequest : HttpWorkerRequest


其中 GetKnownRequestHeader方法的实现主要是在ISAPIWorkerRequest中,其GetKnownRequestHeader主要是调用了它的ReadRequestHeaders私有方法,在ReadRequestHeaders方法中主要是调用它的this.GetServerVariable("ALL_RAW")方法,所以我们可以认为this.GetServerVariable("ALL_RAW")这个方法是获取客户端传来的Cookie参数,而GetServerVariable方法的实现主要是在ISAPIWorkerRequestInProc 类,具体实现非常复杂。

这里的GetKnownRequestHeader方法实现非常复杂我们也就不去深研它了,我们只要知道调用这个方法就会返回Cookie的所有字符串信息。在这个方法里面还调用了一个CreateCookieFromString方法,根据字符串来创建我们的HttpCookie实例。CreateCookieFromString方法实现如下:

复制代码 代码如下:


internal static HttpCookie CreateCookieFromString(String s) {
HttpCookie c = new HttpCookie();

int l = (s != null) ? s.Length : 0;
int i = 0;
int ai, ei;
bool firstValue = true;
int numValues = 1;

// Format: cookiename[=key1=val2&key2=val2&...]

while (i < l) {
// find next &
ai = s.IndexOf('&', i);
if (ai < 0)
ai = l;

// first value might contain cookie name before =
if (firstValue) {
ei = s.IndexOf('=', i);

if (ei >= 0 && ei < ai) {
c.Name = s.Substring(i, ei-i);
i = ei+1;
}
else if (ai == l) {
// the whole cookie is just a name
c.Name = s;
break;
}

firstValue = false;
}

// find '='
ei = s.IndexOf('=', i);

if (ei < 0 && ai == l && numValues == 0) {
// simple cookie with simple value
c.Value = s.Substring(i, l-i);
}
else if (ei >= 0 && ei < ai) {
// key=value
c.Values.Add(s.Substring(i, ei-i), s.Substring(ei+1, ai-ei-1));
numValues++;
}
else {
// value without key
c.Values.Add(null, s.Substring(i, ai-i));
numValues++;
}

i = ai+1;
}

return c;
}


我们平时很少用到HttpCookie的Values属性,所以这个属性大家还是需要注意一下,这个方法就是把一个cookie的字符串转化为相应的HttpCookie实例。
现在我们回到HttpRequest的Cookies属性中来,这里有一个关于Cookie的简单验证

复制代码 代码如下:


private void ValidateCookieCollection(HttpCookieCollection cc) {
if (_enableGranularValidation) {
// Granular request validation is enabled - validate collection entries only as they're accessed.
cc.EnableGranularValidation((key, value) => ValidateString(value, key, RequestValidationSource.Cookies));
}
else {
// Granular request validation is disabled - eagerly validate all collection entries.
int c = cc.Count;

for (int i = 0; i < c; i++) {
String key = cc.GetKey(i);
String val = cc.Get(i).Value;

if (!String.IsNullOrEmpty(val))
ValidateString(val, key, RequestValidationSource.Cookies);
}
}
}


其中HttpCookieCollection的EnableGranularValidation实现如下:

复制代码 代码如下:


internal void EnableGranularValidation(ValidateStringCallback validationCallback)
{
this._keysAwaitingValidation = new HashSet<string>(this.Keys.Cast<string>(), StringComparer.OrdinalIgnoreCase);
this._validationCallback = validationCallback;
}

private void EnsureKeyValidated(string key, string value)
{
if ((this._keysAwaitingValidation != null) && this._keysAwaitingValidation.Contains(key))
{
if (!string.IsNullOrEmpty(value))
{
this._validationCallback(key, value);
}
this._keysAwaitingValidation.Remove(key);
}
}



到这里我们知道默认从浏览器发送到服务器端的Cookie都是需要经过次验证的。这里的ValidateString方法具体实现我们就不说了,不过大家需要知道它是调用了RequestValidator.Current.IsValidRequestString方法来实现验证的,有关RequestValidator的信息大家可以查看HttpRequest的QueryString属性 的一点认识 。现在我们获取Cookie已经基本完成了。那么我们接下来看看是如何添加Cookie的了。

首先我们来看看HttpResponse的Cookie属性:

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjdfjp.html