01 May 2009

ソフトバンク携帯のエラーコード WJ46053E について

ソフトバンクの携帯で携帯サイトにアクセスすると、以下のエラーコードが表示される現象があります。確認したのは703SHf, 814SHの2機種です。

エラーが発生しました。リクエストが不正です。(WJ46053E)

ソフトバンクからはエラーコードの詳細が公開されていないようなので、正確な原因はわかりません。

この2つの記事によると、どうも304 Not Modifiedがらみが原因の一つだと推測できそうです。そこで次の実験をしてみます。

ひとつは、HTTPリクエストヘッダを用いて、アクセス時刻とファイルの最終更新時刻を比較し、最終更新時刻のほうが古ければ304 Not Modifiedを返すという処理。PHP で If-Modified-Since に対応してみる -avoidnote-からお借りしました。



$ts = getlastmod();
doConditionalGet($ts);
echo "hello world";

function str2time($str) {
    /* 
    * Convert a HTTP-date string to Unix time
    * 念のためセミコロン以降を削除してから処理する
    * http://bakera.jp/hatomaru.aspx/ebi/topic/586 を参照
    */
    $str = preg_replace( '/;.*/', '', $str);
    if (!preg_match("/GMT/", $str)) $str .= ' GMT';
    return strtotime($str);
}

function doConditionalGet($timestamp) {

    /*
    * A PHP implementation of conditional get, see 
    * http://fishbowl.pastiche.org/archives/001132.html
    * http://as-is.net/blog/archives/000956.html
    */

    // Convert to GMT format
    $last_modified = gmdate('D, d M Y H:i:s T', $timestamp);

    // Create ETag
    $etag = '"'.md5($last_modified).'"';

    // Send the headers
    header("Last-Modified: $last_modified");
    header("ETag: $etag");

    // See if the client has provided the required headers
    $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ?
        // UNIX タイムスタンプに変換
        str2time( stripslashes( $_SERVER['HTTP_IF_MODIFIED_SINCE'])) : false;

    $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ?
        stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : false;

    if (!$if_modified_since && !$if_none_match)
        return;

    // At least one of the headers is there - check them
    if ($if_none_match && $if_none_match != $etag)
        return; // etag is there but doesn't match

    if ($if_modified_since && $if_modified_since < $timestamp)
        return; // Unix タイムスタンプ(int)で比較する

    // Nothing has changed since their last request - serve a 304 and exit
    header('HTTP/1.1 304 Not Modified');
    exit;
}

?>

こちらは携帯からも問題なく動作しました。もう一方は何もせずただ単に304を返すだけのプログラムです。


header('HTTP/1.1 304 Not Modified');
echo "hello world";
?>

こちらのファイルに携帯からアクセスすると、前述のWJ46053Eエラーが発生しました。

以上の結果より、WJ46053Eが発生する一つの要因として、携帯側のキャッシュが存在しないのに、304が返されたというものが考えられます。ただしあくまでこれは推測です。ほかの原因があるかもしれないし、間違っているかもしれません。さらに言うと、上記の2機種でしか実験をしていないので、ほかのメーカーの機種ではまた違うのかもしれません。