304 Not Modified の罠
このエントリで書かれている内容は、今となっては時代遅れで陳腐な廃れた内容です。真に受けず、十分にご注意ください。
TypeKey 関連の処理を PHP で行い、さらに 304 Not Modified HTTP Header によって UA のキャッシュを利用する際に陥った罠。304 Not Modified ヘッダによってUA のキャッシュを利用すると、TypeKey にサインインしてる状態にも関わらず UA はサインイン前の、サインアウトした状態のキャッシュを出力してしまう問題が判明した。Movable Type のデフォルトでは TypeKey 関連の処理が JavaScript によって UA 側で処理されるため、このような問題は起きない。
何度サインイン手続きを行っても表示されるのはサインアウトされた状態。どうもおかしいと感付いて Ctrl+F5 キーを押してようやく理解した。早速先日公開した Header 部分のテンプレートを修正。どうやら Expires ヘッダは付けない方が良いみたい。
<?php
/* MT4i 対応 UA を MT4i に向ける */
$ua = explode( '/', $_SERVER['HTTP_USER_AGENT'] );
if ( $ua[0] == 'ASTEL' || $ua[0] == 'UP.Browser' || $ua[0] == 'PDXGW' ||
$ua[0] == 'DoCoMo' || $ua[0] == 'J-PHONE' || $ua[0] == 'L-mode' ||
preg_match( '/^KDDI/', $ua[0] ) ) {
header( 'HTTP/1.1 303 See Other' );
header( 'Location: <$MTBlogURL$>(Path to MT4i)' );
exit();
}
/* 最終更新時刻の取得 */
/* 複数のソースから成り立つシステムではこの部分をもう少し工夫する */
$lm_time = getlastmod();
/* ETag 生成 */
$stats = stat( $_SERVER['SCRIPT_FILENAME'] );
$etag = sprintf( '"%x-%x-%x"',
$stats['ino'], $stats['size'], $stats['mtime'] );
/* 更新が無ければ無駄な送信トラフィックを減らす */
if ( ( ( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) &&
strtotime( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) >= $lm_time ) ||
( isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) &&
stripcslashes( $_SERVER['HTTP_IF_NONE_MATCH'] ) == $etag ) ) &&
/* ただし、TypeKey にサインイン済みでないこと */
!isset( $_COOKIE['commenter_name'] ) ) {
header( 'HTTP/1.1 304 Not Modified' );
/* そして、304 であっても ETag は付ける */
header( 'ETag: ' . $etag );
exit();
}
/* XHTML の MIME 型を設定 */
if ( ( isset( $_SERVER['HTTP_ACCEPT'] ) &&
preg_match( '/application\/xhtml\+xml/', $_SERVER['HTTP_ACCEPT'] ) ) ||
preg_match( '/Opera[\/ ][67]\./', $_SERVER['HTTP_USER_AGENT'] ) ||
$ua[0] == 'W3C_Validator' || $ua[0] == 'Another_HTML-lint' ) {
define( 'MEDIATYPE_XHT', 'application/xhtml+xml' );
define( 'MEDIATYPE_JS', 'application/x-javascript' );
} else {
/* application/xhtml+xml 未対応 UA に対する後方互換処置 */
define( 'MEDIATYPE_XHT', 'text/html' );
define( 'MEDIATYPE_JS', 'text/javascript' );
$http_equiv_tags = <<<END
<meta http-equiv="Content-Type"
content="text/html; charset=<$MTPublishCharset$>" />
END;
}
/* HTTP Header 送信 */
header( 'Last-Modified: ' . gmdate( "D, d M Y H:i:s T", $lm_time ) );
header( 'ETag: ' . $etag );
header( 'Content-Type: ' . MEDIATYPE_XHT . '; charset=<$MTPublishCharset$>' );
/* MacIE 4.5 に対しては XML 宣言を送信しない */
if ( !preg_match( '/MSIE 4\.5; Mac/', $_SERVER['HTTP_USER_AGENT'] ) )
echo '<?xml version="1.0" encoding="<$MTPublishCharset$>" ?>', "\n";
echo <<<END
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xml:lang="ja">
<head>
END;
/* application/xhtml+xml 未対応 UA に対する後方互換処置 */
if ( isset( $http_equiv_tags ) ) echo $http_equiv_tags;
?>
<title>(以下略
さらに 304 返信にも ETag を付加するようにした。Apache はリクエストに含まれる ETag と、リクエストされたコンテンツの ETag と一致した場合に 304 Not Modified を返すが、その際にも ETag を付加していたので、これに習って同じような振る舞いをするように変更。
このエントリで書かれている内容は、今となっては時代遅れで陳腐な廃れた内容です。真に受けず、十分にご注意ください。
- タグ
- Movable Type
- obsolete
- templates
- 公開日時
- 2005-01-26T23:57:19+09:00 @664
- Permalink URI & TrackBack URL
- http://blog.drry.jp/2005/01/26/2357
TrackBack ( 1 )
- ヘッダ部分のテンプレート(20050211 版) from drry+@->Weblog
- 2005-02-11T10:15:05+09:00 @664
- 携帯端末からの個別エントリアーカイヴに対するアクセスを MT4i へ適正に渡す。
コメント