その他
    ホーム技術発信DoRubyRailsのActionMailer(Tmail)でドットの連続などのRFC違反している携帯メールアドレスに対応する

    RailsのActionMailer(Tmail)でドットの連続などのRFC違反している携帯メールアドレスに対応する

    この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

    こんにちは、KBMJの中平@railsエンジニアです。
    今回は、docomoやauなどのメールドレスでドットの連続とか@の前にドットをつけたRFC違反メールアドレスだと、ruby on rails のActionMailer(Tmail)でメール送受信が失敗していたので、その対策方法を書きます。RFC違反メールアドレスだとActionMailer(Tmail)でどのような問題が起こるのか

    ruby…rails.@kbmj.com などのメールアドレスだとActionMailer(Tmail)を使ってメールの送受信をした時に、メールアドレスの
    from、toがnilになってしまいメールアドレスが送受信できません。
    (スパムが心配なのでドメインは弊社のものにしています。)

    確認してみる

    ruby script/console
    >> TMail::Version
    => “0.10.7”
    >> mail = TMail::Mail.new
    => #<TMail::Mail port=#<TMail::StringPort:id=0x27c5f68> bodyport=nil>
    >> mail.from = ‘ruby…rails.@kbmj.com’
    => nil

    とnilになってしまい、メールアドレスがきちんと取得できません。

    ■対策方法
    こちらのサイトを参考にさせていただきました。

    最新のTMailだと対策されているみたいですが、リリース済みのプロジェクトでしたので、parse.yからparse.rbを作り直します。

    1.parse.yファイルを取得します。

    Tmailを単体で取得し、その中にparse.yがありますのでそれを使います。
    http://rubyforge.org/frs/?group_id=4512
    ここからダウンロード、使用しているTMailと同じバージョンのものを使います。

    リビジョン 3329で対応しているみたいですので、
    変更内容
    svn log -r 3329 http://i.loveruby.net/svn/public/tmail/trunk/

    svn diff -r 3328:3329 http://i.loveruby.net/svn/public/tmail/trunk/lib/tmail/parser.y
    で変更点を同じようにダウンロードしたpaser.yに編集します。

    2.parse.yからparse.rbを作成しなおします。

    raccを使いparse.yからparse.rbを作成いたします。
    raccがない場合は取得して使ってください。

    windows環境だとサンプルのように
    racc -ocalc.rb calc-ja.y
    としても、実行されないので
    c:\ruby\bin\racc  -ocalc.rb calc-ja.yという感じで実行する必要があります。

    praser.rbを作成する。

    c:\ruby\bin\racc  parser.y -E -o tmail_parser.rb

    参考にさせていただいたサイトですと、直接既存のparser.rbを置き換えていますが、
    私は直接置き換えずtmail_parser.rbとファイル名をつけ、
    project\libの中にtmail_parser.rbを入れておき
    起動時に
    TMail.instance_eval{remove_const ‘Parser’}
    require ‘tmail_parser’
    として、parser.rbを新しいtmail_parserを使うようにしております。

    これで、RFC違反メールアドレス対策が出来ました。
    確認してみる。

    ruby script/console
    >> mail = TMail::Mail.new
    => #<TMail::Mail port=#<TMail::StringPort:id=0x27c5f68> bodyport=nil>
    >> mail.from = ‘ruby…rails.@kbmj.com’
    => “ruby…rails.@kbmj.com”


    問題ないことが確認できました。

    第2の問題
    実際にメール送受信を試したところ、送信は出来ているのですが受信に失敗していました。
    ログを調べてみると・・・・
    postfixがRFC違反メールアドレスだと、

    ruby…rails.@kbmj.comを”ruby…rails.”@kbmj.com という感じで変更していました。


    そのため、再びparseが上手くいかずメールアドレスがnilになっていました。
    ログを見るとヘッダー情報にはメールアドレスがそのままきていましたので、

    require ‘action_mailer’

    module TMail
      class Mail
        # 指定された名前の最初のヘッダを取得する
        def first_header(key)
          if port.to_s =~ /^#{key}:\s*(.*)/i
            $1
          else
            nil
          end
        end
      end
     end

    このようなmoduleを作成し、
    メールの受信処理に

    def receive(email)
    email.first_header(‘return-path’).sub(/^</, ”).sub(/>$/, ”).sub(/^\”/,”).sub(/\”@/,’@’)
    end

    とすることで、無事メールアドレスが取得できました。

    古いバージョンActionMailer(Tmail)でRFC違反メールアドレスの対応する場合は参考にしていただければと思います。