*EtagやIf-modified-sinceやHEADメソッドなど [#yc238f6a]
-ページ: BugTrack
-投稿者: [[henoheno]]
-優先順位: 普通
-状態: 提案
-カテゴリー: その他
-投稿日: 2005-02-08 (火) 23:31:02
-バージョン:
**メッセージ [#f4fec370]
URIの更新チェックに関する話題をここに集めましょう。
*** 利点 [#hba976b9]
+更新チェックが素早く終わるかもしれない
+うまくキャッシュがヒットするとレンダリングを省略できて負荷軽減に繋がるかもしれない
*** 欠点 [#re4a834c]
+インクルードしている先のページの更新状況まではわからないため、意図した結果にならない事がある / かえって誤解する場合がある (GETメソッドでデータを全部取得してみないと、更新されたかどうかが判別できない構成のページには使えない)
+あるページについて、その中で他のページを(何らかの方法で)インクルードしているのかどうか、どのようなページをいくつインクルードしているかを調べようとすると、その処理コストがかかるため折角これらの仕掛けを用意した意味合いが薄れる。
** ちょっと確認: Etag [#tff7fda7]
- Ogawa::Memoranda: 「条件付きGET」のススメ
-- http://as-is.net/blog/archives/000956.html
- hail2u.net - Weblog - ETag
-- http://hail2u.net/blog/coding/etag.html
-- Apacheにおいてはinode番号、ファイルサイズ、最終更新日時をもとにEtagを生成しているらしいという情報と、Perlによる実装例。
-- "ぐぐったら一番上にでて来るページだし、ちゃんと見れよ。" (by PukiWikiスレ Part2 >>109)
- モジュール版PHPで「If-Modified-Since」に対応する
-- http://www.arielworks.net/articles/2004/0125a
** [[BugTrack2/189]]不要なライブラリを読み込まないようにする話題より [#hf6aafec]
*** HTTP HEAD について [#iab4926c]
- ''HTTP HEAD の確認''についても疑問を持っていました。現状では更新時刻の確認だけでもコンバートまで突入してしまいます。 -- [[0]] &new{2006-07-20 (木) 04:13:55};
-- 例えばプラグインを拡張し、plugin_xxx_include() のような関数を作成し、include されたページの情報を引き出す(( 例えば、各ページの更新時刻や、 contents 作成に利用できる ''*{1,3}'' のラインのみを抽出したり(これは個人的に欲しい時期があった。。。) ))とかも有効かな、と思います。簡易パース機能、ですかね。 -- [[0]] &new{2006-07-20 (木) 04:14:52};
--- 簡易パース機能では、(とりあえず)ブロックプラグインのみの解析(( $head == '#' のみ))をし、当該ブロックプラグインに plucin_xxx_include が存在すれば新たに簡易パースにかけ、必要な情報を保持しておく。 -- [[0]] &new{2006-07-20 (木) 04:15:49};
-- 次のようにすればもっと単純です。index.php?hoge でページを閲覧した際、hoge_inc が include 、hoge_pcmt が pcomment で処理されていたと仮定します。コンバート時、 hoge.log に hoge_inc と hoge_pcmt を記録し、 HTTP HEAD の確認時は hoge.log に記録されたページのタイムスタンプを取得し、その中の最新時刻を返すようにすれば恐らく最短距離になるのではと思います。 -- [[0]] &new{2006-07-20 (木) 04:17:09};
--- インクルード系の場合は lib/file.php -> get_source() を通る(通した方が良い)ので、そこで log を作成するのが妥当かも知れません。 -- [[0]] &new{2006-07-20 (木) 04:17:55};
--- related などは関連ページがプラグインの独自仕様になるので、 plugin_related_timestamp() のような関数を用意して調べる必要が出てくるのかな・・・。 -- [[0]] &new{2006-07-20 (木) 04:18:28};
--- リスト系( ls や tracker など)は下位層のページ数が膨大だと結構時間食いそう・・・。 -- [[0]] &new{2006-07-20 (木) 04:19:16};
--- なんだか色々と書きましたが、タイムスタンプの取得処理は(他のページが関連する場合)プラグインの拡張が必要になるのではないかな、と思います。本体側でも関連ページ(hoge_inc)の更新時に各ページ(hoge及び同様の関連ページ)の log の内容を更新するような仕組みがあった方が良いのかな・・・。 -- [[0]] &new{2006-07-20 (木) 04:20:10};
- uDzeKhqwymq -- [[daxmcbgcdun]] &new{2014-03-23 (日) 07:30:24};
- CbigOZFcJMAznuDHkw -- [[powduoqyvye]] &new{2014-04-01 (火) 19:30:36};
#comment
***ブラウザの挙動(back)について / If-Modified-Since [#z4c06e76]
- ''ブラウザの挙動''について。若干調べてみましたが、現状では以下のようになっています。 -- [[0]] &new{2006-07-20 (木) 04:20:35};
-- IE ではページ移動(( 進む・戻る ))の都度 PukiWiki が稼働 & 再描画(稼動結果を反映)します(convert time が毎回変わるので確認できる)。 official や dev の tracker_list 設置ページでやっちゃうとページ移動が恐ろしく遅くなります。 -- [[0]] &new{2006-07-20 (木) 04:21:45};
-- Firefox(fx) ではページ移動の都度確認しているのか、移動の都度 PukiWiki が稼働します(再描画はなし)。知らないうちにバックでものすごい負荷を与えてそうです(サーバーに)。 -- [[0]] &new{2006-07-20 (木) 04:22:48};
--- ちょっと気になったので調べもってコードを書いてみました。初めは ''$_SERVER['REQUEST_METHOD'] == 'head';'' の場合はどうなんだろうと思ったのですが、どうやら IE, fx ではこの条件が true にならないようなので(( イマイチ分かっていない・・・ ))、 ''If-Modified-Since'' を使用するパターンです。IE、fx であれば 304 を返し、ブラウザのキャッシュを使用するようになりました。自分の環境でしか実験していないので汎用性は・・・ですが。 -- [[0]] &new{2006-07-20 (木) 04:23:58};
$timestamp = mktime(0, 0, 0, 7, 20, 2007);// 本当は関連ページも含めた最新の時刻
send_http_head_403($vars['page'], $timestamp);
function send_http_head_403($page, $timestamp)
{
$last_modified = gmdate('D, d M Y H:i:s T', $timestamp);
$etag = '"' . md5($page . $timestamp) . '"';
header('Last-Modified: ' . $last_modified);
header('ETag: ' . $etag);
$modified_since = http_if_modified_since();
if ($modified_since && $modified_since != $timestamp) {
return;
}
if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
$none_match = $_SERVER['HTTP_IF_NONE_MATCH'];
if ($none_match && $none_match != $etag) {
return;
}
} elseif (! $modified_since) {
return;
}
header('HTTP/1.1 304 Not Modified');
exit;
}
function http_if_modified_since()
{
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
$arg = trim($_SERVER['HTTP_IF_MODIFIED_SINCE']);
$length = strpos($arg, 'GMT');
if ($length === false) {
$arg .= ' GMT';
} else {
$arg = substr($arg, 0, $length + 3);
}
$timestamp = strtotime($arg);
if ($timestamp !== false && $timestamp !== -1) {
return $timestamp;
}
}
return false;
}
--- スキンで no-cache が設定されればもちろん無効です。また、no-cache に意味があるのだとすれば(( どうしても必要であれば ))上記の方法は不可能になりますね。 -- [[0]] &new{2006-07-20 (木) 04:25:04};
--- あと、PukiWiki 標準の Last-Modified はとりあえずコメントアウトして実験しました。 -- [[0]] &new{2006-07-20 (木) 04:25:58};
- [[BugTrack/413]], [[BugTrack/486]] -- &new{2009-10-03 (土) 16:25:40};
#comment
** その他のコメント [#j9db1340]
-いずれもinit.phpの改造になりそうな予感。 -- [[henoheno]] &new{2005-02-08 (火) 23:39:56};
-initですか~。てっきり read に仕込むのかと思ってました。 recent.datの日時+該当ページのwikiとdiffのタイムスタンプの新しい方をタネにEtagを作ると、さほど不幸にはならないかも((あまり幸せにもなれないですが :) ))。 さしあたってREADONLY構成だと効きそうですね。単純な RSS からスタートするっちゅー手もアリかもしれませぬ。 -- [[にぶんのに]] &new{2005-02-09 (水) 01:34:19};
- [[BugTrack2/249]] 添付ファイルにはLast-modifiedをつけるべき -- &new{2007-06-24 (日) 23:17:17};
#comment