2

私はサイトをクロールするために使用HttpWebRequestしています。HttpWebResponseリクエストごとに同じものを使用しておりCookieContainer、Cookieが自動的に処理されるようにしています。

ただし、リクエストの1つには、前のレスポンスで設定された特定のCookieが必要です。これはコレクションに存在しますが、そのPathプロパティは正しくないように見えます。RFC2109 (ページ7)によると、Cookieが空白のパスで設定されている場合(このように)、パスはリクエストのURLに設定する必要がありますが、最後のスラッシュは含まれません。実際に起こっていることは、URLパス全体に設定されていることです。つまり、同じサブドメイン内の別のURLでCookieを後で読み取ることはできません。

例:

  1. http://www.myserver.com/sub/mypage.phpでページをリクエストします
  2. 応答には、mycookie=12345Set-Cookieを読み取るヘッダーが含まれています。有効期限=2012年6月27日水曜日16:20:00GMT
  3. Cookieが.NETCookieCollectionに追加されます。パスが設定されていないため、パスが/sub/mypage.phpに誤って初期化されています
  4. 同じサブドメインの下に別のページをリクエストしましたが、これにはmycookie cookieが必要です(例:http ://www.myserver.com/sub/anotherpage.php)。
  5. パスが完全に一致しないため、Cookieは.NETによって提供されません。パスが/subの場合、正しく提供されているはずです

FirebugおよびFirecookie拡張機能を備えたFirefoxブラウザを使用して同じナビゲーション手順を実行しました。パスは、実際のブラウザセッションで正しく設定されています。つまり、サブドメインに設定されています。

誰かがこれを確認し、おそらくこの問題の回避策または修正を指摘できますか?どうもありがとう。

4

1 に答える 1

3

これが問題の内部コードのビットです。偶発的なバグのようには見えません。ただし、標準に準拠していない場合は、問題を報告する必要があります。

switch (this.m_cookieVariant)
{
    case CookieVariant.Plain:
        this.m_path = absolutePath;
        break;

    case CookieVariant.Rfc2109:
        this.m_path = absolutePath.Substring(0, absolutePath.LastIndexOf('/'));
        break;

    default:
        this.m_path = absolutePath.Substring(0, absolutePath.LastIndexOf('/') + 1);
        break;
}

したがって、Cookie自体で特に指定されていない限り、プレーンCookieバリアントを使用します。

すべてのCookieチェックを繰り返す必要があります。本当にこれは私が.netのクッキー処理を嫌う多くの理由の1つです。すべてのドメイン/Cookieを簡単に取得することはできません。最も簡単な修正は、次のことを行うことです。ただし、Cookieが重複することになります。したがって、代わりにURIでCookieを取得することをお勧めします。

public static CookieCollection FixCookies(CookieCollection collection)
{
    foreach (Cookie cookie in collection)
    {
        if (string.IsNullOrEmpty(cookie.Path))
            continue;

        int idx = cookie.Path.LastIndexOf('/');
        if (idx == -1)
            continue;

        cookie.Path = cookie.Path.Substring(0, idx);
    }
    return collection;
}

[STAThread]
private static void Main(string[] args)
{
    var http = (HttpWebRequest)WebRequest.Create("http://localhost/test/test.php");
    http.CookieContainer = new CookieContainer();
    var resp = (HttpWebResponse)http.GetResponse();
    http.CookieContainer.Add(FixCookies(resp.Cookies));
}
于 2012-06-27T18:07:38.923 に答える