これが私がそれを実装した方法です。コードは 1 年以上にわたって複数のブラウザーで動作しているので、かなり信頼できると思います。これは、 RFC 2616に基づいており、さまざまなブラウザーが何をいつ送信したかを観察することによって行われます。
擬似コードは次のとおりです。
server_etag = gen_etag_for_this_file(myfile)
etag_from_browser = get_header("Etag")
etag_from_browser が存在しない場合:
etag_from_browser = get_header("If-None-Match")
ブラウザが etag を引用している場合:
引用符を取り除きます (例: "foo" --> foo)
server_etag を http ヘッダーに設定する
etag_from_browser が server_etag と一致する場合
304 リターン コードをブラウザに送信する
これを処理するサーバー ロジックのスニペットを次に示します。
/* クライアントは Etag または If-None-Match を設定する必要があります */
/* 一部のクライアントは parm を引用します。その場合は引用符を取り除きます */
mketag(etag, &sb);
etagin = apr_table_get(r->headers_in, "Etag");
if (エタジン == NULL)
etagin = apr_table_get(r->headers_in, "If-None-Match");
if (etag != NULL && etag[0] == '"') {
intsl;
sl = strlen(エタグ);
memmove(etag, etag+1, sl+1);
etag[sl-2] = 0;
logit(2,"etag=:%s:",etag);
}
...
apr_table_add(r->headers_out, "ETag", etag);
...
if (etagin != NULL && strcmp(etagin, etag) == 0) {
/* etag が一致する場合、304 を返します */
rc = HTTP_NOT_MODIFIED;
}
etag 生成に関するヘルプが必要な場合は、別の質問を投稿してください。それを行うコードも掘り下げます。チッ!