努力してみた日記
あまりためにはならない話しか書かないと思うよ。2012-04-30 切り替え終了
■ [雑記] バーチャルホストなapacheサーバにIPアドレスでアクセスするとどうなるの?
VMイメージのコピーで済ませられたらいいのになぁ....まぁある程度は仕方ないか。
で、VPS移行作業中ちょっと分からない事が出てしまいました。マルチホストなapacheサーバにIPアドレス指定でアクセスされた場合どうなるのかって話です。
■ ひとつのIPアドレスにA,B二つのホストの構成の話
HTTP1.1はHostヘッダの内容でクライアントがどのホストにアクセスしているのか明示します。
apacheはこのヘッダを見て、DocumentRootを切り替えられます。Aなら /usr/local/www/A 、Bなら /usr/local/www/B 、に振り分けできます。
じゃあさ、ホスト名じゃなくてIPアドレスだったらどうなるの?
■ 答え:「最初に記述されたブロックの設定が使われる」
→@IT - バーチャルホストによる複数サイトの同時運用(2/2)
邪悪になるな、でおなじみのGoogle先生を使い調べてたところ上記リンクのページに書いてありました。最初に記述された VirtualHostディレクティブの設定が適用されるとのこと。
実際に試して目視確認。ふーむ。するとIPアドレス指定の場合の振り分けは出来ないってことか。
2012-04-24 移行しちゃおうか....
■ [雑記] さくらVPSのプラン変更優待
今契約しているのが、さくらVPSの旧プラン512。2Core 512MB HDD20GBで980円/月のVPS。
これを期間内で移行するなら、旧プランの残り期間分の返金および移行先プランの1ヶ月無料をやってくれる(金額を減らすのではなく、無料使用期間が1ヶ月付く)。新プランの3Core 2GB HDD200GBだと1480円/月。
旧プランもそのうち512MB→1GBへのメモリ変更があるらしいけど、ディスク容量が足りないんだよな...将来的に置こうと思っているコンテンツが置けない。ただその将来がいつなのかが未定という(^^;;
500円上乗せでこれなら移行してもよいとも思うし。うーどうしよかね。
2012-04-17 油断できないのぅ
my $Cc = 'abc@hoge.jp, "def@hoge.jp" <ghi@hoge.jp>';
my @addrs = $Cc =~ /((?:[a-zA-Z0-9\.!#\\$%&'*+-\/=\?\^_\`\{\|\}\~]+|"[a-zA-Z0-9\.!#\\$%&'*+-\/=\?\^_\`\{\|\}\~ \(\)<>\[\]:;@,\"\\]+")@[a-zA-Z0-9\.-]+)/g;
my $i=1;
foreach my $addr ( @addrs )
{
print "$i: $addr\n";
$i++;
}
EOF
結果はというと。
1: abc@hoge.jp 2: def@hoge.jp 3: ghi@hoge.jp
出て欲しいのは abc@hoge.jp と ghi@hoge.jp の二つなんですよ。
名前部分にメールアドレスらしきものがあると駄目になる例ですね。
これを避けるには、ダブルクォートではさまれた部分を無視するようにしなくちゃいけないんだけど、
"this is test"@hoge.jp
みたいなメールアドレスもありうるので(実質使われていないとは思うんですけどね)判断が難しいんですよ。
名前部分の囲みなのかメールのローカル部の囲みなのか、これじゃあ判断できないですー、ってことに。
■ じゃあ名前とメールアドレスをパースしちゃえばいいじゃない!
メールアドレスだけをパースしようとするからいけないんだ。名前とメールアドレスをパースしてあとでメールアドレスだけ集めちゃえばいいじゃない!ってことで、無理に正規表現をこねくり回さないで素直に書いてみたのが次のコード。
my $Cc = 'abc@hoge.jp, "def@hoge.jp" <ghi@hoge.jp>, "are you \"ready\" ?" jkl@hoge.jp, ThisIsTest mno@hoge.jp ( other email pqr@hoge.jp ), "this is test"@hoge.jp';
my @addrs = $Cc =~/"(?:\\"|\\\\|[a-zA-Z0-9\.!#$%&'*+-\/=\?\^_\`\{\|\}~ \(\)<>\[\]:;,@])+"(?!@)|\((?:\\"|\\\\|[a-zA-Z0-9\.!#$%&'*+-\/=\?\^_\`\{\|\}~ \(\)<>\[\]:;,@])+\)|[a-zA-Z0-9\.!#$%&'*+-\/=\?\^_\`\{\|\}\~]+@[a-zA-Z0-9\.-]+|"(?:\\"|\\\\|[a-zA-Z0-9\.!#$%&'*+-\/=\?\^_\`\{\|\}\~ \(\)<>\[\]:;,@])+"@[a-zA-Z0-9\.-]+/g;
$i=1;
print "****\n$Cc\n****\n";
foreach my $ml ( @addrs )
{
$a = ($ml =~ /^["\(].+["\)]$/) ? " " : "*";
printf("%03i: %1s [%s]\n", $i, $a, $ml);
$i++;
}
ええ、こそーっと一部正規表現をなおしてます。途中で気が付いちゃったもんで(^^; 実行するとこんな感じ。
**** abc@hoge.jp, "def@hoge.jp" <ghi@hoge.jp>, "are you \"ready\" ?" jkl@hoge.jp, ThisIsTest mno@hoge.jp ( other email pqr@hoge.jp ), "this is test"@hoge.jp **** 001: * [abc@hoge.jp] 002: ["def@hoge.jp"] 003: * [ghi@hoge.jp] 004: ["are you \"ready\" ?"] 005: * [jkl@hoge.jp] 006: * [mno@hoge.jp] 007: [( other email pqr@hoge.jp )] 008: * ["this is test"@hoge.jp]
アスタリスクの付いた、001,003,005,006,008がお目当てのメールアドレスになります。つまり、切り出した要素の両脇がダブルクォートか括弧で囲まれてなければメールアドレスと判断すればよろし。
007は、メールアドレスのあとに書けるコメントです。こちらにもメールアドレスが書かれてしまう可能性があるので組み込んでおきました。
■ 正規表現が長いのでちょっと説明
先の正規表現では4つの文字列にマッチングします。
- "(?:\\"|\\\\|[a-zA-Z0-9\.!#$%&'*+-\/=\?\^_\`\{\|\}~ \(\)<>\[\]:;,@])+"(?!@)
- ダブルクォートで囲まれ最後が『〜"@』で終わらない文字列にマッチングします。『〜"@』で終わるとメールアドレスのローカル部にもマッチングしてしまうためです。
- \((?:\\"|\\\\|[a-zA-Z0-9\.!#$%&'*+-\/=\?\^_\`\{\|\}~ \(\)<>\[\]:;,@])+\)
- ダブルクォートの替わりに括弧"()"で囲まれた文字列のマッチングします。
- [a-zA-Z0-9\.!#$%&'*+-\/=\?\^_\`\{\|\}\~]+@[a-zA-Z0-9\.-]+
- ローカル部がダブルクォートで囲まれていないメールアドレスにマッチングします。
- "(?:\\"|\\\\|[a-zA-Z0-9\.!#$%&'*+-\/=\?\^_\`\{\|\}\~ \(\)<>\[\]:;,@])+"@[a-zA-Z0-9\.-]+
- ローカル部がダブルクォートで囲まれているメールアドレスにマッチングします。
一行の正規表現でローカル部のダブルクォート囲みか名前のダブルクォート囲みか判断させるのは困難でした。なのでこの方法に落ち着くしかありませんでした。
もしうまい手があれば教えてください。いや本当に。
■ [mail] メールヘッダからメールアドレスを取り出す3
これは昨日会社でやっと気が付いたもの。お間抜けですわ(^^;
my $Cc = 'abc@hoge.jp,"def@hoge.jp",jkl@hoge.jp,ThisIsTest,mno@hoge.jp,"this is test"@hoge.jp';
my @addrs = $Cc =~/"(?:\\"|\\\\|[a-zA-Z0-9\.!#$%&'*+-\/=\?\^_\`\{\|\}~ \(\)<>\[\]:;,@])+"(?!@)|\((?:\\"|\\\\|[a-zA-Z0-9\.!#$%&'*+-\/=\?\^_\`\{\|\}~ \(\)<>\[\]:;,@])+\)|[a-zA-Z0-9\.!#$%&'*+-\/=\?\^_\`\{\|\}\~]+@[a-zA-Z0-9\.-]+|"(?:\\"|\\\\|[a-zA-Z0-9\.!#$%&'*+-\/=\?\^_\`\{\|\}\~ \(\)<>\[\]:;,@])+"@[a-zA-Z0-9\.-]+/g;
$i=1;
print "****\n$Cc\n****\n";
foreach my $ml ( @addrs )
{
$a = ($ml =~ /^["\(].+["\)]$/) ? " " : "*";
printf("%03i: %1s [%s]\n", $i, $a, $ml);
$i++;
}
実行すると
**** abc@hoge.jp,"def@hoge.jp",jkl@hoge.jp,ThisIsTest,mno@hoge.jp,"this is test"@hoge.jp **** 001: * [abc@hoge.jp] 002: ["def@hoge.jp"] 003: * [,jkl@hoge.jp] 004: * [,ThisIsTest,mno@hoge.jp] 005: * ["this is test"@hoge.jp]
何かおかしいですよね。カンマがメールアドレス構成文字として許されているように見えます。
...原因はここ。プラス記号とマイナス記号に注目。
[a-zA-Z0-9\.!#$%&'*+-\/=\?\^_\`\{\|\}\~]
a-zで英小文字a〜zを示します。じゃあ+-/は?

確かにカンマ入ってるよね(>_<)
早速この部分を修正して再度実行してみると
my $Cc = 'abc@hoge.jp,"def@hoge.jp",jkl@hoge.jp,ThisIsTest,mno@hoge.jp,"this is test"@hoge.jp';
my @addrs = $Cc =~/"(?:\\"|\\\\|[a-zA-Z0-9\.!#$%&'*+\-\/=\?\^_\`\{\|\}~ \(\)<>\[\]:;,@])+"(?!@)|\((?:\\"|\\\\|[a-zA-Z0-9\.!#$%&'*+\-\/=\?\^_\`\{\|\}~ \(\)<>\[\]:;,@])+\)|[a-zA-Z0-9\.!#$%&'*+\-\/=\?\^_\`\{\|\}\~]+@[a-zA-Z0-9\.-]+|"(?:\\"|\\\\|[a-zA-Z0-9\.!#$%&'*+\-\/=\?\^_\`\{\|\}\~ \(\)<>\[\]:;,@])+"@[a-zA-Z0-9\.-]+/g;
$i=1;
print "****\n$Cc\n****\n";
foreach my $ml ( @addrs )
{
$a = ($ml =~ /^["\(].+["\)]$/) ? " " : "*";
printf("%03i: %1s [%s]\n", $i, $a, $ml);
$i++;
}
結果はこうなりました。
**** abc@hoge.jp,"def@hoge.jp",jkl@hoge.jp,ThisIsTest,mno@hoge.jp,"this is test"@hoge.jp **** 001: * [abc@hoge.jp] 002: ["def@hoge.jp"] 003: * [jkl@hoge.jp] 004: * [mno@hoge.jp] 005: * ["this is test"@hoge.jp]
もう大丈夫でしょう。
2012-04-13 いまさらメールアドレスのパースをやってみる
■ [mail] メールヘッダからメールアドレスを取り出す
私が管理しているあるメールのシステムでは、人間がメールアドレスを管理することをやめさせてます。具体的には、
- 送信されてきたメールは一度管理システムに取り込まれ、そのメールのFromとCcを記録します。
- Subject先頭に管理番号を付与し、Cc,Fromのメールアドレスを管理システム宛のメールアドレスに変更した後Toへ再配信します。
- 受信者は何も考えずそのメールに返信します。
- 返信メールを受信した管理システムはSubjectの管理番号にしたがって保存していたFromを送信対象メールのToへ、CcをCcへ、再設定して再送信します。
Subjectの番号を改ざんしちゃったりすればおかしなことになりますが、まぁほとんどの場合ここを直すような事はないですし、番号のおかげでソートされてスレッド機能のないメールシステムの相手先でも管理し易くなったとか(管理システムで先頭の「Re:」の連続を消しこんであげてます)それなりに成果は上がっている模様です。
また再送信するまで30分ほど時間をとるようにもしてあるので、間違った内容の送信でも時間内なら取り消しが可能です。
■ 面倒なのは送信先の件数カウント
通常ならCcヘッダの送信先アドレスなんて個数なんか気にする必要はないです。
しかし、この管理システムが利用している上位のメールシステムでは、面倒な事にCcヘッダに指定できるメールアドレスの個数に制限があります。なんでも、やたらCcに送信先がある場合は事故の可能性ありとして送信をキャンセルするとか。遠回しに『CcとBccを間違えたメールだよね、それ?』と言いたいらしいです。誰がその個数を決めたか知りませんが。ものによっては複数回同じ内容のメールを送信せにゃいけないことになります。
すると、がんばってCcのメールアドレスを切り出し、送信先件数をカウントする必要が出てくるわけです。ちなみにこの管理システムではメールを分割送信せず、『メールサーバの制限でFromアドレスにしか返信していませんごめんなさい』と一言付け加えるようにしてます。転送は受信者様に再度やっていただくと。ま、大量のCcアドレス自体、あまり褒められたものではないと思いますし(MLにして流しちゃえば?とか思ってしまうのです)
さて、この送信先カウント、やってることは送られてきたメールのCcヘッダからメールアドレスと思われるものを切り出してその数を数えているのですがちょっと厄介です。
調べてみると判りますが、メールアドレスを表す正規表現ってかなりめんどくさいです。PHP使いが誤ったメールアドレス判定用の正規表現を紹介しまくったせいで切れてる方もいらっしゃったり(^^;
少し慣れてきて「正規表現で local@domain な部分の個数を数えればいいんだよね」とか単純にやってしまうとメールアドレスに一家言あるような人等がたくさん湧きます。
■ でも適用場所によっては全てを満たす必要はないの
さて対策用の言い訳を書いておきましょうか。
PHPでの例のほとんどは、入力されたメールアドレスの妥当性確認の例なので、ドットが連続していないか、とかローカル部分のトータル長が正しいかとか、使えない文字含んでないよね?とか、検証をいろいろやらにゃいけません。
しかし。メールのCcヘッダにあるメールアドレスは、送信されてきた時点でそのあたりの確認が済んでいるものとみなしてもさしつかえありません。だって、届かないメールアドレス使わないでしょ?それに携帯へ会社間で行き来するヘビーなメールを送るなんてまず考えられないし。なので携帯メールで見かけるような不正形式のアドレスは含まれないものと仮定しちゃいます。
Wikipediaのメールアドレスの項をみて、こんな正規表現を作りました。RFC読めって?ごめんなさい。
((?:[a-zA-Z0-9\.!#\$%&'*+-\/=\?\^_\`\{\|\}\~]+|"[a-zA-Z0-9\.!#\$%&'*+-\/=\?\^_\`\{\|\}\~\(\)<>\[\]:;@,\"\\]+")@[a-zA-Z0-9.-]+)
たぶんローカル部がダブルクォートで囲まれたよなメールアドレスは見ることはないと思うんですけど念のため。
■ これをPerlのスクリプトなんかで試してみると
今のところそれらしく動いてます。
my $Cc = 'ためしたいCcヘッダの内容';
my @addrs = $Cc =~ /((?:[a-zA-Z0-9\.!#\\$%&'*+-\/=\?\^_\`\{\|\}\~]+|"[a-zA-Z0-9\.!#\\$%&'*+-\/=\?\^_\`\{\|\}\~\(\)<>\[\]:;@,\"\\]+")@[a-zA-Z0-9.-]+)/g;
my $i=1;
foreach my $addr ( @addrs )
{
print "$i: $addr\n";
$i++;
}
■ そうそう
続きがあるので少々お待ちを。
2012-03-24 どれだけMなんだ?
■ [Database] 某社のLinux版ODBCドライバが不具合だらけな件
うちの会社の若い衆が、ただでさえ不具合続出で新製品発表時に『んなもんどうでもいいから不具合はよ直せボケ』と突っ込まれている某社のデータベースをデータソースにしたレポーティングシステムを作っており、やっと来週に納品!というところにこぎつけた。
このデータベース、出た当初はボロクソ言われてたものの、検索速度だけは速くて組み込み機用のカスタマイズもやれてたのである方面ではだいぶ使われている。
まぁ、ごり押しもあるんだけど。
しかし、このごろは先にも書いた通り、ろくでもない不具合を作りこんでくれてて、メンテナンスツールを起動したら最後回復不能!とかドンだけ罠を仕掛けてるんだ、という有様。現場の経験浅いSEさんが命削りながら対処している、そんな状態。
■ で、件のシステム
システムの発注をかけてきたのがそのデータベースを作ってる会社の別事業所で、公共関係の受注を取っている部署。そこの課長さん達も『それを使うと危険が危ない!』って位リスクが高まる事を理解していた。当然採用なんかしたくない。OracleやDB2の方がずっと安心。
しかし、偉い人等は違った。…そしてこのデータベースを組み込むのが絶対条件になってしまったのでした。
でも今回のシステムはそのデータベースをサポートしていないため、今時なぁ…とは思いつつもODBCを経由したアクセスを行うことになった。…そしてWindowsを使うのかと思いきや、変なところでケチったためLinuxをサーバとして使うことになり、あわててLinux版ODBCドライバを取り寄せることになったのでした。どれだけMな皆さんなのよw
■ ま、悪い予想ほど当たる
レポーティングツールはUnicodeを前提としており、データソースはSJIS。ということはSJIS to Unicodeの変換が必要になる。このODBCドライバはきちんとサポートしているとの事でした…が。
しばらく経つと、テストデータのうちいくつかを使うと、レポート表示できず異常終了する事象に遭遇。ローマ数字や丸囲み文字で発生すると聞いたら慣れた人はピンと来るかもしれない。そう、JIS X 0203の範囲での変換しかできないことが発覚したのでした。開発元、問題なく変換できるといってたのに、それを撤回してきました。
次が文字関数の振る舞い。
たとえば、Lower関数。Lower('ABCD')の結果は'abcd'になります。ところで、Lower('全然')の結果が予想できますでしょうか。…ええ、'甦甞'になります(^^;
マルチバイト文字が入っていても関係なく、1バイト毎に変換をかけていくようです。これを避けるには Lower(M'全然')とする必要がありますが、おそらくこれは過去のアプリケーションとの互換のためにこうするしかなかったのかなと思います。この製品、漢字使うときは VARCHARじゃなくてNVARCHARとか使え、って言ってたんですよ。ちなみにNVARCHARは当時で言うところの2バイト文字しか入らない型です。あ、これはODBCのせいじゃないやw
そして、金曜日があと2時間で終わるかというころに発覚したもの。
VARCHAR型で長さゼロの文字列が入ったレコードを読み出そうとするとODBCドライバがこける……なんとなくどんな処理をやっちゃったのか想像が付いちゃうけど……さて、このシステム、本当にカットオーバーに漕ぎ着ける事が出来るのかしらん?
■ あ、当然
一部嘘を混ぜ込んで書いてあるのでその旨ご承知置きください。もちろんドライバが駄目駄目なのは真実です。
2012-01-30 どうしてそこまで..
■ [雑記] ある歌詞の聞き取り
あるOPでかつ舌の悪い歌い手が歌う部分に「星の○○が君を守り続けるよ」があって、なんかほとんどが 「子供」と聞き取っているらしい。そしてそれに異を申し立てると罵倒されるみたい。おおこわ。
自分の耳がおかしいのかもしれないが、本当にここ「子供」なんだろうか。そもそもなんでそこに「子供」が来るのか。原作的に「航路」じゃないのか?
3月にCD発売らしいのでこの時に歌詞がはっきりするだろう。
そして医者に行くべきか否かのいい判断材料が出来る。
■ どうやら『子供』らしい
耳鼻科予約。ごめん、どうしても子供に聞こえないわ....
2012-01-19 ちょっとした内容なんだし、自分で直せるんじゃないのかなぁ
■ [www] NicoWatch Toolsがまた動かないぞー、に対応してみる
と言われてちょっとのぞいてみる。
毎度おなじみ「セッションの再確立中...」が一瞬出て消えてしまう状況。
未定義エラーが出ているようだけどまぁとりあえず置いておく。
■ URLが変更されてたみたいです
FirebugでHTTPセッションを見ていると、以下のURLのリクエストに対して301のレスポンスが返ってきていました。
http://www.nicovideo.jp/api/getflv?v=xxxxxx
もしかして301に対応できていないのかなーってことで遷移先の以下URLに置換えしてみると、なんかしれーっと動き出しました。
http://flapi.nicovideo.jp/api/getflv?v=xxxxxx
スクリプト中の二箇所をこのURLで置換えしただけで何とかなる模様です。また最初の未定義エラーもこれで出なくなりました。
単なる覚書以下の内容です。一度内容を全部消しました。
Before...
● 努力中の人 [朝も早よから何やってんですかw]
● jk [あれ?めずらしくおきているじゃんw いや、目がさめたら寝れなくってw]
● 努力中の人 [通知メールで携帯がブルブル鳴って起きちゃいましたよー意地でも二度寝しますw]
● jk [あ、俺がおこしちゃったのか(^ ^;; というか、努力中の人を起こすには、ここにコメントすればいいのね(うぉい とい..]
● 努力中の人 [携帯への通知を解除したので夜中でも構いませんぜw]