endflow.net blog

/* programming and programming */

Archive for the ‘Apache’ tag

[lang_ja]mod_bwを.htaccessで設定可能にする試み #2[/lang_ja][lang_en]Using mod_bw with .htaccess #2[/lang_en]

without comments

[lang_ja]

/* ここまでの話 */

Windowsでmod_bw 0.7 のビルド、さらにmod_bw 0.8 のビルドを済まして、前回で.htaccessファイルからサーバの再起動なしにmod_bwの設定変更が可能になりました。いや、本当に便利ですよ。特にHostUtilGUI(Windowsのhostsファイルを楽に編集するためのユーティリティ。ブログ書く予定)と相まって。しかし本当の目的はあくまでセグメンテーションフォールトです。

/* 作者に連絡 */

mod_bwの作者に「おいおい、セグメンテーションフォールト起こすとかいっといて、全然起こんねーじゃねーか!がっかりだぜっ!」(もちろんもっと丁寧に)とか送ったところ、すぐに返事が返ってきました。

メールありがとう!
次のリリースにはこれを含めるよ!(ほとんど準備は終わってるんだけど、最近クソ忙しい)
そのとき僕が君のことを言及してなかったら指摘してね!

今のところまだ配布サイトは更新されていないようです。あまり期待はできなさそうですね。私としてはセグメンテーションフォールトを起こす条件を教えてほしかったのですが。本当に忙しいのかもしれません。

もう少し待ってリリースされなかったらまたメールで突っついてみたいと思います。一応このシリーズは継続ということにします。

[/lang_ja]
[lang_en]

Sorry … now translating this post to English.

[/lang_en]

Written by kuy

September 2nd, 2007 at 12:17 pm

Posted in Uncategorized

Tagged with , , ,

[lang_ja]mod_bwを.htaccessで設定可能にする試み #1[/lang_ja][lang_en]Using mod_bw with .htaccess #1[/lang_en]

without comments

[lang_ja]

/* 経過とか */

WindowsでApacheのビルド、そしてmod_bw 0.7 のビルドを経て、mod_bw 0.8 のビルドを終えました。ようやく本題のセグメンテーションフォールトの再現に入ります。その後、原因を探っていきます。途中で挫折する可能性高いですが、可能な限り執念で続けます。

/* Apache 2.x 系のコンフィグレーションAPI */

Apacheのコンフィグレーションはhttpd.confだけでなく、各フォルダ階層にある.htaccessファイルからも可能です。ApacheではコンフィグレーションAPIを通して必要なコンフィグレーションを取得することが出来ます。多くのモジュールが自分専用に記述されたコンフィグレーションしか参照しないため、他にどのようなコンフィグレーションがあろうと関係ないわけです。1つの共通のコンフィグレーションファイルでプラグインを実現する方法が気になっていたのでいい勉強になりました。

実際のコードで説明していきます。以下はmod_bw.cのディレクティブ定義部分の抜粋です。

/* Command Table */
static const command_rec bw_cmds[] = {
    AP_INIT_TAKE2("MaxConnection", maxconnection, NULL,
                  RSRC_CONF | ACCESS_CONF,
                  "a domain (or ip, or all) and the max connections allowed"),
    AP_INIT_FLAG("BandWidthModule", bandwidthmodule, NULL,
                 RSRC_CONF | ACCESS_CONF,
                 "On or Off to enable or disable (default) the whole bandwidth module"),
    AP_INIT_FLAG("ForceBandWidthModule", forcebandwidthmodule, NULL,
                 RSRC_CONF | ACCESS_CONF,
                 "On or Off to enable or disable (default) the mod catching every request"),
    AP_INIT_TAKE1("BandWidthPacket", setpacket, NULL, RSRC_CONF | ACCESS_CONF,
                  "Size of the maximun packet to use."),
    AP_INIT_TAKE2("BandWidth", bandwidth, NULL, RSRC_CONF | ACCESS_CONF,
                  "a domain (or ip, or all) and a bandwidth limit (in bytes/s)"),
    AP_INIT_TAKE2("MinBandWidth", minbandwidth, NULL, RSRC_CONF | ACCESS_CONF,
                  "a domain (or ip, or all) and a minimal bandwidth limit (in bytes/s)"),
    AP_INIT_TAKE1("BandWidthError", bandwidtherror, NULL,
                  RSRC_CONF | ACCESS_CONF,
                  "a http error number. Useful to deliver standar (or personal) error messages"),
    AP_INIT_TAKE3("LargeFileLimit", largefilelimit, NULL,
                  RSRC_CONF | ACCESS_CONF,
                  "a filesize (in Kbytes) and a bandwidth limit (in bytes/s)"),
    {NULL}
};

