multipart/mixed コンテンツ タイプと境界が Amavis によって拒否されました

multipart/mixed コンテンツ タイプと境界が Amavis によって拒否されました

SMTP メールを送信する Ruby スクリプトを作成しています。メールは、ヘッダー、本文、添付ファイルの 3 つの部分に分かれています。残念ながら、カプセル化境界を適切に記述するという Amavis の要件を満たすのに苦労しています。

Amavis によって追加されたこのヘッダーは、問題に気づきました:

X-Amavis-Alert: BAD HEADER SECTION, MIME error: error: multipart boundary is missing, or contains CR or LF

私は読んだRFC 1341のセクション7_2マルチパート構文を定義します。

カプセル化境界は行の先頭、つまり CRLF の後に出現する必要があり、最初の CRLF は前の部分の一部ではなくカプセル化境界の一部と見なされることに注意してください。境界の直後には、別の CRLF と次の部分のヘッダー フィールド、または 2 つの CRLF が続く必要があります。この場合、次の部分にヘッダー フィールドはありません (したがって、Content-Type は text/plain であると想定されます)。

  • カプセル化境界はCRLFに続く必要があります
  • カプセル化境界の直後には別のCRLFと次の部分のヘッダーフィールドが続く必要がある。

私のスクリプトはこれら 2 つのルールを尊重していると思いますが、一部のメール クライアントは添付ファイルを認識しません。以下は生のメールです (各カプセル化境界の前後に CRLF があることに注意してください)。

From: [email protected]\nTo: [email protected]\nSubject: =?UTF-8?B?RMOpY2xhcmF0aW9uIHNpbXBsaWZpw6llIGRlIHZpb2xlbmNl?=\nDate: 2020-12-17 15:59:14 +0100\nMIME-Version: 1.0\nContent-Type: multipart/mixed; boundary=_3c7d2a21904930ec7ff47d0cb268c6605a8d06c02dc50e0c5498926371fae06a68d7\r\n--_3c7d2a21904930ec7ff47d0cb268c6605a8d06c02dc50e0c5498926371fae06a68d7\r\nContent-Type: text/html;charset=\"utf-8\"\nContent-Transfer-Encoding:utf8\r\n\nEMAIL BODY CONTENT HERE\r\n--_3c7d2a21904930ec7ff47d0cb268c6605a8d06c02dc50e0c5498926371fae06a68d7\r\nContent-Type: multipart/mixed; name = \"declaration_171220_155914166.pdf\"\nContent-Transfer-Encoding:base64\nContent-Disposition: attachment; filename = declaration_171220_155914166.pdf\n\nJVBERi0xLjMKJf///...(<- Base64 encoded attachment)...\r\n--_3c7d2a21904930ec7ff47d0cb268c6605a8d06c02dc50e0c5498926371fae06a68d7--

何が間違っているのでしょうか? 非寛容なクライアントが添付ファイルを表示できないようにする原因は何だと思いますか?


もし誰かの役に立つなら、ここに私のRubyスクリプトがあります
require 'base64'

module Reports
  module SMTP
    BOUNDARY = '_3c7d2a21904930ec7ff47d0cb268c6605a8d06c02dc50e0c5498926371fae06a68d7'

    def self.send_report(file_path)
      file_content    = File.binread(file_path)
      encoded_content = [file_content].pack('m')   # Base64
      email_content   = headers + attachment(file_path, encoded_content) + body

      begin
        Net::SMTP.start('groupware.sdis21.org', 25, 'HELO FQDN', 'username', 'password', :plain) do |smtp|
          smtp.send_message(email_content, '[email protected]', ['[email protected]'])
        end
      rescue => e
        puts e.inspect, e.backtrace
      end
    end

    def self.headers
      <<~EOF
        From: [email protected]
        To: [email protected]
        Subject: =?UTF-8?B?#{Base64.strict_encode64('Déclaration simplifiée de violence')}?=
        Date: #{Time.now.to_s}
        MIME-Version: 1.0
        Content-Type: multipart/mixed; boundary=#{BOUNDARY}\r
        --#{BOUNDARY}\r
      EOF
    end

    def self.body
      <<~EOF
        Content-Type: text/html;charset="utf-8"
        Content-Transfer-Encoding:utf8

        EMAIL BODY CONTENT HERE\r
        --#{BOUNDARY}\r
      EOF
    end

    def self.attachment(file_path, encoded_content)
      file_path = file_path.split('/').last
      <<~EOF
        Content-Type: multipart/mixed; name = "#{file_path}"
        Content-Transfer-Encoding:base64
        Content-Disposition: attachment; filename = #{file_path}

        #{encoded_content}\r
        --#{BOUNDARY}--\r
      EOF
    end
  end
end

答え1

問題は、使用している Web クライアントがContent-Type添付ファイルの正しいヘッダーを期待していることです。

Content-Type: application/pdf; name="filename.pdf"

これを解明するために、私は postfix サーバー ( /var/spool/imap/our_domain/...) から受信したいくつかの電子メールを調べ、それをスクリプトで生成している生の電子メールと比較しました。最も顕著な違いはこのヘッダーでした。

関連情報