TMail パーサのデバッグ方法
あれ!? TMail のメール解析がおかしいぞ!? というときは、パーサまで手を入れないといけないかも知れない。そのデバッグの仕方を書いておく。
パーサのデバッグフラグをONにする
TMailを使うスクリプトの中で、
require "tmail" TMail::Parser.const_set(:MAILP_DEBUG, true) # <== ココ mail = TMail::Mail.parse(IO.read(mailfile))
こうするとデバッグ情報が出力される。また通常は、ヘッダの中身を解析していてエラーが起こった場合は、通常何も出力されずに無視されて、エンコード時にそのヘッダが捨てられてしまう。デバッグをONにすると、中断こそしないがそのエラーも出力される。
まずこれで実行して、構文解析エラーが原因なのかどうかが調べてみるとよい。エラーメッセージだけで、対応方法が分かる場合がある。
パーサの中の、どの解析ルールが原因なのかを調べないといけない場合は、次のステップに進もう。
raccのインストール
gem install racc
デバッグ情報付きパーサの生成
TMailのパーサは、 lib/tmail/parser.rb である。これは、ルール定義ファイル parser.y から、racc によって自動生成される。
cd tmail-1.2.3.1 racc -t -o lib/tmail/parser.rb lib/tmail/parser.y
オプション"-t"はデバッグ情報付きのパーサが生成される。
ふたたび実行
デバッグ情報入りのパーサだと、豊富な情報がたくさん出てくる。
(例)解析部分:
Content-Type: multipart/mixed;
(例)出力:
read :CTYPE(CTYPE) :CTYPE shift CTYPE [ (CTYPE :CTYPE) ] goto 12 [ 0 12 ] read :TOKEN(TOKEN) "multipart" shift TOKEN [ (CTYPE :CTYPE) (TOKEN "multipart") ] goto 62 [ 0 12 62 ] read "/"("/") "/" shift "/" [ (CTYPE :CTYPE) (TOKEN "multipart") ("/" "/") ] goto 99 [ 0 12 62 99 ] read :TOKEN(TOKEN) "mixed" shift TOKEN [ (CTYPE :CTYPE) (TOKEN "multipart") ("/" "/") (TOKEN "mixed") ] goto 126 [ 0 12 62 99 126 ] reduce <none> --> params [ (CTYPE :CTYPE) (TOKEN "multipart") ("/" "/") (TOKEN "mixed") (params {}) ] goto 136 [ 0 12 62 99 126 136 ] read ";"(";") ";" shift ";" [ (CTYPE :CTYPE) (TOKEN "multipart") ("/" "/") (TOKEN "mixed") (params {}) (";" ";") ]