XREA-ad

WEBLOG

2008/11/16 日曜日 17:59:52 [WEB]

mod_rewriteでのクエリの扱い

mod_rewriteでクエリ(URIの?マーク以降の部分)を参照するにはRewriteCond%{QUERY_STRING}を調べればよい。 rNote時代のクエリ付きのリクエストをリダイレクトさせようと思い、たとえば

http://reva.s28.xrea.com/?d=2008-11-16

へのアクセスを

http://reva.s28.xrea.com/archives/date/2008/11/16/

へ書き換えるべく、.htaccessに次のような記述を加えました。

RewriteEngine on
RewriteCond %{QUERY_STRING} d=([0-9]+)-([0-9]+)-([0-9]+)
RewriteRule . /archives/date/%1/%2/%3/ [R=301,L]

しかし実際にURIが正しく変換されるか試してみると、リクエストがループしていると怒られました。 どうやら書き換え後のURIにもクエリが付加されているようで、 いつまでたってもRewriteCondを満たしてしまっていたようです。 つまり、

http://reva.s28.xrea.com/?d=2008-11-16
http://reva.s28.xrea.com/archives/date/2008/11/16/?d=2008-11-16
http://reva.s28.xrea.com/archives/date/2008/11/16/?d=2008-11-16
http://reva.s28.xrea.com/archives/date/2008/11/16/?d=2008-11-16
.
.
.

という風なリダイレクトが繰り返されていたと考えられます。 その後試行錯誤したところ、どうも書き換えURIに?が入っているとクエリの引継ぎは行われないことが分かり、

RewriteEngine on
RewriteCond %{QUERY_STRING} d=([0-9]+)-([0-9]+)-([0-9]+)
RewriteRule . /archives/date/%1/%2/%3/? [R=301,L]

と試しに書いてみたところ、期待通りに動いてしまいました。マジか。 しかも変換後のURIに?がくっついてhttp://reva.s28.xrea.com/archives/date/2008/11/16/? のようになることもありませんでした。これは如何に。

もう少し調べてみると、だいたい次のような感じで挙動していることが分かりました。

  • 書き換えURIに?が入っていなければ、元のURIのクエリを引き継ぐ
  • 書き換えURIに?が入っていれば、元のURIのクエリを破棄する
  • 書き換えURIに?が入っていて[QSA]オプションがついていれば、書き換えURIに元のクエリを合成する

これらから察するに、元のURIだけでなく書き換えURIも内部で一度クエリだけを切り離されて処理された後、付け直しているのかも。 末尾に?だけ付けても実際に返されるURIにゴミが付かなかったのは、元のURIのクエリが書き換えURIの空のクエリで上書きされた後、変換後のURIを出力する際にクエリは空だから?以降は付ける必要なしと判断されているものと考えられるんじゃないでしょうか。

それにしてもクエリ破棄のために末尾に?を付けるって発想はなかった。 mod_rewrite、というか.htaccessはまだまだ分からんことが多いなあ。

2008/9/3 水曜日 14:01:00 [WEB]

Famicompo mini vol.5

Famicompo mini vol.5が始まりました。 これはファミコン音源で作った曲のコンペティションです。 ピコピコした音が好きな方は是非聴きに行きましょう!

ちなみに、曲はすべてNSFというファミコン音楽のフォーマットで投稿されています。 NSFの再生にはシンプルで軽い"VirtuaNSF"や、Winampの再生プラグインとして動作する"NSFplug"がおすすめです。

VirtuaNES official site
VirtuaNSFを配布しているサイト。
入手は "Download" > "Other program / data" から。
DIGITAL SOUND ANTIQUES
NSFplugを配布しているサイト。
2007/12/23 日曜日 22:56:00 [WEB]

圧縮転送をtext/htmlに限定する

.htaccessを使って簡単に圧縮転送の対象を限定できました。

SetEnv gzip-only-text/html 1

上のように記述するとmod_deflateの方でこの変数を参照してくれて、 html以外のファイルは圧縮されなくなるようです。 Apacheは全然分からないのでこんな書き方になってますが、 もうちょっと格好いい書き方がありそうですね。

前に書いた夢の音楽館様から借りている file.nijinone.jp上に置いたzipファイルがgzipで更に圧縮される問題はこれで解決しました。

