1

このCookieをWebサーバーからSet-Cookieヘッダーで返しました。

PHPSESSID = 462rutd8g0sbg9sinh3hqa2ol6; path = /、wordpress_test_cookie = WP + Cookie + check; path = /、wordpress_ca07030412dd7fcd4dbeaae0bd9f5df9 = testemail@example.com; Expires = Sun、01-Jul-2012 05:11:02 GMT; path = / wp-content / plugins; httponly、wordpress_ca07030412dd7fcd4dbeaae0bd9f5df9 = testemail@example.com; Expires = Sun、01-Jul-2012 05:11:02 GMT; path = / wp-admin; httponly、wordpress_logged_in_ca07030412dd7fcd4dbeaae0bd9f5df9 = testemail@example.com; Expires = Sun、01-Jul-2012 05:11:02 GMT; パス=/; httponly

使用しようとしていますCookieContainer.SetCookies(new Uri(url),cookie);

ただし、例外'{"UriのCookieヘッダーの解析中にエラーが発生しました' http://www.smallbizads.us/'。"}System.FormatException {System.Net.CookieException'

いくつか掘り下げると、SetCookiesがCookieを分割するためにを使用していることがわかります。しかし、私はExpiresヘッダーを持っているので、それは明らかに機能しません。,

この問題を回避するにはどうすればよいですか?

注:Set-Cookie Wordpressの問題により、このメソッドを使用するには、ヘッダーからCookieを取得する必要があります。したがって、他のオプションを提案しないでください。

4

2 に答える 2

3

それを分析するのにしばらく時間がかかりました。

私が見る限り、WordPressによって生成されたPHPSESSID(PHPセッションID)を1つのドメイン(.smallbizads.us)に対して複数のパスに設定したいと考えています。有効期限は常に同じです。

まず、Cookieヘッダーを取得します。

string cookieHeader = "PHPSESSID=462rutd8g0sbg9sinh3hqa2ol6; ...etc;"

';'で分割します 区切り文字。

var cookies = cookieHeader.Split(new[] {';'}).ToList();

最終的に12個のアイテムのリストが表示されます。例えば:

  • "PHPSESSID = 462rutd8g0sbg9sinh3hqa2ol6"
  • "path = /、wordpress_test_cookie = WP + Cookie + check"
  • "expires = Sun、01-Jul-2012 05:11:02GMT"
  • ..。

このリストには有効期限が複数回表示されますが、常に同じ値になります。最初の有効期限を取得して、それをDateTimeに変換するだけです。

var expiresValue = (from c in cookies
                    where c.Trim().StartsWith("expires")
                    select c).First();
var expiresOn = DateTime.Parse(expiresValue.Substring(expiresValue.IndexOf('=') + 1));

では、Cookieの値を取得しましょう。セッションID:

var sessionId = (from c in cookies
                 where c.Trim().StartsWith("PHPSESSID")
                 select c).Single();
sessionId = sessionId.Substring(sessionId.IndexOf('=') + 1);

次に、Cookieを設定する必要があるパスを取得します。

var paths = (from c in cookies
             where c.Trim().StartsWith("path=")
             select c).ToList();

これで、CookieContainerとSystem.Net.Cookieクラスを使用してCookieを設定できます。

foreach (var path in paths)
{
    var cookie = new Cookie();
    cookie.Name = "PHPSESSID";
    cookie.Value = sessionId;
    cookie.Domain = ".smallbizads.us";
    cookie.Expires = expiresOn;
    cookie.HttpOnly = true;

    var container = new CookieContainer();

    var startIndex = path.IndexOf('=') + 1;
    var stopIndex = path.Contains(',') ? path.IndexOf(',') : path.Length;
    cookie.Path = path.Substring(startIndex, stopIndex - startIndex);

    container.Add(cookie);
}
于 2012-06-17T06:28:55.147 に答える
0

曜日は追加情報を追加せず、日付はそれなしで解析できることに注意して、正規表現を使用して曜日とカンマを削除できます。の代わりに使用する拡張メソッドは次のとおりですCookieContainer.SetCookies()

/// <summary>
/// Although it's invalid, in the wild we sometimes see a Set-Cookie header with the form "Name=Value; expires=Sun, 23-Dec-2012 12:25:37 GMT".
/// Multiple cookies can be set with one header, comma separated, so CookieContainer.SetCookies() can't parse this due to the comma in the date.
/// Fortunately, the DayOfWeek provides no useful information, and the date can be parsed without it, so this removes the day and comma.
/// </summary>
public static void SetCookiesWithExpires(this CookieContainer cookies, Uri uri, String cookieHeader) {
    // Note: The Regex may be created more than once in different threads. No problem; all but the last will be garbage collected.
    Regex expiresEqualsDay = _expiresEqualsDay ?? (_expiresEqualsDay = new Regex(EXPIRES_EQUALS_DAY_PATTERN, RegexOptions.IgnoreCase | RegexOptions.Compiled));
    cookies.SetCookies(uri, expiresEqualsDay.Replace(cookieHeader, EXPIRES_EQUALS));
}
private static Regex _expiresEqualsDay;     // Lazy-initialized.
private const String EXPIRES_EQUALS_DAY_PATTERN = "; *expires=[A-Za-z]+, *";
private const String EXPIRES_EQUALS = "; Expires=";
于 2012-12-26T15:41:06.043 に答える