PMAFind
Webサーバのログに記録されていたものにPMAFindというphpMyAdminを探索するロボットプログラムがいました。
/phpmyadmin/main.php /PMA/main.php /mysql/main.php /admin/main.php /db/main.php /dbadmin/main.php /web/phpMyAdmin/main.php /admin/pma/main.php /admin/phpmyadmin/main.php /admin/mysql/main.php /mysql-admin/main.php /phpmyadmin2/main.php /mysqladmin/main.php /mysql-admin/main.php /main.php /phpMyAdmin-2.5.6/main.php /phpMyAdmin-2.5.4/main.php /phpMyAdmin-2.5.1/main.php /phpMyAdmin-2.2.3/main.php /phpMyAdmin-2.2.6/main.php /myadmin/main.php
のようなパスを探しているようです。注意、注意。
PERL_DL_NONLAZY
とある環境で、PerlのTestを書いていて、make testを実行すると
install_driver(Oracle) failed: Can't load '/usr/lib/perl/site_perl/5.005/sun4-solaris/auto/DBD/Oracle/Oracle.so' for module DBD::Oracle: ld.so.1: /opt/local/bin/perl: 重大なエラー: 再配置エラー: ファイル /usr/lib/perl5/site_perl/5.005/sun4-solaris/auto/DBD/Oracle/Oracle.so: シンボル newSVuv: 参照シンボルが見つかりません。
というエラーに出くわすことがありました。これは、テスト実行時のPERL_DL_NONLAZY=1という環境変数設定を抜いてやるとうまくいったのですが、なぜテストの時はLAZYロードにするのかな?と疑問に思い調べてみると、
ExtUtils/MM_Unix.pm For some reason which I forget, Unix machines like to have PERL_DL_NONLAZY set for tests.
だそうです...
ExtUtils-MakeMakerの古いバージョン(その環境のものは5.4302)だと、ExtUtils/MM_Unix.pmに
$perl = "PERL_DL_NONLAZY=1 $perl" unless $Is_Win32;
とべた書きしてあって、LAZYロードに変えることはMakeMakerのオプションではできないようです。
なので、Makefile.PLで↓のようにして対処しています。
use ExtUtils::MakeMaker; use File::Copy; WriteMakefile( # ・・・ ); open(IN, "Makefile") || die; open(OUT,">Makefile.tmp") || die; while(<IN>) { s/PERL_DL_NONLAZY=1//g; print OUT; } close(OUT); close(IN); move("Makefile.tmp", "Makefile");
まあ、そもそもDBD/Oracle/Oracle.soのビルドの問題ではあるのですが...(多分、バイナリを他所から持ってきたのではと推測)
CでRubyモジュールを作る
PerlのXSがsoを読み込むPerlモジュールファイル(.pm)を必要とするのに比べて、Rubyのrequireは.soファイルを直接読み込んでくれるので、ちょっとばかり簡単です。
.soの作り方は、svn.ruby-lang.orgにあります。
CのコードはRubyのマクロをふんだんに使って記述します。
static VALUE rb_hello_c(self) VALUE self; { return rb_str_new2("Hello C"); } void Init_hoge() { VALUE rb_cHoge = rb_define_class("Hoge", rb_cObject); rb_define_alloc_func(rb_cHoge, rb_hoge_s_alloc); rb_define_private_method(rb_cHoge, "initialize", rb_hoge_initialize); rb_define_method(rb_cHoge, "hello_c", rb_hello_c); }
.soと.rbで同名の拡張モジュールにしたい場合は、.soと.rbを同じところにおき、.rb側に
◆hoge.rb require 'hoge.so' class Hoge def hello_rb "Hello Ruby" end end
と書けば、.rbが先に読み込まれ、続いて.soが読み込まれます。
◆hoge_test.rb require 'hoge' hoge = Hoge.new puts hoge.hello_c puts hoge.hello_rb
「クラス中のあるメソッドだけは、Cライブラリを使いたい」なんて時にはこれで対応できます。
セッションIDの作り方
セッションIDを生成する際にもっとも使われているのはMD5やSHA-1などで、時間やプロセスIDをハッシュ化する方法でしょうか。実際にRubyのCGI::Sessionは、こんな感じです。
def create_new_id require 'digest/md5' md5 = Digest::MD5::new now = Time::now md5.update(now.to_s) md5.update(String(now.usec)) md5.update(String(rand(0))) md5.update(String($$)) md5.update('foobar') @new_session = true md5.hexdigest end
ただ、MD5やSHA-1でも天文学的な確率で(ハックではない偶然)、コリジョンすることを恐れてユニーク性を保証したいという場合もあります。これは、システムでユニークな連番を振ってIDに付け加えればよいでしょう。つまり、
デタラメな値(できるだけユニーク、推測が不可能) + システムユニークID(推測されても仕方なし)
という組合せでセッションIDのユニーク性とハック不可能性を同時に達成することになります。
ところが、世の中にはとほほなものもあります。時間やプロセスID(できるだけユニーク、推測が不可能)を素のまま使い、それに連番(推測されても仕方なし)を付け加えるケースです。
113555965892740005
これでは、推測不可能があやしくなります。こんなセッションIDがあったら、見る人が見ればシステム時間を使っていると推測されるでしょう。時間やプロセスIDを使っては発番されるIDの帯域を自ら狭めていることになります。「できるだけユニーク、推測が不可能」の部分は単に同じ桁数のランダム値を用いたほうが堅牢です。
Rails + Windows + Mysql(SJIS)
この組合せだとMysqlと日本語のやりとりをするときに文字化けします。「UTF-8を使え」というのが簡単な解決策ですが、しがらみ等あってそうはいかない場合もあると思いますので回避方法を...
どこかのドキュメントに書いてあるのかもしれませんが、探せなかったのでソースを読んでみる。ActiveRecordのconection_adapters/mysql_adapter.rbに
private def connect encoding = @config[:encoding] if encoding @connection.options(Mysql::SET_CHARSET_NAME, encoding) rescue nil end @connection.real_connect(*@connection_options) execute("SET NAMES '#{encoding}'") if encoding end
という行があります。@configすなわちdatabase.ymlで設定できるということです。
development: adapter: mysql database: Depot_development host: localhost username: scott password: tiger encoding: sjis
こんな感じでOKです。
Railsのrakeタスクあれこれ
rake -Tでrakefileに定義されているタスクを一覧表示できます。いろいろあって覚えきれないので、ココにメモっておきます。(rails-0.14.4ベース。よく使うものだけ)
タスク | 説明 |
---|---|
clear_logs | すべてのログを削除します。開発中は大量のdevelopment.logが出力されるので必須 |
clone_structure_to_test | development環境からtest環境へスキーマ定義を移行します。 |
db_schema_dump | ActiveRecordを使ってDB定義をdumpします。db/schema.rbに出力されます。 |
db_schema_import | db_schema_dumpで出力したものをimportします。 |
db_structure_dump | DDLを出力します |
stat | 行数、クラス数、メソッド数などのメトリクスを出力できます。面白いのはプロダクトコードとテストコードの比率も出力してくれること。 |
recent | 10分以内に更新したテスト、10分以内に更新したモデル・コントローラのテストを実行する。 |
こう並べてみると、他のフレームワークと異なり、Rails気が利くタスクがたくさんあり、痒いところに手が届くものになっていることが分かります。