更に、ファイル転送時にファイルサイズ不明と表示される現象も起こらなくなりました。 これはあくまで推測ですが、圧縮後のサイズが一定値を超えるとバッファから溢れて、 Content-Lengthが確定する前にストリーム応答で転送が開始されてしまうんじゃないかと思います。 この推測が当たってるとすると、大体のレンタルサーバーではその挙動を見る限り、重いファイルは圧縮しない設定になってる? どうなんでしょう。

それにしてもダメもとで試した.htaccessが機能したのは驚きました。 というか大丈夫なのかこれは。 利用規約には特に何も書かれてないしサーバーの設定でも禁止されてないのはOKってこと...なのかな!

2007/12/2 日曜日 2:02:00 [WEB]

Firefoxでcheckloaduri.enabledの設定が反映されない

Firefoxではセキュリティのためネットワーク上のページからローカルにある画像ファイルなどを読み込めないようになっています。 どうしてもローカルファイルを呼び出す必要がある場合はuser.jsに次のような記述を加えます:

user_pref("capability.policy.policynames", "localfilelinks");
user_pref("capability.policy.localfilelinks.sites", "http://許可するサイト");
user_pref("capability.policy.localfilelinks.checkloaduri.enabled", "allAccess");
# 他の名前と被らなければ
# "localfilelinks"の代わりに好きな名前を使える

Fx1.5以降はこの書き方でOK...のはずなんだけど何故か上手くいかない!

小一時間格闘して見つけた原因は意外にもアドオンのNoScriptでした。 実はNoScriptには信頼済みサイトからのローカルファイルへのアクセスを許可するかどうかの設定があって、 こっちの設定がuser.jsの記述よりも優先されてしまうようです。 要するに、NoScriptを使ってる人はuser.jsは使わずにNoScriptの設定を変えるだけでOKってことらしい。

設定はNoScript オプション > "詳細設定"のタブ > "Trusted"のタブ > "Allow local links"のチェックボックスから変更できます。 これだとNoScriptで許可したサイトすべてからローカルファイルにアクセスできるようになるので少し怖いかも...でも仕方ないか。

この方法でOGameのスキンをローカルに置けました。 ちなみに、わざわざWeb上からローカルファイルを読み込ませたいのって大体スキンとか高速化とかの目的だと思うんですが、 Firefoxの場合、ローカルファイルのパスはfile://から始める必要があるのでご注意。 例えばc:\ogame\skin\を指定する場合はfile://c:/ogame/skin/みたいな感じで。

2007/9/29 土曜日 21:30:00 [WEB]

Adblock Plus フィルタ

なんかいいフィルタないかなと思って検索したら何故かこのページが引っかかった。 あんな適当なまま放置しておくのも申し訳ないのでちょっと書き直してみます。

まずはフィルタの書き方を紹介してみます。 公式の説明を読みながら書いてみたのですが、英語は得意ではないので間違っている部分などがあったら教えてもらえると助かります...。
公式: Adblock Plus: Writing Adblock Plus filters

基本書式

http://example.com/ads/banner123.gifという画像をブロックする場合について考えます。

まず、このアドレスをそのまま書いたものが最も単純なフィルタとなります。

  • http://example.com/ads/banner123.gif

またAdblock Plusのフィルタは部分一致をとるため、

  • example.com/ads
  • example.com
  • example
  • ads/
  • banner123.gif

のようなフィルタを記述してもhttp://www.example.com/adbanner.gifをブロックできます。 ただし、上の例でのexampleなどの一般的な単語をフィルタにしてしまうと広告でない要素までブロックしてしまう可能性があるので注意してください。

また、Adblock Plusではワイルドカードが使用できます。

  • http://example.com/ads/banner*.gif

と記述するとhttp://example.com/ads/banner123.gifだけでなく、http://example.com/ads/banner001.gifhttp://example.com/ads/bannerABC.gifなどもブロックできます。 広告の中には表示のたびにアドレスが変わるものもあるので有効に活用してください。 ただし、ワイルドカードを使用したフィルタがあまりにも多いと動作が遅くなるようです。

ホワイトリスト

ホワイトリストに一致したアドレスは、フィルタに一致した場合でもブロックされません。 フィルタを記述する際、先頭に@@を付けるとホワイトリストとして扱われます。 例えば、

  • adv

