挑戦してみたのですが、どうしてもやり方がわかりませんでした。
http://dqn.sakusakutto.jp/2012/05/apache_mongodbshell_javascript_cgi.html
ご教授のほど、よろしくお願いいたします。
おもしろそうですね。
CGIだと動作自体は重そうですが、DBの内容をJSONで出力するような用途なら簡単な記述で済みそうです。
で、本題ですが、やはり環境変数に関するものは無さそうです。なのでラッパー書いてみました。
環境変数は--evalオプションつかって、変数ENVに代入してます。
POSTの内容はENV.POSTに入れました。通常1行だと思いますが複数行であれば「;」でつなげています。
また、コマンドラインに入れる関係上、最大長が気になるのでとりあえず3,000バイトを制限値にしてます。これは--evalやめてファイル経由にすれば解決はしますが手抜きしました。
あと、環境変数に複数行入っている事は考慮してません。多分エラーにならず無視というか、ENVのキー扱いになるだけのはずです。SERVER_SIGNATUREとか複数行の事がある様な気がしてますが、多分使わないだろうから手抜きしました。
POSTやQUERY_STRINGは自前でパースすることになります。
と書いてみたものの、正直安全面は、エスケープとか充分なのか分かりません。
実用的にはperlとかで既存のライブラリ使ってJSONにした方が安全なのでしょうけれど、それやっちゃうとMongoDBのCGIなのと言う疑惑がw
#shやsedは良いのか?というと広い意味でOSの一部ということで。perlも微妙だけれど。
MongoDB自体で環境変数や標準入力に対応してもらえば一番なのでしょうけれど。
mongowrapper
#!/bin/sh env='POST:"' if [ "0$CONTENT_LENGTH" -lt 3000 ]; then env=$env`sed -e 's/[[:cntrl:]]//;s/["\\\\]/\\\\&/g;1h;1!H;${g;s/\n/;/g;p;};d'` fi env=$env'"' env=$env`printenv | sed -e 's/[[:cntrl:]]//;s/["\\\\]/\\\\&/g;s/^/"/;s/=/":"/;s/$/"/;H;${g;s/\n/,/g;p;};d'` /usr/local/bin/mongo --quiet --eval "var ENV={$env}" "$1"
呼び出しはこんな感じで。
#env付けないとエラーになるのは何でだっけ?
#!/usr/bin/env /path/to/hoge/mongowrapper print("Content-type:text/plain\n"); print("ENV="); printjson(ENV);
最後に。
このラッパーは引数を一つしか見ません。
ブログの方で、"?foo"を付けるとエラーメッセージ出るのはCGIの仕様
http://ja.wikipedia.org/wiki/Common_Gateway_Interface
QUERY_STRINGに文字'='が含まれない場合は、サーバはQUERY_STRINGの内容をコマンドライン引数としてCGIプログラムに渡す。
でMongoDBshellの引数として付いた"foo"をスクリプトファイルとして解釈するからだと思います。なので引数1つにしました。
#本当は引数チェックしてスイッチとか渡せばいいけれどこれも手抜き。
正確に言うとmongoDBshell です。(javascript実行環境)
hello worldは動きました。
おもしろそうですね。
CGIだと動作自体は重そうですが、DBの内容をJSONで出力するような用途なら簡単な記述で済みそうです。
で、本題ですが、やはり環境変数に関するものは無さそうです。なのでラッパー書いてみました。
環境変数は--evalオプションつかって、変数ENVに代入してます。
POSTの内容はENV.POSTに入れました。通常1行だと思いますが複数行であれば「;」でつなげています。
また、コマンドラインに入れる関係上、最大長が気になるのでとりあえず3,000バイトを制限値にしてます。これは--evalやめてファイル経由にすれば解決はしますが手抜きしました。
あと、環境変数に複数行入っている事は考慮してません。多分エラーにならず無視というか、ENVのキー扱いになるだけのはずです。SERVER_SIGNATUREとか複数行の事がある様な気がしてますが、多分使わないだろうから手抜きしました。
POSTやQUERY_STRINGは自前でパースすることになります。
と書いてみたものの、正直安全面は、エスケープとか充分なのか分かりません。
実用的にはperlとかで既存のライブラリ使ってJSONにした方が安全なのでしょうけれど、それやっちゃうとMongoDBのCGIなのと言う疑惑がw
#shやsedは良いのか?というと広い意味でOSの一部ということで。perlも微妙だけれど。
MongoDB自体で環境変数や標準入力に対応してもらえば一番なのでしょうけれど。
mongowrapper
#!/bin/sh env='POST:"' if [ "0$CONTENT_LENGTH" -lt 3000 ]; then env=$env`sed -e 's/[[:cntrl:]]//;s/["\\\\]/\\\\&/g;1h;1!H;${g;s/\n/;/g;p;};d'` fi env=$env'"' env=$env`printenv | sed -e 's/[[:cntrl:]]//;s/["\\\\]/\\\\&/g;s/^/"/;s/=/":"/;s/$/"/;H;${g;s/\n/,/g;p;};d'` /usr/local/bin/mongo --quiet --eval "var ENV={$env}" "$1"
呼び出しはこんな感じで。
#env付けないとエラーになるのは何でだっけ?
#!/usr/bin/env /path/to/hoge/mongowrapper print("Content-type:text/plain\n"); print("ENV="); printjson(ENV);
最後に。
このラッパーは引数を一つしか見ません。
ブログの方で、"?foo"を付けるとエラーメッセージ出るのはCGIの仕様
http://ja.wikipedia.org/wiki/Common_Gateway_Interface
QUERY_STRINGに文字'='が含まれない場合は、サーバはQUERY_STRINGの内容をコマンドライン引数としてCGIプログラムに渡す。
でMongoDBshellの引数として付いた"foo"をスクリプトファイルとして解釈するからだと思います。なので引数1つにしました。
#本当は引数チェックしてスイッチとか渡せばいいけれどこれも手抜き。
なるほど!!
その発想はなかったです。
shを経由すればよかったんですね。
あと、PerlのCGIをかませばいろいろできそうですね!
ありがとうございます!
#env付けないとエラーになるのは何でだっけ?
シェバングは再帰的に解釈されないから、コマンドにスクリプトが指定できない。
# じゃなかったっけ。
なるほど!!
2012/05/28 01:21:33その発想はなかったです。
shを経由すればよかったんですね。
あと、PerlのCGIをかませばいろいろできそうですね!
ありがとうございます!
シェバングは再帰的に解釈されないから、コマンドにスクリプトが指定できない。
2012/06/02 15:50:03# じゃなかったっけ。