ページ

2009年9月2日水曜日

NSHTTPCookieStorage相当のクラスを自前で実装する (7)クッキー送出のロジックを改良〜実装

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

ざっくりとした実装ができた。

仕様は以前紹介した通り。

Cocoaの日々
NSHTTPCookieStorage相当のクラスを自前で実装する (6)クッキー送出のロジックを改良


サンプル:CookieStorage-3.zip


まずはクッキー取得から。
XCHTTPCookieStorage.m

- (void)setCookie:(NSHTTPCookie *)cookie
{
NSString* key1 = [cookie domain];
NSString* key2 = [NSString stringWithFormat:@"%@/%@", [cookie path], [cookie name]];

NSMutableDictionary* cookies2 = [_cookies valueForKey:key1];
if (!cookies2) {
cookies2 = [NSMutableDictionary dictionary];
[_cookies setValue:cookies2 forKey:key1];
}
[cookies2 setValue:cookie forKey:key2];
}


ドメインをキーにして辞書を作成する。この辞書には path/name をキーとしてクッキーを格納する。


次に取得。変更がはいったポイントのみ解説する。
- (NSArray *)cookiesForURL:(NSURL *)URL
{
NSMutableArray* return_cookies = [NSMutableArray array];
NSString* url_path = [URL path];
NSString* url_domain = [URL host];
NSDate* date = [NSDate date];
BOOL is_secure = [[URL scheme] isEqualToString:@"https"];

NSArray* domain_parts = [url_domain componentsSeparatedByString:@"."];
int count = [domain_parts count];
if (count < 1) {
return return_cookies;
}

int index = [domain_parts count]-1;
NSString* part = [domain_parts objectAtIndex:index];
NSString* check_domain = [NSString stringWithFormat:@".%@", part];
index--;

while (index >=0) {
part = [domain_parts objectAtIndex:index];
if (index) {
check_domain = [NSString stringWithFormat:@".%@%@", part, check_domain];
} else {
check_domain = [NSString stringWithFormat:@"%@%@", part, check_domain];
}
index--;

NSDictionary* cookies2 = [_cookies valueForKey:check_domain];
if (!cookies2) {
continue;
}

for (NSHTTPCookie* cookie in [cookies2 allValues]) {
:
(以下、ドメインを除くチェックが続く)


渡されたリクエストURLを .(ドット)で分解し、これを順番に組み立ててチェックしていく。
(イメージ)mail.google.co.jp の場合:

.co.jp
.google.co.jp
mail.google.co.jp


最後の完全一致を除き、先頭に .(ドット)をつけて検索する。なお以前の仕様では検索順序が(詳細 >> 汎用)だったが、これを逆(汎用 >> 詳細)にした。この辺りの仕様はちょっとからないのだが、異なるドメインで同じ path+name が存在した時にはパスと同じように詳細な方を優先させた方が良いと判断してこのような順序とした。


実行してみよう。


ログインできた(クッキー取得と送出がうまくいっている、と思われる)。


- - - -
なお今のままではドメインが .co.jp を持つクッキーもマッチしてしまう。汎用ドメイン(.xcatsan.comなど)を想定してドメインの単語が2つ以上を許しているが .co.jp などはどの組織にも属さない情報となるのでセキュリティ上問題となる。ここでちゃんとチェックするか、あるいはクッキー保存時にそのようなドメインを持つクッキーを受け付けない様にする必要がある(あるいは両方)。