* Content Negotiation でリクエストに応じて gzip 圧縮ファイルを返す
HTTP の Content Negotiation 機能を使うと、ユーザの環境に応じて適切なファイルを返すことができる。
これを利用すると、以下を実現できる。
HTTP リクエストヘッダ Accept-Encoding: gzip を送ってきているクライアントにはあらかじめ gzip で圧縮しておいたファイルを返し、Accept-Encoding: gzip を送ってきていないクライアントには gzip 圧縮していない生のファイルを返す。
動的に生成するページを圧縮したいなら、mod_gzip や mod_deflate のフィルタを使うのがよいだろう。しかし、静的ページならば、あらかじめ圧縮したファイルを返す方式でも良い。毎回圧縮をしないので、CPU 資源を節約することにもつながる。
また、mod_gzip や mod_deflate が使えないサーバでも圧縮を利用できるというメリットがある。現在 sonic64.com はさくらインターネットのホスティングサービスを利用している。残念なことに私の利用しているコースでは mod_gzip が使えない。Content Negotiation 以外の方法でコンテンツを圧縮して返そうと思ったら、すべてを CGI にしてコード中で圧縮するか、proxy を挟むくらいしか方法がない。
コンテントネゴシエーション - Apache HTTP サーバ
http://httpd.apache.org/docs/2.1/content-negotiation.html
MultiViews が有効になると、クライアントのリクエストに応じてサーバが最適なファイルを選択して返すようになる。
私の使っているサーバは httpd.conf で MuitiViews が有効になっているようなので試してみる。
まず、生のファイルと、圧縮して拡張子 .gz を付加したファイルを用意する。
ブラウザからリクエスト。
あれ? うまく Content-Negotiation されてないな。なんで? リクエストするファイル名を変えてみるか。cl.xml じゃなくて、cl をリクエストしてみよう。
今度はうまくいった。Content-Location: cl.xml.gz と Vary: negotiate,accept-encoding が返されている。cl でリクエストすると Content-Negotiation が働き、cl.xml でリクエストしたときは Content-Negotiation がなされない。なんでだろう?
コンテントネゴシエーション - Apache HTTP サーバ
http://httpd.apache.org/docs/2.1/ja/content-negotiation.html
上記ページの説明を見る限り、foo.MIME-TYPE.ENCODING のファイルは foo.MIME-TYPE でアクセスできるはずなんだけどなあ。 とりあえずなんで cl でないとダメなのかは後で調べてみよう。
これはとくに Content-Negtiation とは関係ない。以下のように、cl.xml.gz を直接リクエストしたときも Content-Encoding: gzip がサーバから返されている。
Content-Encoding: gzip を返しているのは mod_mime だ。Apache のデフォルトでこの機能が働くように httpd.conf が記述されている。httpd.conf の以下の部分が該当箇所。もし設定されていなければ、.htaccess で設定する。
ん? 今気づいたけど、拡張子 tgz も AddEncodding してるの? それだと tgz という拡張子を付けたファイルの場合、クライアント側で gzip を展開してしまうので gzip されたファイルを保存したいとユーザが考えたときなどに問題になるんじゃないのかな? Google で AddEncoding x-gzip gz tgz を検索するとヒット。
Re: .tar.gz -> .tgz
http://search.fml.org/mlarchives/fml-help/200107/msg397.html
あ、やっぱり。.tar.gz という拡張子なら Content-Encoding が付かないので問題ないが、.tgz にすると Content-Encoding が付いてしまうので展開さてしまうと。まあ tgz なんて拡張子を使わないようにするか、AddEncoding から tgz を消せば良いだけだから実害は少ないかな。
cl.xml にリクエストがあったとき、Accept-Encoding に gzip があり、かつ cl.xml.gz がサーバに存在していたら Content-Encoding: gzip で cl.xml.gz の中身を返すようにしたいだけなんだけどなあ。cl.xml を CGI にでもすれば簡単にできるけど、それじゃあサーバに余計な負荷をかけてしまう。しょうがない、mod_rewrite を使うか。明日やってみよう。
これを利用すると、以下を実現できる。
HTTP リクエストヘッダ Accept-Encoding: gzip を送ってきているクライアントにはあらかじめ gzip で圧縮しておいたファイルを返し、Accept-Encoding: gzip を送ってきていないクライアントには gzip 圧縮していない生のファイルを返す。
- Content Negotiation を利用して圧縮ファイルを返す手法と mod_gzip/mod_deflate の違い
クライアントが送ってくるリクエストヘッダに応じて、圧縮したデータまたは生のデータを返す。一見 mod_gzip や mod_deflate がやっていることと同じように見えるが、違う。最大の違いは動的にファイルを圧縮するのではなく、最初から圧縮済みのファイルを置いておくことにある。動的に生成するページを圧縮したいなら、mod_gzip や mod_deflate のフィルタを使うのがよいだろう。しかし、静的ページならば、あらかじめ圧縮したファイルを返す方式でも良い。毎回圧縮をしないので、CPU 資源を節約することにもつながる。
また、mod_gzip や mod_deflate が使えないサーバでも圧縮を利用できるというメリットがある。現在 sonic64.com はさくらインターネットのホスティングサービスを利用している。残念なことに私の利用しているコースでは mod_gzip が使えない。Content Negotiation 以外の方法でコンテンツを圧縮して返そうと思ったら、すべてを CGI にしてコード中で圧縮するか、proxy を挟むくらいしか方法がない。
- Apache で Content Negotiation
Apache だと MultiViews を使う。コンテントネゴシエーション - Apache HTTP サーバ
http://httpd.apache.org/docs/2.1/content-negotiation.html
Multiviews
MultiViews はディレクトリ毎のオプションで、 httpd.confファイルの <Directory>, <Location>, <Files> セクション中や、(AllowOverride が適切な値に 設定されていると) .htaccess ファイルで Options ディレクティブによって設定することができます。 Options All は MultiViews をセットしないことに注意してください。明示的に その名前を書く必要があります。
MultiViews が有効になると、クライアントのリクエストに応じてサーバが最適なファイルを選択して返すようになる。
私の使っているサーバは httpd.conf で MuitiViews が有効になっているようなので試してみる。
まず、生のファイルと、圧縮して拡張子 .gz を付加したファイルを用意する。
[21:27:32][hiroaki@sonic64 ~/public_html/test]$ ls -l
-rw----r-- 1 hiroaki users 39751 Sep 13 21:18 cl.xml
-rw----r-- 1 hiroaki users 9785 Sep 13 21:18 cl.xml.gz
ブラウザからリクエスト。
http://sonic64.com/test/cl.xml
GET /test/cl.xml HTTP/1.1
Host: sonic64.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP; rv:1.7.10) Gecko/20050717 Firefox/1.0.6
Accept: text/xml, application/xml,application/xhtml+xml, text/html;q=0.9,text/plain;q=0.8, image/png,*/*;q=0.5
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
HTTP/1.x 200 OK
Date: Tue, 13 Sep 2005 12:29:40 GMT
Server: Apache/1.3.33 (Unix)
Last-Modified: Tue, 13 Sep 2005 12:18:00 GMT
Etag: "3449c4-9b47-4326c378"
Accept-Ranges: bytes
Content-Length: 39751
Keep-Alive: timeout=3, max=8
Connection: Keep-Alive
Content-Type: application/xml
あれ? うまく Content-Negotiation されてないな。なんで? リクエストするファイル名を変えてみるか。cl.xml じゃなくて、cl をリクエストしてみよう。
http://sonic64.com/test/cl
GET /test/cl HTTP/1.1
Host: sonic64.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP; rv:1.7.10) Gecko/20050717 Firefox/1.0.6
Accept: text/xml, application/xml,application/xhtml+xml, text/html;q=0.9,text/plain;q=0.8, image/png,*/*;q=0.5
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
HTTP/1.x 200 OK
Date: Tue, 13 Sep 2005 12:35:24 GMT
Server: Apache/1.3.33 (Unix)
Content-Location: cl.xml.gz
Vary: negotiate,accept-encoding
TCN: choice
Last-Modified: Tue, 13 Sep 2005 12:18:02 GMT
Etag: "3449c8-2639-4326c37a;4326c74b"
Accept-Ranges: bytes
Content-Length: 9785
Keep-Alive: timeout=3, max=8
Connection: Keep-Alive
Content-Type: application/xml
Content-Encoding: gzip
今度はうまくいった。Content-Location: cl.xml.gz と Vary: negotiate,accept-encoding が返されている。cl でリクエストすると Content-Negotiation が働き、cl.xml でリクエストしたときは Content-Negotiation がなされない。なんでだろう?
コンテントネゴシエーション - Apache HTTP サーバ
http://httpd.apache.org/docs/2.1/ja/content-negotiation.html
リンクに MIME タイプを使い続けたい (例えば foo.html)時は、言語拡張子は (エンコーディング拡張子もあればそれも含めて) MIME タイプ拡張子の右側になければなりません (例えば foo.html.en)。
上記ページの説明を見る限り、foo.MIME-TYPE.ENCODING のファイルは foo.MIME-TYPE でアクセスできるはずなんだけどなあ。 とりあえずなんで cl でないとダメなのかは後で調べてみよう。
- mod_mime が 拡張子 gz のファイルを Content-Encoding: gzip にしている
うまく Content-Negotiation がなされて gz ファイルが返されたとき、Content-Encoding: gzip も同時にサーバから返されていて、いわゆる「透過的な圧縮」になっている。mod_gzip や mod_deflate を使ったときと同じような、HTTP 転送データそのものを圧縮している状態だ。これはとくに Content-Negtiation とは関係ない。以下のように、cl.xml.gz を直接リクエストしたときも Content-Encoding: gzip がサーバから返されている。
http://sonic64.com/test/cl.xml.gz
GET /test/cl.xml.gz HTTP/1.1
Host: sonic64.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP; rv:1.7.10) Gecko/20050717 Firefox/1.0.6
Accept: text/xml, application/xml,application/xhtml+xml, text/html;q=0.9,text/plain;q=0.8, image/png,*/*;q=0.5
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
HTTP/1.x 200 OK
Date: Tue, 13 Sep 2005 12:42:35 GMT
Server: Apache/1.3.33 (Unix)
Last-Modified: Tue, 13 Sep 2005 12:18:02 GMT
Etag: "3449c8-2639-4326c37a"
Accept-Ranges: bytes
Content-Length: 9785
Keep-Alive: timeout=3, max=8
Connection: Keep-Alive
Content-Type: application/xml
Content-Encoding: gzip
Content-Encoding: gzip を返しているのは mod_mime だ。Apache のデフォルトでこの機能が働くように httpd.conf が記述されている。httpd.conf の以下の部分が該当箇所。もし設定されていなければ、.htaccess で設定する。
<IfModule mod_mime.c>
#
# AddEncoding allows you to have certain browsers (Mosaic/X 2.1+) uncompress
# information on the fly. Note: Not all browsers support this.
# Despite the name similarity, the following Add* directives have nothing
# to do with the FancyIndexing customization directives above.
#
AddEncoding x-compress Z
AddEncoding x-gzip gz tgz
ん? 今気づいたけど、拡張子 tgz も AddEncodding してるの? それだと tgz という拡張子を付けたファイルの場合、クライアント側で gzip を展開してしまうので gzip されたファイルを保存したいとユーザが考えたときなどに問題になるんじゃないのかな? Google で AddEncoding x-gzip gz tgz を検索するとヒット。
Re: .tar.gz -> .tgz
http://search.fml.org/mlarchives/fml-help/200107/msg397.html
gz が展開されてしまう、という問題ですよね?
あ、やっぱり。.tar.gz という拡張子なら Content-Encoding が付かないので問題ないが、.tgz にすると Content-Encoding が付いてしまうので展開さてしまうと。まあ tgz なんて拡張子を使わないようにするか、AddEncoding から tgz を消せば良いだけだから実害は少ないかな。
- cl.xml へのリクエストを cl.xml.gz にネゴシエーションしたい
うーん、なんだか今日はやりたいことができなかったなあ。cl.xml にリクエストがあったとき、Accept-Encoding に gzip があり、かつ cl.xml.gz がサーバに存在していたら Content-Encoding: gzip で cl.xml.gz の中身を返すようにしたいだけなんだけどなあ。cl.xml を CGI にでもすれば簡単にできるけど、それじゃあサーバに余計な負荷をかけてしまう。しょうがない、mod_rewrite を使うか。明日やってみよう。
- すべての記事の見出し (全1029件)
- 全カテゴリの一覧と記事の数
- カテゴリごとに記事をまとめ読みできます。記事の表題だけを見たい場合は、すべての記事の見出し (カテゴリ別表示) へ。
- .net (57件)
- 2ch (19件)
- amazon (5件)
- Apache (22件)
- bash (13件)
- Bookmarklet (9件)
- C# (45件)
- chalow (18件)
- ChangeLog メモ (20件)
- coLinux (2件)
- CSS (5件)
- Delphi (5件)
- DVD (6件)
- Excel (1件)
- F-ZERO (4件)
- FF12 (31件)
- ftp (8件)
- Google (21件)
- gpg (7件)
- HTML (19件)
- http (19件)
- IE (10件)
- IIS (4件)
- iPod (2件)
- JavaScript (14件)
- Linux (63件)
- MCP (6件)
- Mozilla (14件)
- MS SQL Server (30件)
- MySQL (4件)
- Namazu (3件)
- PC (48件)
- Perl (58件)
- PHP (2件)
- Postgres (36件)
- proftpd (2件)
- qmail (1件)
- RFC (4件)
- RSS (33件)
- Ruby (15件)
- samba (3件)
- sonic64.com (6件)
- SQL (15件)
- Squid (3件)
- ssh (7件)
- Subversion (3件)
- unix (31件)
- VSS (2件)
- Windows (34件)
- winny (9件)
- XML (9件)
- xyzzy (17件)
- おいでよ どうぶつの森 (19件)
- お菓子 (5件)
- アスキーアート (13件)
- アニメ (9件)
- クレジットカード (2件)
- ゲーム (120件)
- シェルスクリプト (18件)
- シレン2 (8件)
- セキュリティ (9件)
- ソフトウェア (21件)
- デザインパターン (2件)
- ネットワーク (30件)
- バックアップ (17件)
- プログラミング (14件)
- マリオカートDS (3件)
- メール (26件)
- メモ (116件)
- ラーメン (11件)
- 音楽 (59件)
- 給油 (3件)
- 三国志大戦 (13件)
- 車 (7件)
- 書斎 (4件)
- 食 (30件)
- 買い物 (17件)
- 簿記 (8件)
- 本 (32件)
- 漫画 (9件)
- 2007-04-23 (Mon)
- 2007-03-07 (Wed)
- 2007-02-27 (Tue)
- 2007-01-17 (Wed)
- 2007-01-15 (Mon)
- 2007-01-14 (Sun)
- 2007-01-08 (Mon)
- 2006-12-01 (Fri)
- 2006-11-22 (Wed)
- 2006-11-20 (Mon)
- 2006-11-19 (Sun)
- 2006-09-30 (Sat)
- 2006-08-29 (Tue)
- 2006-08-04 (Fri)
- 2006-07-27 (Thu)
- 2006-07-23 (Sun)
- 2006-07-17 (Mon)
- 2006-07-10 (Mon)
- 2006-07-06 (Thu)
- 2006-07-03 (Mon)
- 2006-06-29 (Thu)
- 2006-06-28 (Wed)
- 2006-06-27 (Tue)
- 2006-06-25 (Sun)
- 2006-06-19 (Mon)
- 2006-06-18 (Sun)
- 2006-06-15 (Thu)
- 2006-06-11 (Sun)
- 2006-06-01 (Thu)
- 2006-05-30 (Tue)
- プロファイル
- 斎藤 宏明。エンジニアです。宇都宮市に住んでいます。
- リンク
- RSS
- スポンサードリンク
- Powered by
- ☆さくらインターネット☆