• 终于找到问题了,原来是.net framework2.0,3.0,3.5的CookieContainer的bug解决方法


    找了 很久都发现不出问题,最后终于发现原来是微软的一个BUG

    用HttpWebRequest发送请求,附上了CookieContainer(CookieContainer里面确定已经包含了所有需要的 Cookie),但是当发送请求后某些Cookie并没有发送出去,调试了两天,一直觉得是请求的网站设了什么古怪的限制,使请求老是发送不成功,最后用 SocketSniff抓包发现少发送了几个Cookie(因为这些cookie涉及到几个子域名),检查CookieContainer,里面确实有这 几个Cookie,最后只好反编译HttpWebRequest,在类CookieModule里发现方法OnSendingHeaders的如下代码, 这个是把cookie设置到headers里面的关键地方:

    internal static void OnSendingHeaders(HttpWebRequest httpWebRequest)
    {
    try
    {
    if (httpWebRequest.CookieContainer != null)
    {
    string str;
    httpWebRequest.Headers.RemoveInternal("Cookie");
    string cookieHeader = httpWebRequest.CookieContainer.GetCookieHeader(httpWebRequest.Address, out str);
    if (cookieHeader.Length > 0)
    {
    httpWebRequest.Headers["Cookie"] = cookieHeader;
    }
    }
    }
    catch
    {
    }
    }
    问题出在GetCookieHeader这个方法里面,某些Cookie的domain判断错误导致没有附加上去。.Net framework4.0以下的都存在此问题。最后把程序框架调到4.0的,就没有这个问题了。当然4.0以下的框架版本可以用下面的方法处理一下 CookieContainer里面domain。
    1. Don't use .Add(Cookie), Use only .Add(Uri, Cookie) method.
    2. Call BugFix_CookieDomain each time you add a cookie to the container or before you use .GetCookie or before system use the container.



    private void BugFix_CookieDomain(CookieContainer cookieContainer)
    {
        System.Type _ContainerType 
    = typeof(CookieContainer);
        Hashtable table 
    = (Hashtable)_ContainerType.InvokeMember("m_domainTable",
                                   System.Reflection.BindingFlags.NonPublic 
    |
                                   System.Reflection.BindingFlags.GetField 
    |
                                   System.Reflection.BindingFlags.Instance,
                                   
    null,
                                   cookieContainer,
                                   
    new object[] { });
        ArrayList keys 
    = new ArrayList(table.Keys);
        
    foreach (string keyObj in keys)
        {
            
    string key = (keyObj as string);
            
    if (key[0== '.')
            {
                
    string newKey = key.Remove(01);
                table[newKey] 
    = table[keyObj];
            }
        }
    }
  • 相关阅读:
    通过模板类简单实现Spark的JobServer
    aggregate 和 treeAggregate 的对比
    IntelliJ Idea 常用快捷键列表
    dataframe 数据统计可视化---spark scala 应用
    用java api读取HDFS文件
    .net Core 简单中间件使用
    .Net Core Ocelot网关使用熔断、限流 二
    .Net Core Ocelot网关使用 一
    Docker 问题处理
    CentOS 创建用户
  • 原文地址:https://www.cnblogs.com/goody9807/p/2110535.html
Copyright © 2020-2023  润新知