というフィルタがhttp://example.com/advice.gifをブロックするのを止めたい場合、

  • @@http://example.com/advice.gif
  • @@example.com/advice.gif
  • @@advice

などと記述してください。

コメント

!から始まるフィルタはコメントとして扱われ、フィルタとしては機能を持ちません。

前方一致・後方一致

|をフィルタの先頭・末尾に付けると前方一致・後方一致として扱われます。 例えば、

  • swf|

と記述すると後方一致によりhttp://example.com/swf/index.htmlはブロックされずに、 http://example.com/annoyingflash.swfはブロックされます。

フィルタオプション

フィルタの末尾に$を付けると、それに続けてフィルタオプションを指定できます。 複数のフィルタオプションを使用する場合はカンマで区切ってください。

要素の種類によってブロックするかどうかを決めるオプション群をまとめてタイプオプションと呼びます。 使用できるタイプオプションは以下の通りです。

script
外部スクリプト。
image
画像。
background
背景画像。
stylesheet
外部スタイルシート。
object
FlashやJavaなどのオブジェクト要素。
link
画像のリンク先アドレス。"バナーのリンク先をチェックする"が有効の場合のみ適用されます。
subdocument
フレームなどから呼び出される外部ドキュメント。
document
ページ本体。このタイプオプションはホワイトリストのみで適用されます。Adblock Plusでは表示するページ本体のアドレスがホワイトリストに一致した場合、そのページ内の要素すべてがホワイトリスト扱いとなります。
other
その他の要素 (XBLのbindings, XMLHttpRequests, objectが呼び出すdata, など)

例えば、タイプオプションを用いて.cgiで終わる画像をブロックしたい場合は

  • .cgi|$image

と記述できます。

タイプオプションの先頭に~を付けると逆タイプオプションとなり、指定された種類以外の要素をブロックします。 例えば、

  • adv$~script,~stylesheet

と記述することで、advの文字が含まれているスクリプトとスタイルシート以外の要素をブロックできます。

大文字小文字の区別をする場合はmatch-caseオプションを使用します。例えば、

  • BannerAd.gif$match-case

http://example.com/BannerAd.gifをブロックしますが、http://example.com/bannerad.gifはブロックしません。

collapseオプションを使用すると"ブロック要素を隠す"の設定に関わらず、 フィルタごとに要素を隠すかどうか決めることができます。 隠す場合はcollapseを、隠さない場合は~collapseを指定します。

正規表現

/から始まって/で終わるフィルタは正規表現として扱われます。 書き方の規則はJavaScriptの正規表現と同じです。 ワイルドカード同様、動作を遅くする可能性があるので使いすぎには注意してください。

稀に、正規表現を使いたくないフィルタが正規表現として扱われてしまうことがあります。 例えば、http://example.com/adv/banner.jpgという広告に対して、 ディレクトリ部分のadvにマッチさせてブロックしたい場合、

  • /adv/

と記述すると/から始まって/で終わっているため正規表現として扱われてしまいます。 これを防ぐには先頭にワイルドカードを用いて

  • */adv/

と記述してください。

要素非表示

要素非表示(原文:Element hiding)はアドレスではなくページ内の要素に対して適用されるフィルタです。 このフィルタは主にテキスト広告をターゲットとし、ページ内で一致した要素を隠します。 要素非表示は後述の属性セレクタ及びCSSセレクタの2種類の記述ルールに分かれています。

属性セレクタによる要素非表示

属性セレクタによる要素非表示はHTML内の各要素(タグ)の属性を条件として、一致する要素を隠します。 フィルタの記述にはHTMLの知識が必要となります。

属性セレクタによる要素非表示の基本書式は

  • domain#tag(id/class)

です。ドメイン名を記述しないとすべてのドメインに対して有効になり、タグ名を*とするとすべてのタグに対して有効になります。 例えば、http://example.com/に次のようなテキスト広告が掲載されているとします。

<div id="textad">
Really cheap tofu, click here!
</div>

この広告を非表示にするためには

  • example.com#div(textad)
  • example.com#*(textad)

などと記述してください。 上の例では要素のidの一致をとっていますが、classが一致した場合も要素は非表示になります。 例えば、上のフィルタはclassの一致により

<div class="textad">
Cheapest tofu, only here and now!
</div>

