
저는 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와 다음 부분에 대한 헤더 필드 또는 두 개의 CRLF가 와야 합니다. 이 경우 다음 부분에 대한 헤더 필드가 없습니다(따라서 Content-Type text/로 간주됩니다). 솔직한).
- 캡슐화 경계는 CRLF를 따라야 합니다.
- 캡슐화 경계 바로 뒤에는 또 다른 CRLF + 다음 부분의 헤더 필드가 와야 합니다.
내 스크립트는 이 두 가지 규칙을 준수한다고 생각하지만 일부 메일 클라이언트는 첨부 파일을 인식하지 못합니다. 원시 이메일은 다음과 같습니다(각 캡슐화 경계 앞에 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
문제는 우리가 사용하고 있는 웹 클라이언트가 Content-Type
첨부 파일에 대한 올바른 헤더를 기대하고 있다는 것입니다.
Content-Type: application/pdf; name="filename.pdf"
이를 파악하기 위해 postfix 서버( )에서 받은 일부 이메일을 살펴보고 /var/spool/imap/our_domain/...
이를 스크립트로 생성 중인 원시 이메일과 비교했습니다. 가장 눈에 띄는 차이점은 이 헤더였습니다.