上記コードの最初の配列要素に注目してみると、AP_INIT_TAKE2というマクロがあります。このマクロの定義は

/** method of declaring a directive which takes 2 arguments */
# define AP_INIT_TAKE2(directive, func, mconfig, where, help)
{ directive, { .take2=func }, mconfig, where, TAKE2, help }

となっていて、ディレクティブ名、設定関数へのポインタ、汎用関数で設定する構造体とオフセット、ディレクティブのスコープ(利用範囲)、説明文の4引数を取ります。mod_bwでは.htaccessファイルによる設定を許していないということなので、ディレクティブのスコープに注目します。スコープとして指定できる定数は

定数名 意味
OR_ALL 全ての場所で利用可能。
RSRC_CONF ディレクトリセクション外で利用可能。.htaccessは不可。
ACCESS_CONF ディレクトリセクションのみで利用可能。.htaccessは不可。
OR_AUTHCFG 全ての場所で利用可能。ただし.htaccessでは”AllowOverride AuthConfig”が必要。
OR_LIMIT 全ての場所で利用可能。ただし.htaccessでは”AllowOverride Limit”が必要。
OR_OPTIONS 全ての場所で利用可能。ただし.htaccessでは”AllowOverride Options”が必要。
OR_FILEINFO 全ての場所で利用可能。ただし.htaccessでは”AllowOverride FileInfo”が必要。
OR_INDEXES 全ての場所で利用可能。ただし.htaccessでは”AllowOverride Indexes”が必要。
OR_NONE AllowOverrideで上書き不可能。

となっています。これらの定数はOR演算子で組み合わせて指定することができます。例えば上記 mod_bw のコードでは RSRC_CONF と ACCESS_CONF を組み合わせて指定することで、ディレクトリセクションの内外問わず利用可能だが、.htaccessファイルでは一切設定不可能という意味になります。ところでちょっと気になったのは OR_NONE の意味です。これは.htaccessファイルによる上書き禁止ということですが、”RSRC_CONF | ACCESS_CONF” と “OR_NONE” の違いがあるのでしょうか?

/* mod_bw 0.8 で .htaccessファイルを使用可能にする */

いよいよmod_bw 0.8 を.htaccessファイルが使用できるように変更を加えます。といってもスコープを OR_ALL にするだけで.htaccessファイルが使用可能になるので、早速全てのスコープ指定を OR_ALL に置換してビルドして動作確認。

何とまたしてもあっけなく動いてしまいました・・・。

サーバを起動したまま、.htaccessファイルのBandWidthModuleディレクティブのOn/Offを切り替えてみても正しく動作しています。セグメンテーションフォールトについてはどのような状況で発生したのかを詳細に教えてもらわないと再現できそうにないため、作者に問い合わせてみます。それでも.htaccessが使えると本当に楽なので当面このバイナリを使ってみようと思います。もちろん危ない代物なのでここでバイナリ配布はしませんが、必要な方はメール(yuki {DOT} kodama [AT] gmail (DOT) com)を頂ければ送ります。

