Fastlyでよく使う変数

```
特に記載がない限り本記事の記載内容はデフォルト設定での挙動となります。
Fastlyの正式なサポート情報は https://docs.fastly.com/ を参照して下さい。
```

Varnishの設定言語であるVCL(Varnish Configuration Language)では、リクエストやレスポンスヘッダーの内容や、その他サーバーのステータスなど様々な情報を取得して処理に利用することが出来ます。この記事では Fastly で設定を行う上でよく使われるものと、変数を利用するにあたって知っておくと便利なテクニックをまとめたいと思います。

なお、Varnishで利用可能な変数はバージョン毎に異なりますが、Varnishで利用可能なすべての変数がFastlyで利用できるわけではありませんのでご注意下さい。また、Fastly独自の変数などもあります。

`Fastly で利用可能な変数や関数がまとめられた Fastly オフィシャルのページが公開されました。
https://developer.fastly.com/reference/vcl/variables/
今のところ英文のみとなっていますが、こちらのページも参照してみて下さい。


## 最初に

Fastlyで利用可能な変数は、サブルーチンによってreq.xxx、beresp.xxx といったように共通の文字列で始まるグループに分けられています。代表的なものに以下のようなものがあります。

req.xxx: クライアントからのリクエストに関連する情報です
req.http.xxx: クライアントからのリクエストのHTTPヘッダーに関連する情報です
beresp.xxx: オリジンからのレスポンスに関する情報です
resp.xxx: Fastlyからクライアントへのレスポンスに関連する情報です

それぞれの変数はサブルーチン事によって利用できるものと出来ないものがあります。
例えば vcl_recv では req.url は参照出来ますが、beresp.xxxを参照することは出来ません。vcl_recvを処理しているのはリクエストを受けたタイミングなので、この段階ではまだオリジンからのレスポンスに関連する beresp.xxx の情報が存在しないためです。

変数の値を書き換える場合は、その変更がリクエストに対してどのような影響をあたえるのかを意識しながら処理を行うようにしましょう。


## クライアントからのリクエスト - req

**req.url** - 文字列 - 読み込み/書き込み - すべてのサブルーチンで利用可
クライアントからリクエストされたURL。hostやスキームは含まない。
例えばリクエストされたのが `http://www.example.com/dir1/dir2/index.html?id=111` であった場合、req.url は `/dir1/dir2/index.html?id=111` となります。

**req.url.path** - 文字列 - 読み込み専用 - すべてのサブルーチンで利用可
req.urlからクエリストリングの箇所(`?`以降)を除いた値。例: `/dir1/dir2/index.html`

**req.url.ext** - 文字列 - 読み込み専用 - すべてのサブルーチンで利用可
リクエストURLの拡張子。複数の拡張子がある場合は最後の拡張子。拡張子が存在しない場合は空文字列。

