ページ

2010年4月12日月曜日

Twitpicアップローダ開発(4) 2回目以降の認証失敗解決〜Keep-Aliveをオフにする

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

(前回)Cocoaの日々: Twitpicアップローダ開発(3) 開発中

2回目以降のアップロードに失敗する件について調査した。

現象は1回目のアップロード成功後、2回目が失敗する。失敗時のエラーは "1001 - Invalid twitter username or password"
1回目と2回目で同じ username/password を使っていることは確認済。

ネット上で情報を探した限りでは同様の問題については1件だけみつかった。
Twitpic not working, Posterous is... why? - Stack Overflow

ただ解決していない様子。


さらに調査したところ、1回目の成功後,60秒すぎると2回目でも成功するようになることがわかった。また別プロセスでほぼ同時にアップロードを行った場合も両プロセスともに成功した。

このことからなんらかのセッション管理が影響を及ぼしているのだと考えてリクエストヘッダやレスポンスをダンプしてみた。

リクエストヘッダ

twitpic.up[25881:80f] requestHeaders : {
    "Accept-Encoding" = gzip;
    "Content-Length" = 39135;
    "Content-Type" = "multipart/form-data; charset=utf-8; boundary=0xKhTmLbOuNdArY";
    Cookie = "__qca=P0-1902714012-126624....(略)";
    "User-Agent" = "twitpic.up 1.0 rv:0.1 (Macintosh; Mac OS X 10.6.3; ja_JP)";
}

レスポンスヘッダ
twitpic.up[25881:80f] responseHeaders: {
    "Access-Control-Allow-Origin" = "*";
    Connection = "keep-alive";
    "Content-Encoding" = gzip;
    "Content-Type" = "application/xml";
    Date = "Mon, 12 Apr 2010 14:28:35 GMT";
    Server = "nginx/0.6.35";
    "Transfer-Encoding" = Identity;
    "X-Powered-By" = "PHP/5.2.10";
}

リクエスト時に Cookie が渡されているが、これはどうも WebKit の Cookie が使われているようだ。WebKit の Cookie は以前のブログで見たようにすべてのアプリで共通に使われる。実際、別のサイト(例えば google.comなど)に ASIHTTPRequest からリクエストを送ると、初めてにもかかわらず Googleサイト用の Cookie が飛んでいた。

Cookie が怪しそうだ。

前回のコメントで [ASIHTTPRequest setSessionCookies:nil]; を呼ぶと2回に1回は成功する様になるとのアドバイスをもらったので、試したところ確かにそのような結果となった。やはり Cookie なのか? ただ2回に1回というのがよくわからない。

その後、ASIHTTPRequest やレスポンスヘッダを眺める内に Connecion = "keep-alive" が気になった。そういえば 60秒後に成功するというのはなんとなくだが keep-alive のタイムアウトっぽい。そこで試しにこれを切ってみる。ASIHTTPReuqest には shouldAttemptPersistentConnection というプロパティがあるのでこれに NO を入れてやれば良い。

request.shouldAttemptPersistentConnection = NO;

すると...成功。連続で何度やっても成功した。おお、原因は Keep-Alive だったのか。

レスポンスを見ると Connection= close になっているので当たりのようだ。
twitpic.up[25839:80f] responseHeaders: {
    "Access-Control-Allow-Origin" = "*";
    Connection = close;
    "Content-Encoding" = gzip;
    "Content-Type" = "application/xml";
    Date = "Mon, 12 Apr 2010 13:34:22 GMT";
    Server = "nginx/0.6.35";
    "Transfer-Encoding" = Identity;
    "X-Powered-By" = "PHP/5.2.9";
}

Twitpicサーバ側ではなく、クライアント側(ASIHTTPRequestの設定)が原因だったか。ネットで探しても解決策がなかなか見つからないわけだ。


- - - -
Keep-Aliveだと失敗する理由はわかりません。誰か分かる人、コメント投稿をどうぞ。