2016-11-09 13 views
1

私はティエリーが提案したものと同様に、アプリケーションにカスタムキャッシングビヘイビアを追加しましたin this article。私の静的コンテンツ内のすべてのCSS、JSとHTMLファイルサーバのために私は2以下のヘッダを追加しています:Restletでキャッシュされたリクエスト(ETag)の304応答を手動で返す必要がありますか?

// Added by me 
ETag: "0c635aa7113262fac7606da2432e00f5" // md5(last_mod_date_of_file) 
Cache-Control: max-age=31536000 // one year 

// Automatically added by Restlet (probably Directory class?) 
Date: Wed, 09 Nov 2016 11:50:53 GMT 
Expires: Wed, 09 Nov 2016 12:00:53 GMT 
Last-Modified: Wed, 09 Nov 2016 17:30:56 GMT 

これは正常に動作します、しかし私は、テストサーバー上でコードを展開し、ChromeでF5を打った後ということに気づきました私は応答の全体をもう一度(HTTP 200を返して)取り出します。

私は、これらの要求があまりにも適切なヘッダを使用していることに気付きました:

Cache-Control:max-age=0 
If-Modified-Since: Wed, 09 Nov 2016 17:30:56 GMT 
If-None-Match: "0c635aa7113262fac7606da2432e00f5" 

私の質問があり、私は私のサーバーフィルタでIf-None-Matchヘッダの手動検証を行い、その後、 304応答を返す必要があります?それともRestletによって処理されていますか?

注:この問題で少し奇妙なのは、私のローカル開発環境で適切に動作するように思えたということです。また、ExpiresがRestletによって日付に設定されてからLast-Modifiedに設定される理由について少し混乱しています。これが悪のルートであればデバッグしようとしますが、304ステータスの手動設定とサーバー上のETagsのチェックについては私の質問を無効にしません。

+0

一般的なシナリオは、ブラウザとJavaアプリケーションの間にキャッシュリバースプロキシを置くことです。この場合、304はそれによって処理され、アプリケーション内で気にする必要はありません。エッジサーバーがヘッダーをブラウザやHTTP標準と同じではないと解釈する可能性があるため、注意してください。例えば。 NGINXは非常に(ミス)設定可能です。 – cruftex

+1

上記のヘッダーから、Last-Expiresは現在の時刻から10分後です。実際には最後に修正された時間の継ぎ目が間違っています。ビルドとプロダクションの時間やゾーンが異なるかもしれませんか? – cruftex

答えて

2

私はこれを理解することができました。私は以下の回答を投稿しています。

サーバフィルタでIf-None-Matchヘッダを手動で検証して304応答を返す必要がありますか?

いいえ、手動で行う必要はありません。これは自動的にRestletによって処理されます(DirectoryServerResourceがそれを処理します)。

何が問題でしたか?

実際には、Last-Modifiedヘッダーが将来の日付に設定されていたという問題がありました。これは、私の生産サーバーがUTC-8タイムゾーンにあったのに対し、私がUTC+1に開発していたからです。

私はどのように修正しましたか?

Restlet APIについて知る必要がありましたが、その解決策はそれほどありませんでした。私は、アプリケーションが起動されると、オペレーティングシステムからアプリケーションディレクトリのFile Last Modifiedプロパティを読み取るようにしました。これは、Last-Modifiedヘッダーで使用したかった値です。 ここではのresponseにこのヘッダーを設定することはできません.HTTPキャッシュヘッダーの自動処理は前述のDirectoryServerResourceクラスの自動処理の前に行われます。だから、解決策は以下の通りです:

DSRを拡張するクラスを作成します(あなたに無料で取り扱うすべての自動キャッシュを与える)とLast-Modifiedヘッダはこのロジックキックの前に設定されているように、そのhandle()方法を変更します。

public class WebAssetsResource extends DirectoryServerResource { 
    @Override 
    public Representation handle() { 
     Date desiredDate = ...; // I read this from File System 
     getInfo().setModificationDate(desiredDate); 
     return super.handle(); // Automatic logic will use desired date 
    } 
} 

今度は、新しく作成されたリソースがカスタムDirectoryクラスで使用されていることを確認してください。あなたが望むよう

public class CachedWebAssetsDirectory extends Directory { 
    public CachedWebAssetsDirectory(Context context, Reference rootLocalReference) { 
     super(context, rootLocalReference); 
     setTargetClass(WebAssetsResource.class); // Needed so that Restlet will use our implementation of a ServerResource to serve static files 
    } 
} 

その後、あなたはその上に任意のカスタムフィルタを構築し、CachedWebAssetsDirectoryを使用することができます。

関連する問題