**req.url.qs** - 文字列 - 読み込み専用 - すべてのサブルーチンで利用可
クエリストリング。`？`の後ろからURLの終端まで。例: `id=111`
Fastlyが提供するファンクションを利用して、クエリストリングのソートなどの処理を実施することも可能です。詳細は[Query string manipulation VCL features](https://docs.fastly.com/guides/vcl/query-string-manipulation-vcl-features)をご参照下さい。

**req.url.basename** - 文字列 - 読み込み専用 - すべてのサブルーチンで利用可
リクエストURLの最後の / からクエリストリングを含まないURLの終端まで。例: `index.html` 

**req.url.dirname** - 文字列 - 読み込み専用 - すべてのサブルーチンで利用可
ファイル名を含まないディレクトリ。 例: `/dir1/dir2`

**req.request** - 文字列 - 読み込み/書き込み - すべてのサブルーチンで利用可
クライアントから送られたリクエストメソッド。例: `GET`, `HEAD`
なお、URLベースのでのPurgeリクエストの場合、`FASTLYPURGE`が設定されます。
よって、PurgeリクエストをVCLの処理対象外にする場合は`req.request != "FASTLYPURGE"`が条件として利用出来ます。

**req.protocol** - 文字列 - 読み込み専用 - すべてのサブルーチンで利用可
プロトコル。`http` または `https`

**req.is_ssl** - BOOL - 読み込み専用 - すべてのサブルーチンで利用可
リクエストがSSL(TLS)であったかどうか。SSLの場合は1, Non-SSLの場合は0。

**req.http.*** - 文字列 - 読み込み/書き込み - すべてのサブルーチンで利用可
リクエストに含まれる任意のHTTPヘッダー。例えばreq.http.accept ではAccetpヘッダーの情報を取得できます。自身で追加したカスタムヘッダーの内容も取得可能です。

**req.http.host** - 文字列 - 読み込み/書き込み - すべてのサブルーチンで利用可
リクエストのHostヘッダー含まれるホスト名。

**req.backend** - BACKEND - 読み込み/書き込み - すべてのサブルーチンで利用可
バックエンド(オリジン）の情報。バックエンドを変更したい場合は、vcl_recvでこの値を上書きします。

**req.backend.healthy** - BOOL - 読み込み専用 - vcl_recv, vcl_pipe, vcl_pass, vcl_hash, vcl_miss, vcl_hit, vcl_fetch, vcl_deliver, vcl_error で利用可
バックエンドが応答可能な状態どうか。応答可能な場合は`1`、応答出来ない場合は `0`

**req.vcl** - 文字列 - 読み込み専用 - vcl_recv で利用可
読み込まれているVCLのバージョン情報。 [service_id].[version_number]_[generation]-[hash]のフォーマット。

**req.service_id** - 文字列 - 読み込み専用 - すべてのサブルーチンで利用可
FastlyのサービスID。

**req.postbody** - 文字列 - 読み込み専用 - すべてのサブルーチンで利用可
PostリクエストのPayload。

**req.http.Fastly-Client-IP** - 文字列
FastlyにアクセスしてきたクライアントのIP。

**req.http.Fastly-FF**
Fastlyがリクエストをフォワードする際に付与するヘッダー。シールディングを利用している際に、シールディングPOPで処理をさせないためなどに利用する。
例:  `if (!req.http.Fastly-FF){処理内容}`

## バックエンドへのリクエスト - bereq
**bereq.url** - 文字列 - 読み込み/書き込み - vcl_pipe, vcl_pass, vcl_miss, vcl_fetchで利用可
FastlyからバックエンドへリクエストされたURL。hostやスキームは含まない。

**bereq.http.*** - 文字列 - 読み込み/書き込み - vcl_pipe, vcl_pass, vcl_miss, vcl_fetchで利用可
バックエンドへのリクエストに含まれる任意のHTTPヘッダー。


## バックエンドからのレスポンス - beresp
**beresp.status** - INTEGER - 読み込み/書き込み - vcl_fetch で利用可
バックエンドから返却されたレスポンスコード。

**beresp.http.*** - 文字列 - 読み込み/書き込み - vcl_fetch で利用可
バックエンドからのレスポンスに含まれる任意のHTTPヘッダー。

**beresp.cacheable** - BOOL - 読み込み/書き込み - vcl_fetch で利用可
オブジェクトをキャッシュ対象としてよいかどうか。[デフォルトでキャッシュ対象](https://docs.fastly.com/guides/basic-concepts/http-status-codes-cached-by-default)ではないレスポンスコードをキャッシュしたい場合などには`true`を設定する必要があります。

**beresp.ttl** - RTIME - 読み込み/書き込み - vcl_fetch で利用可
キャッシュのTTL。デフォルトではオリジンからのレスポンスに含まれるSurrogate-Control、Cache-Control、Expiresヘッダーなどで指定した値が含まれている。VCLでTTLを変更したい場合は、vcl_fetch上でこの値を上書きする。vcl_fetch上でCache-Control関係のヘッダーの値を変更してもTTLは変更されません。

**beresp.stale_if_error(beresp.grace)** - RTIME - 読み込み/書き込み - vcl_fetch で利用可
staleオブジェクトのTTL。

**beresp.stale_while_revalidate** - RTIME - 読み込み/書き込み - vcl_fetch で利用可
stale_while_revalidateのTTL。

**beresp.backend.ip** - IP - 読み込み専用 - vcl_fetch で利用可
リクエストに利用されたバックエンドのIP。


## クライアントへのレスポンス - resp
**resp.status** - 整数値 - 読み込み/書き込み - vcl_deliver, vcl_log で利用可
クライアントに返却されるHTTPのステータスコード。

**resp.response** - 文字列 - 読み込み/書き込み - vcl_deliver, vcl_log で利用可
クライアントに返却されるレスポンスのステータスコードに含まれるフレーズ。例えば200の場合は`OK`

**resp.http.***
クライアントに返却されるレスポンスに含まれる任意のHTTPヘッダー。

## キャッシュオブジェクトに関する変数 - obj
**obj.hits** - 整数値 - 読み込み専用 - vcl_hit, vcl_deliver, vcl_log で利用可
オブジェクトがキャッシュヒットした回数。

**obj.cacheable** - BOOL - 読み込み専用 - vcl_hit, vcl_log で利用可
オブジェクトがキャッシュ対象かどうか。

**obj.ttl** - RTIME - 読み込み/書き込み - vcl_hit, vcl_error, vcl_log で利用可
オブジェクトがキャッシュされる時間。






## 時間に関する変数 - time
**now** - TIME - 読み込み専用 - すべてのサブルーチンで利用可
RFC 1123 フォーマットでの現在時刻。例: `Sun, 16 Nov 2014 15:20:53 GMT`

**now.sec** - 文字列 - 読み込み専用 - すべてのサブルーチンで利用可
ユニックスタイムでの現在時刻。例: `1519709073`

**time.elapsed** - RTIME - 読み込み専用 - すべてのサブルーチンで利用可
リクスストを処理開始してからの秒数（小数点3桁）。例: `0.236`

その他の時間に関する変数については[Date- and time-related VCL features](https://docs.fastly.com/guides/vcl/date-and-time-related-vcl-features)を参照して下さい。

## その他の変数
**client.ip** - IP - 読み込み専用 - すべてのサブルーチンで利用可
クライアントのIP。ただし、例えばシールディングを利用している場合には実際のクライアントのIPではなくFastlyのIPとなる。FastlyにアクセスしてきたクライアントのIPが必要な場合は`req.http.Fastly-Client-IP`を参照。

**server.identity** - 文字列 - 読み込み専用 - すべてのサブルーチンで利用可
サーバーのホスト名とデータセンター名。例: `cache-jfk1034-JFK`

**server.region** - 文字列 - 読み込み専用 - すべてのサブルーチンで利用可
Fastly POPの所属するリージョン名。例: `APAC`, `US-West`など

**client.geo.country_code** - 文字列 - 読み込み専用 - すべてのサブルーチンで利用可
2文字で表されるISO 3166-1フォーマットでのカントリーコード。

その他の地域情報に関連する変数については[Geolocation-related VCL features](https://docs.fastly.com/guides/vcl/geolocation-related-vcl-features)をご参照下さい。

**fastly_info.state** - 文字列 - 読み込み専用 - すべてのサブルーチンで利用可
リクエストのステータス。以下のいずれかの値を含みます。
　NONE: Varnishによってステータスがまだ設定されていない。
　HIT-: キャッシュからコンテンツを配信。
　HITPASS-: vcl_fetch においてpassとマークされているリクエスト。
　HIT-STALE-: ステールオブジェクトからコンテンツを配信。
　HIT-SYNTH-: （Fastlyが生成した）シンセティックレスポンスを配信。
　MISS-: キャッシュされていないコンテンツを配信。
　PASS-: キャッシュスべきでないコンテンツを配信。

## tls接続とHTTP/2に関する情報 - tls
**tls.client.protocol** - 文字列 - 読み込み専用 - vcl_recv, vcl_hash, vcl_deliver, vcl_log で利用可
コネクションに利用されたTLSのバージョン。

**tls.client.cipher** - 文字列 - 読み込み専用 - vcl_recv, vcl_hash, vcl_deliver, vcl_log で利用可
コネクションに利用された暗号スイート。

**fastly_info.is_h2** - BOOL - 読み込み専用 - vcl_recv, vcl_hash, vcl_deliver, vcl_log で利用可
リクエストでhttp2が利用されたかどうか。

tlsとHTTP/2に関するその他の関数については[TLS and HTTP/2 VCL variables and functions](https://docs.fastly.com/guides/vcl/tls-and-http2-vcl-variables-and-functions)をご参照下さい。





## ログにおすすめの変数
この記事で紹介した変数は Fastly からリアルタイムに送信するログに含めることが可能ですが、この他にもログに含めると役に立つ変数は多数あります。ログに各種情報を含める設定の手順については[ログに有用な変数](https://docs.fastly.com/ja/guides/streaming-logs/useful-variables-to-log)をご参照下さい。


## まとめ 
本記事では Fastly で設定するにあたって通常はこれだけ把握しておけば大丈夫、という変数をご紹介しました。ここで紹介している以外にもたくさんの情報が取得可能ですので、取得したい内容の変数が存在するか分からない場合は[Fastlyのオフィシャルドキュメントサイト](https://docs.fastly.com/)を参照するか、support@fastly.com までお問い合わせ下さい。