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