ページ

2009年9月15日火曜日

NSHTTPCookieStorage相当のクラスを自前で実装する (13)ドメインチェックルール調整

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

GoogleAppsへログインできることが確認できたのだが、また一つ問題に気がついた。

ログインボックスに「ログイン状態を保持する」というのがある。


チェックを入れておくと、次回ブラウザでアクセスした時に自動的にログイン状態になる。Safariではそのような動作になっていた。

ところがサンプルアプリの CookieStorageではこれが動作しない。ログイン状態は恐らくクッキーで管理されていると思われるので、なんらかの理由で CookieStorage がクッキーが受け取れていないか、あるいは送出できていないと予想される。

Safari のクッキーを眺めているとこのクッキーはどうも "HID"という名前を持つものだと分かった。


リクエストのURLと、このクッキーのドメインを照らし合わせてみると次のようになっていた。

クッキードメイン:.www.google.com
リクエストURL:www.google.com


なるほど。このケースは送出OKなのか。今の XCHTTPCookieStorage では NGにしているのでこれでは確かにクッキーが送出されない。Safari が動作し、GoogleAppsがそのような動作を期待しているということはこれが仕様なのだろう。手を入れて対応できるようにしよう。

クッキー送出判断ロジックに手を加えた。

以前のコードはこう。
XCHTTPCookieStorage.m
 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--;


以前はわざわざ最後のチェックで頭に . をつけないようにしていた。例えば、リクエストURL が www.google.com の場合、送出するクッキーを探すときのドメインは次のようになっていた。
[index= 2] .com
[index= 1] .google.com
[index= 0] www.google.com


新コードはこうなった。
 int index = [domain_parts count]-1;
NSString* part = [domain_parts objectAtIndex:index];
NSString* check_domain = [NSString stringWithFormat:@".%@", part];
index--;

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


クッキーを探すときに頭に . が付くケースを追加した。
[index= 2] .com
[index= 1] .google.com
[index= 0] .www.google.com
[index=-1] www.google.com




加えて -[setCookies:forURL:mainDocumentURL:] 内の NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain チェックも頭に . が付くケースを追加した。

- (void)setCookies:(NSArray *)cookies forURL:(NSURL *)URL mainDocumentURL:(NSURL *)mainDocumentURL
{
:
(旧)NSString* url_host = [mainDocumentURL host];
(新)NSString* url_host = [NSString stringWithFormat:@".%@", [mainDocumentURL host]];

for (NSHTTPCookie *cookie in cookies) {
if (_cookie_accept_policy ==
NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain &&
![url_host hasSuffix:[cookie domain]]) {
continue;
}
[self setCookie:cookie];
}
}



実行すると GoogleApps で無事にログイン状態が保持された。


ソースコード:CookieStorage-6.zip