14
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

mod_mruby ngx_mrubyAdvent Calendar 2014

Day 18

[mod_mruby] リバースプロキシしたコンテンツを更にフィルタで操作する

Last updated at Posted at 2014-12-17

これは mod_mruby ngx_mruby Advent Calendar 2014 の18日目(12/18)の投稿です。

この投稿の位置づけとしては、アドベントカレンダーの16日目に書いた記事(静的リソースをリバースプロキシで配信する)の応用編です。

Apache では、リバースプロキシしたコンテンツに対して、更に出力フィルタをかけて処理することが出来ます。(有名な出力フィルタだと mod_deflate など。)

イメージは次のとおり。

スクリーンショット 2014-12-16 22.10.17.png

Apache のフィルタについての説明はこちら。ちなみにコンテンツハンドラ(例:PHP、Perl)の前に起動されるのが入力フィルタで、後に起動されるのが出力フィルタです。
http://httpd.apache.org/docs/current/ja/filter.html

もちろん mod_mruby でもフィルタを作成できますので、同様にリバースプロキシしたコンテンツに対して任意のフィルタ処理をすることが可能です。

mod_mruby でのプロキシの設定については16日目に書いたので、今回はWEBサービスにおける通信の削減を目的としたフィルタの設定を2例、紹介します。

前提となる環境はアドベントカレンダーの3日目、Apache のディレクティブ設定や mod_mruby スクリプトの例は10日目に書いたので、宜しければそちらも参照ください。
mod_mruby を Amazon EC2、Apache2.4 へ導入する(Apache のバージョンは 2.4.10、mod_mruby のバージョンは 1.9.7 です)
mod_mruby の可能性とディレクティブ設定/スクリプトの例

① リバースプロキシしたコンテンツのHTTPレスポンスヘッダを操作

リバースプロキシ先から返ってきた画像ファイルに対し、mod_mruby で Cache-Control ヘッダを操作して、ブラウザにキャッシュさせる時間を任意に指定する例です。

/usr/local/apache2/mruby/respose_header.rb
r = Apache::Request.new

if /\.(gif|jpe?g|png)$/ =~ r.filename
  r.headers_out['Cache-Control'] = 'max-age=20'
end

この例だと 20秒だけブラウザにキャッシュさせます。上記のスクリプトを出力フィルタとしてフックします。

***.conf
SetOutputFilter mruby
mrubyOutputFilter /usr/local/apache2/mruby/respose_header.rb

するとブラウザへのHTTPレスポンスヘッダは次のようになります。
(リバースプロキシ先は GitHub Pages の例です。)

スクリーンショット_2014-12-16_15_05_22.png

フィルタのディレクティブ設定については公式ページをご覧ください。
http://httpd.apache.org/docs/current/ja/filter.html

<Files> 等のディレクティブと組み合わせたり、.htaccess に書いたりもできます。

また上記の例ではスクリプト内で拡張子を判定していますが、拡張子をキーに出力フィルタを定義することも出来ると思います。

ただ出力フィルタのフェーズで Apache の HTTPリクエストやヘッダにアクセスするのは行儀が悪いかも^^; まあこういう設定もできるよということで..

② リバースプロキシしたコンテンツを gzip 圧縮して配信

静的コンテンツを gzip 圧縮して、ネットワーク帯域を節約します。gzip 圧縮は mod_deflate を利用します。ちなみに mod_deflate が何をしてくれるかというと、ブラウザが gzip 圧縮に対応している場合は次のようなヘッダを送ってくるので、

スクリーンショット_2014-12-16_14_58_25.png

mod_deflate はコンテンツを圧縮して送出し、ヘッダは次のように返します。ブラウザはこれで圧縮されたコンテンツだと判断し解凍します。

スクリーンショット_2014-12-16_14_58_42.png

もし mod_deflate がサーバに入ってない(mod_deflate.so が存在しない)場合は、次のように configure し直してから Apache を再コンパイルすると導入できます。
$ ./configure --enable-deflate

設定方法については、まず .conf ファイルにて mod_deflate を有効にします。

***.conf
LoadModule deflate_module modules/mod_deflate.so

例として PNG 形式の画像ファイルを gzip 圧縮する場合は次のようにします。

***.conf
AddOutputFilterByType DEFLATE image/png

するとブラウザへのHTTPレスポンスヘッダは次のようになります。
(これもリバースプロキシ先は GitHub Pages の例です。)

スクリーンショット_2014-12-16_15_03_19.png

ちなみにフィルタは複数を併用できるので、例えば上記の①②を同時に設定することもできます。

スクリーンショット_2014-12-16_15_06_46.png

おわりに

今回は mod_mruby でリーバスプロキシしたコンテンツに対して、更に通信の削減を目的としたフィルタを適用する例を紹介しました。

これ以外にも、フィルタで色々できそうです。mod_mruby では最も簡単なフィルタは次のように書けます。(何もしないコード。)下記の例だと、変数 content には HTTPレスポンスのコンテンツ内容(HTML、JavaScript、CSS、画像バイナリ、JSON、etc..)が格納されているので、ここで加工が出来ちゃいます。

ただ大きいコンテンツはメモリに注意と思われ。

フィルタのコード例
f = Apache::Filter.new

content = f.flatten
f.cleanup

f.insert_tail content
f.insert_eos

またの機会に、スマホ用の画像変換をしてみようかなと^^

明日(12/19)は inokappa さんによる記事です!よろしくお願いします。

14
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?