10 votes

HttpWebRequest.Headers.Add("Cookie",value) vs HttpWebRequest.CookieContainer

Lorsque je reçois une réponse de HttpWebRequest avec HttpWebRequest.Headers.Add("Cookie", value) par rapport à HttpWebRequest.CookieContainer, et les résultats sont différents.

Alors, quelle est la différence entre eux et quand les utiliser.

8voto

Cameron Tinker Points 4158

De mon expérience, j'ai eu quelques problèmes avec l'utilisation de HttpWebRequest.CookieContainer pour gérer les cookies. Cela peut fonctionner dans une certaine mesure, mais parfois les cookies ne sont pas conformes à la RFC et ne sont pas analysés correctement dans le CookieContainer. Si vous gérez vos cookies manuellement en les ajoutant à l'en-tête Cookie de la requête, vous aurez plus de succès avec certains sites qui ne sont pas conformes à la RFC. Un des problèmes avec CookieContainer est que s'il y a une date avec une virgule dans la date comme "26 septembre 2013", il l'analysera comme un cookie totalement séparé et la parse incorrectement. Un autre problème est que les cookies définis sur une redirection HTTP 302 ne seront pas pris en compte par le CookieContainer.

C'est à vous de décider ce qui est le mieux pour vos besoins spécifiques, mais si les problèmes avec le CookieContainer donnent des résultats différents de la définition manuelle de l'en-tête du cookie, je vous recommande de continuer à définir manuellement l'en-tête du cookie. Espérons que Microsoft mettra à jour cela à l'avenir afin que nous puissions revenir à l'utilisation des classes .NET pour gérer les cookies.

Éditer :
Je suis tombé sur du code qui analyse correctement un en-tête "Set-Cookie". Il gère les cookies séparés par des virgules et extrait le nom, l'expiration, le chemin, la valeur et le domaine de chaque cookie.

Ce code fonctionne mieux que l'analyseur de cookies de Microsoft et c'est vraiment ce que le parseur de cookies officiel devrait faire. Je n'ai aucune idée pourquoi Microsoft n'a pas encore corrigé cela puisque c'est un problème très courant.

Voici le code original : http://snipplr.com/view/4427/

Je le poste ici au cas où le lien deviendrait indisponible à un moment donné :

public static CookieCollection GetAllCookiesFromHeader(string strHeader, string strHost)
{
    ArrayList al = new ArrayList();
    CookieCollection cc = new CookieCollection();
    if (strHeader != string.Empty)
    {
        al = ConvertCookieHeaderToArrayList(strHeader);
        cc = ConvertCookieArraysToCookieCollection(al, strHost);
    }
    return cc;
}

private static ArrayList ConvertCookieHeaderToArrayList(string strCookHeader)
{
    strCookHeader = strCookHeader.Replace("\r", "");
    strCookHeader = strCookHeader.Replace("\n", "");
    string[] strCookTemp = strCookHeader.Split(',');
    ArrayList al = new ArrayList();
    int i = 0;
    int n = strCookTemp.Length;
    while (i < n)
    {
        if (strCookTemp[i].IndexOf("expires=", StringComparison.OrdinalIgnoreCase) > 0)
        {
            al.Add(strCookTemp[i] + "," + strCookTemp[i + 1]);
            i = i + 1;
        }
        else
        {
            al.Add(strCookTemp[i]);
        }
        i = i + 1;
    }
    return al;
}

private static CookieCollection ConvertCookieArraysToCookieCollection(ArrayList al, string strHost)
{
    CookieCollection cc = new CookieCollection();

    int alcount = al.Count;
    string strEachCook;
    string[] strEachCookParts;
    for (int i = 0; i < alcount; i++)
    {
        strEachCook = al[i].ToString();
        strEachCookParts = strEachCook.Split(';');
        int intEachCookPartsCount = strEachCookParts.Length;
        string strCNameAndCValue = string.Empty;
        string strPNameAndPValue = string.Empty;
        string strDNameAndDValue = string.Empty;
        string[] NameValuePairTemp;
        Cookie cookTemp = new Cookie();

        for (int j = 0; j < intEachCookPartsCount; j++)
        {
            if (j == 0)
            {
                strCNameAndCValue = strEachCookParts[j];
                if (strCNameAndCValue != string.Empty)
                {
                    int firstEqual = strCNameAndCValue.IndexOf("=");
                    string firstName = strCNameAndCValue.Substring(0, firstEqual);
                    string allValue = strCNameAndCValue.Substring(firstEqual + 1, strCNameAndCValue.Length - (firstEqual + 1));
                    cookTemp.Name = firstName;
                    cookTemp.Value = allValue;
                }
                continue;
            }
            if (strEachCookParts[j].IndexOf("path", StringComparison.OrdinalIgnoreCase) >= 0)
            {
                strPNameAndPValue = strEachCookParts[j];
                if (strPNameAndPValue != string.Empty)
                {
                    NameValuePairTemp = strPNameAndPValue.Split('=');
                    if (NameValuePairTemp[1] != string.Empty)
                    {
                        cookTemp.Path = NameValuePairTemp[1];
                    }
                    else
                    {
                        cookTemp.Path = "/";
                    }
                }
                continue;
            }

            if (strEachCookParts[j].IndexOf("domain", StringComparison.OrdinalIgnoreCase) >= 0)
            {
                strPNameAndPValue = strEachCookParts[j];
                if (strPNameAndPValue != string.Empty)
                {
                    NameValuePairTemp = strPNameAndPValue.Split('=');

                    if (NameValuePairTemp[1] != string.Empty)
                    {
                        cookTemp.Domain = NameValuePairTemp[1];
                    }
                    else
                    {
                        cookTemp.Domain = strHost;
                    }
                }
                continue;
            }
        }

        if (cookTemp.Path == string.Empty)
        {
            cookTemp.Path = "/";
        }
        if (cookTemp.Domain == string.Empty)
        {
            cookTemp.Domain = strHost;
        }
        cc.Add(cookTemp);
    }
    return cc;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X