あっけない幕切れでしたが、初志を貫くという意味でこの試みは継続していこうと思います。必ずやセグメンテーションフォールトを起こす!(違

[/lang_ja]
[lang_en]

Sorry … now translating this post to English.

[/lang_en]

Written by kuy

August 15th, 2007 at 7:47 pm

Posted in Uncategorized

Tagged with , , ,

[lang_ja]mod_bwをWindowsでビルドする #2[/lang_ja][lang_en]Build mod_bw on Windows #2[/lang_en]

without comments

[lang_ja]

/* mod_bw 0.8 ビルドの準備 */

前回でmod_bw 0.7のビルドが完了したため、今回は0.8のビルドを行います。ソースはmod_bw-0.8.tgzから落とすことが出来ます。いきなり放り込んでビルドしてみてもいいのですが、どうやらこのバージョンでStableになっているので、ちょっとDiffを見てみます。

私は最近Vimに移行したということもあり、まだ多くの外部ツールに依存しています。中でもよく使用するDiffツールはRekisaです。WinMergeとかは以前使ったこともありましたが、Rekisaは3つ以上のファイルのDiffをスマートに閲覧できます。あとは同じ日本人だからなのか、どうも趣味が合うんですよね。細かいところで。TortoiseSVNのDiffツールとしてもRekisaを設定して使っています。ちなみにFolsaというフォルダDiffツールと連携するとかなり幸せになれます。ただFolsaはちょっとした問題があって、改造して使ってます。ソースコード添付感謝です。後日エントリを書きたいと思います。

たぶんこれら全部Vimでできるんでしょうけどね。徐々に移行していきたいと思います。

さて、かなり脱線しましたが、0.7と0.8の変更点の調査です。Diffを見た結果、前回のエントリで指摘した、apr_version.hヘッダがインクルードされていない問題は修正されていました。

あとは0.8のChangeLog

- Added user agent match on bandwidth and connections limiting
- Fixed issue of symbols not found on some platforms
- Updated documentation accordingly

に書いてある通り、UA(ユーザエージェント)を考慮したコードが追加されていました。

/* mod_bw 0.8 ビルド */

それでは実際にビルドしてみます。

前回のディレクトリをまるごとコピーして、mod_bw.cのみ0.8のものに差し替えてください。そしてVisual Studio 2003でソリューションファイルを開いてリビルド・・・あっけなく完了しました。Debug版ではありますが、念のため動作確認をしたところ動きました。ちなみに前回の0.7も動作確認済みです。

本家ではWindowsバイナリの配布が0.7のみだったと思うので、ここに載せておきます。動作確認した環境はWindows XP SP2 + XAMPP 1.6.0a(Apache HTTPD 2.2.4)です。

以上でこのエントリは終わりになりますが、本当の目的である原因不明のセグメンテーションフォールトの再現と修正はこれからです。

ようやくスタート。

[/lang_ja]
[lang_en]

/* Prepare for Building mod_bw 0.8 */

I have finished to build mod_bw 0.7 in previous post. Today, I try to build version 0.8. You can download source code of mod_bw-0.8.tgz from here. I think no problem to drop and rewrite source codes into folder of 0.7 but mod_bw became “stable version” from version 0.8. So I get Diff and check result.

Recently, I changed editor from EmEditor to Vim. So I still depend on many external tools. Especially I like Rekisa that is a Diff tool supported multiple files. I have used WinMerge before but WinMerge does not support diffing multiple file (three or more). And developer of Rekisa is Japanese, too. Smile I also use it as Diff tool of TortoiseSVN.

Of course, I know that Vim include these features. I think I change step by step.

OK, let’s get back to the subject. Tongue out Get Diff between 0.7 and 0.8. I checked a result of Diff and a problem that header file “apr_version.h” doesn’t include in mod_bw.c was fixed.

In changelog of 0.8

- Added user agent match on bandwidth and connections limiting
- Fixed issue of symbols not found on some platforms
- Updated documentation accordingly

I found the codes related UA (User Agent).

/* Build mod_bw 0.8 */

OK, let’s start building.

Copy the directory (previous entry), rename to other name (i.e. “mod_bw-0.8-vs”) and replace a file “mod_bw.c” (version 0.8). After this step, build with Visual Studio 2003 .NET … succeed. I checked to run correctly.

It only distribute a binary of version 0.8 for Windows in official website and you can download here. The environment I checked it is Windows XP SP2 + XAMPP 1.6.0a (Apache HTTPD 2.2.4).

This entry finish above but don’t forget. The goal is reproduction of segmentation fault and repair it.

We only arrive start line. Tongue out

[/lang_en]

Written by kuy

August 14th, 2007 at 11:21 pm

Posted in Uncategorized

Tagged with , , ,

[lang_ja]mod_bwをWindowsでビルドする #1[/lang_ja][lang_en]Build mod_bw on Windows #1[/lang_en]

without comments

[lang_ja]

/* 経緯 */

Flashでローディング表示を作るとき、ローカルサーバを使うとロードが一瞬で終わってしまいデバッグできないので、mod_bwのような帯域制限モジュールを利用することが多いと思います。

この便利なmod_bwですが、なぜか.htaccessファイルでの設定に対応しておらず、httpd.confファイルで設定する必要があります。私はデバッグ中に頻繁に制限速度を変更したくなるので、いちいちApacheを再起動するのは面倒です。.htaccessファイルに対応していない理由はREADMEによると

This mod, is able to limit bandwidth usage on every virtual host or directory. htaccess files are not supported yet, cause i’ve been having some serious segfaults when implementing it.

ということなので、無理だろうけど原因を探るべく、はじめの目標は Windowsでmod_bw 0.8をビルドすることにします。配布されているVisual Studio用のプロジェクトファイルは0.7用なので最初は0.7をビルドしてみます。ChangeLogではあんまり大きな変更はなさそうなので、たぶん0.7がビルドできたら0.8のソースに差し替えればそのままビルドできるだろう、という魂胆です。

/* Apacheのビルド */

Apacheモジュールビルドのために、まずApacheをビルドする必要があります。

Apacheのソースを落としたらデフォでVisual Studio用(たぶんVisual C++ 6.0)のdswファイルがあったのでVisual Studio 2003で開きました。変換自体は問題なくパスしたわけですが、ビルドしたらまぁお約束のエラーが出てきたわけです。

例えばmod_dirをビルドすると

fatal error RC1107: invalid usage; use RC /? for Help

ってエラーが出て、ビルドログでどんなコマンドで死んだのか見ると、

コマンド ライン “rc.exe /d “NDEBUG” /d “BIN_NAME=”mod_dir.so”" /d “LONG_NAME=”dir_module for Apache”" /l 0×409 /I “workhttpd-2.2.4buildwin32″ /I “../../include” /I “../../srclib/apr/include” /fo”Release/mod_dir.res” workhttpdbuildwin32httpd.rc” を作成しています。

というようにリソースコンパイルエラー(RC1107)が発生します。原因は見ての通りBIN_NAMEとかLONG_NAMEのディレクティブのネストされたダブルクオーテーションなので、内側のクオーテーションをシングルクオーテーションにすることで回避しました。mod_dirに限らず、libhttpdとかのエラーもこれで回避できます。

/* mod_bw のビルド */

まずソースをダウンロード。

mod_bw-0.7.tgz / mod_bw-0.7vc.zip / mod_bw-0.8.tgz

mod_bw_vsとか適当な名前のディレクトリに1つ目と2つ目のソースを解凍して、dswをVisual Studio 2003で開いて変換します。次にプロジェクトのプロパティのC/C++の全般のところのincludeパスを先ほどビルドしたApacheのディレクトリにします。リンカの入力のところはちょっと注意が必要です。設定ではlibapr.libやlibaprutil.libとなっていますが、先ほどビルドしたApacheではなぜかlibapr-1.libやlibaprutil-1.libとなっています。指定は相対パスでも絶対パスでも特に問題ないです。

この状態でビルドすると

mod_bw fatal error LNK1104: コンパイラは、ファイル ‘httpd-2.0.52oswin32BaseAddr.ref’ を開くことができません。

と表示されて、ファイルが開けないようです。しかし正しくパスを設定しても今度は

mod_bw fatal error LNK1147: オプション ‘/BASE:@httpd-2.0.52oswin32BaseAddr.ref,mod_bw.so’ で無効な番号が指定されています。

というエラーが出てきます。そもそも /BASE というオプションはDLLのベースアドレス設定のようです。解説には実行時のページングが軽減されてパフォーマンスの向上につながると書いてあります。なるほど。・・・ってことは別に無くてもいいということになるので、即刻外します。

そしてリビルドすると

mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_set が関数 _update_counters で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_cas が関数 _update_counters で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_dec が関数 _bw_filter で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_add が関数 _bw_filter で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_inc が関数 _bw_filter で参照されました。
mod_bw fatal error LNK1120: 外部参照 5 が未解決です。

と、今度はリンカエラーが出てきました。libapr-1.libに関数がエクスポートされていないのでしょうか?ちょっとlibapr-1.expをテキストエディタで開いてatomicで検索すると・・・ちゃんと各関数はエクスポートされているようです。ここでソース(mod_bw.c)を見てみると、最初の方に怪しげなプリプロセッサが見つかりました。

/* Compatibility for APR < 1 */

#if (APR_MAJOR_VERSION < 1)
#define apr_atomic_inc32 apr_atomic_inc
#define apr_atomic_dec32 apr_atomic_dec
#define apr_atomic_add32 apr_atomic_add
#define apr_atomic_cas32 apr_atomic_cas
#define apr_atomic_set32 apr_atomic_set
#endif

試しに全部コメントアウトします。そしてリビルド・・・成功。

このAPR_MAJOR_VERSIONっていうのはapr_version.hで定義されています。が、それにもかかわらず何故かインクルードされていないので、全てプリプロセッサで置換されてしまったようです。ということで

#include “apr_version.h”

をmod_bw.cに追加してリビルドするとうまくいきました。

今日はここまで。

[/lang_ja]
[lang_en]

/* Background */

When I debug flash content that includes progress bar for informing status of loading using a local web server (Apache), it will finish loading in no time. So I use “mod_bw” is a module of Apache. “mod_bw” limit band-width and number of connections from the same client.

This module is very useful but it DOES NOT support .htaccess files. Therefore, we have to configure in httpd.conf file. It mean you must restart Apache web server every time you change it. It is annoying operation for me because I very often change configurations of mod_bw. From README, the reason that mod_bw doesn’t support .htaccess is

This mod, is able to limit bandwidth usage on every virtual host or directory. htaccess files are not supported yet, cause i’ve been having some serious segfaults when implementing it.

So I try to research and remove this problem. At first, I try to build mod_bw 0.8 on Windows + Visual Studio because there is no binary of mod_bw 0.8 for Windows. it only distribute project files of Visual Studio for version 0.7 but there are only a little changes between 0.7 and 0.8. Therefore I think I will replace from 0.7 source to 0.8 source after I build 0.7 source. Tongue out

/* Building Apache */

First of all, you have to build Apache web server for building Apache module.

You can find dsw file (project file for Visual C++ 6.0) in the source code of Apache web server and open it with Visual Studio 2003 .NET. It will finish converting without troubles. However, errors will rise when you build any project in the solution of Apache web server. Yell

For instance, you build “mod_dir” project,

fatal error RC1107: invalid usage; use RC /? for Help

As you see, this is resource compile error (RC1107) and you find cause what command in the build log.

command line “rc.exe /d “NDEBUG” /d “BIN_NAME=”mod_dir.so”" /d “LONG_NAME=”dir_module for Apache”" /l 0×409 /I “workhttpd-2.2.4buildwin32″ /I “../../include” /I “../../srclib/apr/include” /fo”Release/mod_dir.res” workhttpdbuildwin32httpd.rc”

This error caused by a nested double quotations of directives BIN_NAME and LONG_NAME. So I replaced from double quotation to single quotation for avoiding this resource compile error. You can also avoid errors of libhttpd project using same way.

/* Building mod_bw */

At first, you download following archives:

mod_bw-0.7.tgz / mod_bw-0.7vc.zip / mod_bw-0.8.tgz

Extract mod_bw-0.7.tgz and mod_bw-0.7vc.zip into a same folder (i.e. “mod_bw_vs”), open and convert dsw file with Visual Studio 2003 .NET. In the next, Open project property, move to [C/C++] -> [General] -> [include path] and set the path of Apache build directory. But note at [Linker] -> [Input]. In default configuration, it setted libapr.lib and libaprutil.lib but libapr and libaprutil project of Apache solution will generates libapr-1.lib and libaprutil-1.lib. For your information, you can use both of absolute path and relative path.

You start building …

mod_bw fatal error LNK1104: compiler doesn’t open a file ‘httpd-2.0.52oswin32BaseAddr.ref’

The error of file open occured. However, you set correct path …

mod_bw fatal error LNK1147: Option ‘/BASE:@httpd-2.0.52oswin32BaseAddr.ref,mod_bw.so’ で無効な番号が指定されています。

The other error ocurred. Wait … a option /BASE specify base address of DLL in memory space. This option affect runtime performance. That is no problem without /BASE option and I removed this option.

OK, and build …

mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_set が関数 _update_counters で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_cas が関数 _update_counters で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_dec が関数 _bw_filter で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_add が関数 _bw_filter で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_inc が関数 _bw_filter で参照されました。
mod_bw fatal error LNK1120: 外部参照 5 が未解決です。

The next are linker errors. There is a possibility that functions (_apr_atomic_set, _apr_atomic_cas, …) wasn’t exported into libapr-1.lib. I have opened libapr-1.exp using text editor and searched with keyword “atomic”. As a result, each functions were exported correctly. So I opened source code (mod_bw.c) and found doubtful preprocessors at head of code.

/* Compatibility for APR < 1 */

#if (APR_MAJOR_VERSION < 1)
#define apr_atomic_inc32 apr_atomic_inc
#define apr_atomic_dec32 apr_atomic_dec
#define apr_atomic_add32 apr_atomic_add
#define apr_atomic_cas32 apr_atomic_cas
#define apr_atomic_set32 apr_atomic_set
#endif

Comment out these lines and rebuild project … succeed !  Laughing

A symbol APR_MAJOR_VERSION is defined in apr_version.h but I wonder why apr_version.h doesn’t include in mod_bw.c. So all of “… atomic … 32″ are replaced by preprocessor program. Therefore I appended

#include “apr_version.h”

to mod_bw.c and rebuild project … OK !

Thanks for reading. Wink

[/lang_en]

Written by kuy

August 12th, 2007 at 4:11 am

Posted in Uncategorized

Tagged with , , ,