4月 262010
とっても便利なVarnishですがいろいろできないことがあってたまになんとか出来ないかなーとか悩むことがあります
特に日付演算には弱い気がします。
以前紹介したESIでのTTLを強引な指定についても日付演算ができれば簡単に・・・と
ということでサンプル的に
- アクセスされた時間をもとにExpiresを付与
をやってみたいと思います
どうやってInline-Cの記述を行うか
公式WikiにはVCLにInline-CできるよーぐらいしかなくそこからリンクにあるPDFに答があります
Using Varnish or VCL for webmasters
要は
varnishd -d -f [vclファイル] -C
でデバッグコードを出してなんとかしなさい!というのが読み取れます
実際にこのコマンドを打つとこんな感じのC言語のコードが(長々と)出てきます
static int VGC_function_vcl_pass (struct sess *sp) { /* ... from (Default Line 74 Pos 5) */ { { VRT_count(sp, 36); VRT_done(sp, VCL_RET_PASS); } } }
これをなんとなく読みといてなんとなく機能を作っていきます
Expires付与の場合
今回の仕様は以下の感じで
- アクセスした時間から30日後のExpiresを付与する
- すでにExpiresが付与されている場合は付与しない
ってな感じです。
この場合vcl_deliverがいいかなーと思うので以下のような感じで書いてみます
VCLファイルの先頭部分
日付の処理を行うのでtime.hをincludeしてあげます
C{ #include <time.h> }C
vcl_deliver部分
sub vcl_deliver { if(!resp.http.Expires){ C{ time_t timer; struct tm *date; char str[256]; time(&timer); timer+=3600*24*30; date = localtime(&timer); strftime(str,255,"%a, %d %h %Y %H:%M:%S %Z",date); VRT_SetHdr(sp, HDR_RESP, "\010Expires:", str, vrt_magic_string_end); }C } }
これだけです
他にもいろいろ関数があるのでそのうち紹介しようかなーとは思いますが特に重要な点を
VRT_SetHdr(sp, HDR_RESP, "\010Expires:", str, vrt_magic_string_end);
ヘッダ変数に値をセットする関数です
第1引数
固定でspを渡します
第2引数
どこのヘッダなのかを特定します
- HDR_REQ
req.http.*に相当 - HDR_RESP
resp.http.*に相当 - HDR_OBJ
obj.http.*に相当 - HDR_BEREQ
bereq.http.*に相当
今回はレスポンスです
第三引数
resp.http.ExpiresのExpires部分を特定するのですが注意が必要です
最初の1バイト目に後続文字列(:まで含む)の文字列長を指定します。
第四引数以降
任意の文字列(char*)で複数個指定が可能です
末端引数
vrt_magic_string_endを指定しておしまいです
これを実行するとレスポンスヘッダに
Expires: Wed, 26 May 2010 10:38:21 UTC
みたいな感じで付与されます
2012/06/01
第三引数にしょうもないミスがあったので修正しました・・・
[…] This post was mentioned on Twitter by \いわなちゃん/. \いわなちゃん/ said: [blog] VarnishのInline-Cで機能拡張する方法 http://is.gd/bIi1A […]