BMU さん、
どうもありがとうございます。
ちょこちょこ覗いていたのですが、ようやくこのゲストブックも静かになってきたようですね。
中田さん、ご苦労様です。
私はアパッチを少しかじってみましたが、数週間ぶりに再びAnHttpdを使わしていただいたところ、簡単な設定で使える便利さが改めて感じられました。なにやら少し懐かしかったです。
今までほしい機能ばかりを書き込んで、何かと失礼なことを申し上げていたと思います。申し訳ありませんでした。しばらくプログラミングしていなかったせいか、プログラムを作るのはそう簡単ではないことを忘れてしまっていたようです。
アパッチのほうはとりあえず順調に動いてくれています。中田さんのおっしゃられたとおり、私にはこちらのほうが性に合っているのかもしれません。
しかし、このAnHttpdはISAPIやCGIのテスト環境としては設定も簡単で使いやすいので、今後も使いつづけていくつもりです。簡単に自宅サーバを立ち上げることの出来る、こういったソフトを開発してくださった、中田さんにはあらためて感謝します。
分かりました。Apacheは設定が難しそうですが、試してみます。
BMU さん、
0 というのは、0 CRLF CRLF の 0 でチャンク形式エンコーディングの終わりを示します。
もちろんそれだけを出すのはおかしいので、AN HTTPD の手抜きのバグということになります。
本来は 500 エラーを返すべきなので、そのように直そうと思います。
それとは別にこれは提案なのですが、BMUさんは AN HTTPD 以外の HTTPサーバを使うことにした方がいいように思います。 IIS でも Apache でも今やっていることはできるほずだと思いますし、ISAPIの実装もIISは本家ですからちゃんとしていると思います。ISAPIフィルタも使えますから、その方がうまくいくかもしれません。
もちろん AN HTTPD のバグ解消に協力していただけるのであれば私としてはその方がありがたいのですが、なかなか時間がかかってしまうと思うので、BMUさんにとっては IIS や Apache などを使う方がいいのではないかと思うのです。
確かに、例外処理を怠っていたようです。私のミスでした。
しかし、同時にIEのブラウザも挙動不審を起こすようです。他のブラウザでは「0」となど表示されません。一体何なんでしょうか「0」とは。ちなみにソース表示でもファイルの内容は「0」だけです。再起動すれば直るのでどうでもいいことですが、画像転送も変になるようです。
BMU さん、
DLL側は(必要な場合の)同時アクセス対策はしてあるのですよね(?)。
そうですね。分かりました。
それから、てっきりBorland C++はC++Bulderのことかと思っていました。C++言語のほうはあまりよく知らないので。
ちなみに情報の出所は、以下のURLです。
http://www2.justnet.ne.jp/~tyche/bcbbugs/reports/dll001.html
http://www2.big.or.jp/~osamu/Delphi/Tips/key.cgi?key=12#0106.txt
しかし、自作の意地悪テストプログラム(HTTPD経由で絶え間なく連続してdllにアクセスする)で、試してみたのですが、4500回以上アクセスしてもメモリリークは起きなかったようです。だとすると、これが原因ではないかもしれません。お騒がせて申し訳ありませんでした。同様のテストプログラムで試してみた所、DLLに同時アクセスするとエラーが発生するようです。その後スレッドの起動が不安定になりました。
NameServer1 さん、
また話がそれてしまいますが、AN HTTPD が何を使ってコンパイルしているかは readme.html を見てもらえばわかります。
Borland 系のコンパイラのメモリリークと BMUさんの 「Can't begin 」エラーとはまだむすびついていません。
もう少し調べてみないとわかりませんが、今のところ別の話ではないかと思っています。
中田さん、
BMUさんが当てた理由としては
orland C++ - Copyright 1996 Borland Intl.
という文字がhttpd.exe内に入っているからだと思います。
BMU さん、
C++ Builder ではなくて、それより古い Borland C++ です。
それはともかく、その情報の出所を教えてくれませんか?
もちろんロードしてアンロードしなければいいのはわかっていますが、現状の AN HTTPD の ISAPIインタフェースでそれをやると、少なくとも PerlIS.dll で不具合が出るのです。
対策は考えますが、これも時間がかかると思います。
とりあえずは定期的に net stop/start などをしてください。
私もいろいろ調べてみました。C++Builder(恐らくこれを使われているのではないかと思うのですが)でもその現象は確認されているようです。
対処法は、「一度ロードしたDLLは最後まで解散しない」、か「インポートライブラリを使う」となっていました。
とりあえず、最初から一般タブで拡張子の実行プログラムの設定で使うと分かっているDLLは、サーバ起動時に読み込んで終了時に解散する、としていただけないでしょうか。そうすれば私が使う分の問題はなくなると思うのですが。
ただ、その他、使用するかが定かではない物の場合は、ISAPI DLLの使用を避けるか、NameServer1さんの自動再起動のツールみたいなのを使うしかないのでしょうね。
BMU さん、
それはWindowsではしょうがないという話ですか?
私も調べて確認してみます。
ISAPI DLLは、しばらく正常に動作していたのですが、突然動作しなくなってしまいました。アクセスすると、ブラウザに「0」とだけ表示されます。サーバのエラーログを見ると(もう残っていないのでうろ覚えなのですが)「Can't begin thread」次の行に「error 0」と記録されていました。DLL側の問題かと思っていたのですが、問題となるようなことは見つからず、そのエラーの後は他のCGIも起動できなくなるようです。AnHTTPDのサービスを再起動すると正常に戻りました。
原因は全く分からないのですが、「DLLの動的ロード、リロードを数百回繰り返すとメモリリークを起こす」という話を聞いたことがあります。これが原因とは限りませんが、一般タグでHTTPサーバ機能のチェックを外して、適用して、もう一度チェックをつけても改善されませんでしたので、恐らくこれが原因のような気がします。
BMU さん、
両方ともいずれ対応する予定です。あまり優先度は高くない内容だと思いますので、だいぶ先になってしまうかもしれませんが。
ありがとうございました。前回の件はクリアできました。
しかし、デフォルトインデックスがどうであれ、「.htm」か「.html」で認識しているのであれば、「.htm,.html」に関連付けられたISAPIDLLで処理されなければならないと思うのですが、どうでしょうか。
また、話は変わるのですが、バーチャルホストごとに一般のタグのCGI、SSIの部分を設定できるようにはならないのでしょうか。現行のバージョンでは、その部分はすべてのバーチャルホスト共通になっていると思います。それぞれ個別に設定がしたいのですが。
BMUさん、
デフォルトインデックス:index.html,index.htm
ではダメでしょうか?
先回「/index.html」はアクセスできるが「/」では出来る、と書きましたが、よく見てみると「/index.htm」の間違いでした。
デフォルトインデックスは「index.html」に設定されています。ドキュメントルートに「index.htm」を置いていたので、デフォルトインデックスの設定を「index.htm」に変更してみると、「/」でアクセスしてもISAPI DLL(以下DLL)で処理されるようになるようです。しかし、その設定でドキュメントルートに置かれている「index.htm」のファイル名を「index.html」に変更すると今度は処理されなくなってしまいます。(もちろん逆も試してみました)
補足ですが、サーバの設定ではこのDLLで実行する拡張子を「.htm,.html」と設定しています。
ファイル名が「index.htm」でも「index.html」でも「/」でできるように出来ないのでしょうか?
BMU さん、
そうですか? 私が確認したところではちゃんと動くようですが。。。
BMUさんがどういう設定をしているか、 HKEY_LOCAL_MACHINE\Software\AnHttpd 以下をファイルにしてメールで送ってもらえば見てみますけど。
しばらく前のhtmlファイルの実行ファイルとしてISAPIのDLLを指定する方法を試してみたのですが、大方うまく動くようになりました。しかし、「/index.html」でアクセスするとうまくいくのですが、「/」でアクセスすると、DLLで処理されないようです。なにか良い方法はないでしょうか?
ちょうど、私もその方法に気付いた所です。早速試してみます。
お忙しいのに、色々とすいませんでした。
BMU さん、
ISAPI DLL を使うのなら、.html の実行ファイルとしてそのDLLのパスを指定してもらえば現在のバージョンでできます。
DLLをドキュメントルートに置く必要はありません。
MoreInfinityさん、それも考えてみたのですが、おっしゃっているように「http://hogehoge/xxx.dll/index.html」とすると「http://hogehoge/index.html」とするよりも、見かけがかなり不格好になってしまい、そのやり方だと「GET /」でもアクセスできるので意味がなくなってしまいます。ドキュメントルートにDLLのみを置いて、そのDLLで別の所を参照するように作っておけば「http://hogehoge/xxx.dll/index.html」のみでアクセス可能になるとは思いますが、まず「GET /」か「GET /index.html」でアクセスするのが一般的なのに、それでアクセスできなくなってしまいます。それでは、見かけも中身もいいとはいえません。
とはいえ、的確な面白い意見をありがとうございました。私も初心に返って頭の中を整理することが出来ました。それで、私の最初の発言からセキュリティやSSIやDLLプラグイン云々の話はすべてなかったことにして、改めて中田さんにお願いしたいのですが、ドキュメントルートに「c:\httpd\www\xxx.dll」というように、CGIやISAPI/NSAPI DLLを設定できるように出来ませんでしょうか。そう設定できれば現在のバージョンで「http://hogehoge/xxx.dll/index.html」としなければならない所を、「http://hogehoge/index.html」でアクセスできます。もし、こうすることの利点がないようでしたら、見かけだけの問題ですので現行のままで結構です。こちらの考えている利用法や利点を書いても、ただややこしくなってしまうだけで、余計に難解になってしまうだけだと思いますので、もし分からなければ、そう言ってもらえばこちらで工夫して目立たないように何とかします。
BMUさん、
あまり詳しくない者が言うことじゃないかもしれませんが、
http://hogehoge/xxx.dll/index.htmlとかだけでアクセスするようにしたらいいんじゃないですか? 見掛けをたいせつにするとかなら、分かりませんが。
BMU さん、
申し訳ありませんが、今までの話をあわせて何をどう実装すればいいのかまだ理解できませんので「DLLプラグイン」の方は対応できそうにありません。
もう一度SSIでの方法も探ってみますが、とりあえずDLLプラグインについて書かせていただきます。
まず、「どうして効率が良くなるのか」については、DLLで従来のSSIとは全く別な方式で構文解析する、ファイルの先頭にDLLのタグがある場合、それだけを指示として読み取る、などして不要な解析をなくすつもりです。(*.shtmlのみSSIを使うということは従来のままでできますが、そういうことではなく処理内容をまとめてファイルの頭に書いておくということです)
また、「セキュリティ」については、タグにパスワードが含まれていなければ実行しない、また、設定ファイルで指定されたディレクトリ以下以外のファイルでは実行しない、などです。また、ディレクトリによって一部機能に制限をかけたりすることも出来るかもしれません。(例えば、別のディレクトリのファイルなどをincludeできないようにする、execコマンドの範囲を制限するなど)
以上のことはDLLを使わなくても出来るかもしれません。ただ、前述のセキュリティのための機能制限については、どうしても必要ですのでどちらにしても実装していただければありがたいです。もし、そうするための方法が既にあれば教えてください。お願いします。
BMU さん、
Apache の SSI のような 変数のセットや条件分岐 以上に「柔軟性を持たせたい」項目としてはどのようなものがありますか?
また、「DLLプラグイン」によってなぜ「セキュリティが高くなる」のかと、なぜ「効率が上がる」のか、もう少し説明してもらえませんか?
はい、つまりはそういうことです。SSIよりも柔軟性を持たせたい、かつセキュリティを高めたい、そして効率を上げたいということなんです。
はじめからそう説明出来ればよかったのですが…。
お忙しい中、本当にすいませんでした。
BMU さん、
そうすると、実装方法(DLLを使うかどうかなど)は別として、機能としては SSI(とその拡張)との違いは何ですか?
つまり、SSIを拡張すればよいように思えるのですが、それではうまくいかない理由を知りたいのです。
あるいは、index.htm の中身とレスポンスの具体的な例を示してもらうのでもよいかもしれません。
たとえば、index.htm に
このファイルは//LAST_MODIFIED//に更新されました。
という記述がある場合、GetResult() は、Content として上の部分を
このファイルは2003年8月20日に更新されました。
に置き換えて AN HTTPD に戻す、とか。
この例だと SSI でできると思いますから、SSIではうまくいかない例が欲しいです。
あるいはSSIよりも柔軟なものを、という話であればそれはそれで理解できるのですが。
私が説明下手ですいません。
>>プラグインの機能は個々のファイルに対してそれぞれの処理をしたいからです。
>の方の話ですよね?
はい、その通りです。
しかし、念のためですがDLLが実際にファイルを書き換えるという機能ではありません。以前、仮想パスにするとややこしい云々絶対パスにして欲しいと書いていましたが、よく考えてみればそれは必要なさそうです。余計に分かりにくくしてしまったことを謝罪します。
さて、この前の例でTAnHTTPRequest型に変数ReqFileがあるとして、Requestされたファイルのパスと名前(例:"/test/index.htm")が格納されているとします。そしてhogehoge.dllの関数GetResultは独自の設定ファイルを読み込んで、そのReqFileの値によって(ファイルの中の特定の文字列を置換するなど)どう処理するかを振り分けるわけです。
他にも各HTMLファイルにhogehoge.dllへの指示を書き込むなど、それぞれのファイルにそれぞれの処理を出来るようにします。これはDLLのほうで実現可能です。
そして、DLLの関数がファイルの内容を処理して出力したものをAnHttpdにクライアントに渡してもらいます。
>>3.関数GetResultの戻り値の内容をクライアントに返す
>という時の、戻り値の例をあげてください。
先回、戻り値はPChar型と書いていましたが、TAnHTTPResuest型とほとんど変わらないTAnHTTPResponse型の間違いです。よく考えてみればこの2つの型は分けなくてもいいかもしれません。どちらにしても、その中の変数Contentにファイルの内容、変数ContentLengthにファイルのサイズ……など格納して返します。しかし、これではDLLで確保したメモリが解散がうまくできないと思います(メモリ関連の知識が未熟なことをお許しください)。AnHTTPdの詳しい構造は分からないので何ともいえませんが、他にも値を戻すのにコールバック関数を利用するなどの方法はいろいろ考えられます。
BMU さん、
ますますわからなくなりました。
>プラグインの機能は個々のファイルに対してそれぞれの処理をしたいからです。
の方の話ですよね?
>3.関数GetResultの戻り値の内容をクライアントに返す
という時の、戻り値の例をあげてください。
設定変更時だけではなく起動時もでした
すいません、説明不足でした。例えばこんな感じです
1.ANHTTPDが設定変更時にDLLを読み込む
2.リクエストがあると、まずレスポンスをクライアントに返さず、DLLに渡す。
例) hogehoge.dll の function GetResult(Req:TAnHTTPdRequest※):PChar;を呼び出す。
※ TAnHTTPdReqestの宣言(Delphi風)
type>C言語ならstructやunionなど
TAnHTTPdReqest = record;
LastModified:TData;
ContentType:array [0..255] of char;
ContentLength:integer;
Content:PChar;
:
などその他諸々
end;
BMU さん、
再読み込みの方はわかるのですが、「プラグインの機能」の方はどうでしょうね。
また、「DLLプラグイン」というのもちょっと理解できません。もう少し説明してもらえますか?
外部からもhttpでコントロールできるようにするとセキュリティ的に危険ですね。127.0.0.1かlocalhostからのリクエストのみ受け付けるとかすればいいかもしれません。それでも危なっかしいので、やはりプラグインという手ですね。その場合CGIの出力をどうするかが問題ですね。とりあえずパスも知りたいので、パスとファイル情報とCGI出力をDLLの関数に渡して、そのの関数の戻り値をクライアントに返すようにすれば完璧です。
ご多忙のこととは存じますが、よろしくお願いします。
先ほどのコメントで目的が不明確でしたので補足しておきます。
プラグインの機能は個々のファイルに対してそれぞれの処理をしたいからです。(最終更新日その他の変数・定数の挿入など)
また、再読み込みの機能はユーザ管理を別のソフトでしたいと思っているので必要だからです。
お願いします。
はじめまして。いつもAnHttpdを使わせていただいております。
さっそくですが、欲しい機能についてです。
リクエスト 「GET /test/index.html」となるとき、内部的に「GET /cgi-bin/hogehoge.cgi?url=c:\www\test\index.html」の内容をレスポンスするするような機能がほしいと思います。効率が悪くなるのでcgiでなくてもDLLプラグインが使えたら嬉しいです。効率を重視して特定の拡張子のみそうする機能があればもっといいです。わがままかもしれませんが、仮想パスの場合プラグインのソースがややこしくなりそうなので引数に渡すのは絶対パスでお願いします。
また、外部プログラムから「An Httpd」設定のレジストリをいじったときに(サービス再起動などをせずに)an httpdのウィンドウにメッセージを送った時や「GET /httpd-command/restart?pass=password」などの特定のリクエストを送った時などに設定読み直しをしてくれるような機能もあればと思います。
よろしくお願いします。