のような広告も隠します。 また、上のフィルタではドメインをexample.comに限定していますが、 すべてのドメインに対してこのフィルタを有効にしたい場合は

  • #div(textad)
  • #*(textad)

と記述すればよいでしょう。 ドメイン名はワイルドカードで表現することはできず、またドット文字から始めることもできません。 したがってwww1.example.comwww2.example.comといった特定のレベル以下のドメインを指定する場合、

  • www*.example.com
  • *.example.com
  • .example.com

などと記述することはできないので注意してください。 範囲が大きくなってしまうかもしれませんが、上の例を正しく記述したものは

  • example.com

となります。

属性セレクタによる要素非表示ではidclassだけでなく、他の属性の一致によって要素を隠すこともできます。 その場合の基本書式は

  • domain#tag(属性名=属性値)(属性名=属性値)...

のような形になります。 複数の( )を記述した場合、すべての条件に一致する要素のみが隠されます。 使用できる条件は完全一致だけでなく、以下のものが使用できます。

  • =
完全一致
  • *=
部分一致
  • ^=
前方一致
  • $=
後方一致

公式サイトでは以下の3つの例が掲載されています。

  • #div(title*=adv)
title属性に"adv"を含むdiv要素を隠します。
  • #div(title^=adv)(title$=ert)
title属性が"adv"で始まり"ert"で終わるdiv要素を隠します。
  • #table(width=80%)(bgcolor=white)
width属性が"80%"かつbgcolor属性が"white"であるtable要素を隠します。

実際に属性セレクタによる要素非表示を使用する場合はドメイン名と属性の両方を使うことが多くなるでしょう。

CSSセレクタによる要素非表示

CSSセレクタによる要素非表示は記述したCSSセレクタに一致する要素を非表示にします。 フィルタの記述にはスタイルシートの知識が必要となります。

CSSセレクタによる要素非表示の基本書式は

  • domain##selector

です。ドメイン名の記述に関しては属性セレクタによる要素非表示と同じです。 selectorにはCSSの文法に従ってセレクタを記述します。 文法に関してはCSS 概説 | セレクタNEXTindexさん)のページが分かりやすいと思います。 公式サイトでは以下の例が掲載されています。

  • ##div.adheader + *
class属性がadheaderであるdiv要素に隣接するすべての要素を隠します。

公式サイトによると、この機能は上級ユーザ向けでありAdblock PlusはCSSセレクタによる要素非表示のフィルタに関しては文法チェックを行わないと注釈されています。 CSSセレクタが文法的に正しくないフィルタを入力すると、他の正常なフィルタまで動作しなくなるかもしれません。

サンプルフィルタ

ここで、俺が普段使っているフィルタを紹介してみます。 まともに表示できないページがあっても、ホワイトリストに入れて開き直すというスタイルでブラウジングしているので、 他所のフィルタと比べて誤爆率が高いかもしれません。

  • ?$image

引数をとるすべての画像をブロックします。 広告だけでなく、アクセスカウンターやアクセス解析もブロックしてくれることもあります。 強力な分、誤爆も多いです。

  • /\/ad[isv]?[\.\/]/
  • adframe
  • adserve
  • advert

advertisementに関連する語のフィルタです。

  • click.
  • value.
  • affiliate
  • banner/

これらの単語も広告に含まれていることが多いようです。

このほか、よく見かける広告はピンポイントでブロックしています。

  • amazon

Amazonの広告をブロックします。これは個人のWebサイトやBlogでよく見かけます。 Amazonのサイトを利用する方は下で紹介するホワイトリストもあわせて使用してください。

  • rd.rakuten.co.jp
  • grp*.ias.rakuten.co.jp
  • hpad.www.infoseek.co.jp
  • topics.news.www.infoseek.co.jp

infoseek iswebで表示される広告です。

  • aaa.livedoor.jp#form(name=aaasearch)

AAA! CAFEで表示される広告と検索フォームです。

  • tok2.com#*(id$=-SEO)
  • tok2.com#*(id^=TOK2-)

TOK2.COMで表示される広告と検索フォームです。

表示できないページは適宜ホワイトリストに加えていくと良いでしょう。

  • @@wiki$image
  • @@|http://*.google.co.jp/
  • @@|http://*.google.com/
  • @@|http://*.microsoft.com/
  • @@|http://*.youtube.com/
  • @@|http://www.amazon.co.jp/$document