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


internal void AddCookie(HttpCookie cookie, bool append) {
ThrowIfMaxHttpCollectionKeysExceeded();

_all = null;
_allKeys = null;

if (append) {
// DevID 251951 Cookie is getting duplicated by ASP.NET when they are added via a native module
// Need to not double add response cookies from native modules
if (!cookie.FromHeader) {
// mark cookie as new
cookie.Added = true;
}
BaseAdd(cookie.Name, cookie);
}
else {
if (BaseGet(cookie.Name) != null) {
// mark the cookie as changed because we are overriding the existing one
cookie.Changed = true;
}
BaseSet(cookie.Name, cookie);
}
}
private void ThrowIfMaxHttpCollectionKeysExceeded() {
if (Count >= AppSettings.MaxHttpCollectionKeys) {
throw new InvalidOperationException(SR.GetString(SR.CollectionCountExceeded_HttpValueCollection, AppSettings.MaxHttpCollectionKeys));
}
}


这里的AddCookie方法也非常简单,不过每次添加都会去检查Cookie的个数是否超过最大值。其实添加Cookie还可以调用HttpResponse的AppendCookie方法,

复制代码 代码如下:


public void AppendCookie(HttpCookie cookie)
{
if (this._headersWritten)
{
throw new HttpException(SR.GetString("Cannot_append_cookie_after_headers_sent"));
}
this.Cookies.AddCookie(cookie, true);
this.OnCookieAdd(cookie);
}


这里它的实现和HttpCookieCollection的     public void Add(HttpCookie cookie)方法实现一致。
 同样我们也知道这些Cookie是在HttpResponse的GenerateResponseHeadersForCookies方法中被使用,
其中GenerateResponseHeadersForCookies方法的实现如下:

复制代码 代码如下:


internal void GenerateResponseHeadersForCookies()
{
if (_cookies == null || (_cookies.Count == 0 && !_cookies.Changed))
return; // no cookies exist

HttpHeaderCollection headers = Headers as HttpHeaderCollection;
HttpResponseHeader cookieHeader = null;
HttpCookie cookie = null;
bool needToReset = false;

// Go through all cookies, and check whether any have been added
// or changed. If a cookie was added, we can simply generate a new
// set cookie header for it. If the cookie collection has been
// changed (cleared or cookies removed), or an existing cookie was
// changed, we have to regenerate all Set-Cookie headers due to an IIS
// limitation that prevents us from being able to delete specific
// Set-Cookie headers for items that changed.
if (!_cookies.Changed)
{
for(int c = 0; c < _cookies.Count; c++)
{
cookie = _cookies[c];
if (cookie.Added) {
// if a cookie was added, we generate a Set-Cookie header for it
cookieHeader = cookie.GetSetCookieHeader(_context);
headers.SetHeader(cookieHeader.Name, cookieHeader.Value, false);
cookie.Added = false;
cookie.Changed = false;
}
else if (cookie.Changed) {
// if a cookie has changed, we need to clear all cookie
// headers and re-write them all since we cant delete
// specific existing cookies
needToReset = true;
break;
}
}
}


if (_cookies.Changed || needToReset)
{
// delete all set cookie headers
headers.Remove("Set-Cookie");

// write all the cookies again
for(int c = 0; c < _cookies.Count; c++)
{
// generate a Set-Cookie header for each cookie
cookie = _cookies[c];
cookieHeader = cookie.GetSetCookieHeader(_context);
headers.SetHeader(cookieHeader.Name, cookieHeader.Value, false);
cookie.Added = false;
cookie.Changed = false;
}

_cookies.Changed = false;
}
}


这里我们还是来总结一下吧:在HttpWorkerRequest中我们调用 GetKnownRequestHeader方法来获取Cookie的字符串形式,然后再将这里的字符串转化为HttpCookie集合供 HttpRequest使用,在HttpResponse中的GenerateResponseHeadersForCookies方法中会处理我们的 cookie实例,调用cookie的GetSetCookieHeader方法得到HttpCookie对应的字符串值,然后把该值添加到 HttpHeaderCollection 集合中(或者修改已有的值)。在获取cookie是这里有一个验证需要我们注意的就是 RequestValidator.Current.IsValidRequestString方法。   在添加或修改Cookie是有2个地方的检查(1)检查Cookie的个数是否达到我们配置的cookie最大个数,(2)现在是否已经写入头信息,如果 头信息已经写了则不能操作cookie。

您可能感兴趣的文章:

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

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