Опечатки в именах, вызывающие синтаксические ошибки SMTP в поле - PullRequest
2 голосов
/ 01 ноября 2019

У нас есть приложение rails, которое может отправлять электронные письма людям. Мы используем почтовый гем (v2.7.1)

Некоторые пользователи вводят свои имена, а не адреса электронной почты, так, что это вызывает синтаксические ошибки при попытке отправить электронное письмо.

Вот несколько примеров, один из которых работает нормально, и два разных ошибочных примера - имена были изменены, но опечатки остались прежними

Работает:

to = "\"Joe Bloggs\" <joe.bloggs@example.com>"
m = Mail.new
m.to = to
#<Mail::Message:92412660, Multipart: false, Headers: <To: "Joe Bloggs" <joe.bloggs@example.com>>>

Ошибка1:

to = "\"Joe B\"log-gs\" <joe.bloggs@example.com>"
m = Mail.new
m.to = to
#<Mail::Message:92412660, Multipart: false, Headers: <To: "Joe B"log-gs" <joe.bloggs@example.com>>>

Falure 2:

to = "\"JOE BLOGGS\\\" <joe.bloggs@example.com>"
m = Mail.new
m.to = to
#<Mail::Message:92412660, Multipart: false, Headers: <To: "JOE BLOGGS\" <joe.bloggs@example.com>>>

Когда мы пытаемся отправить ошибки, мы получаем ошибку:

Net::SMTPSyntaxError: 501 Syntax error in parameters
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:969 in check_response
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:937 in getok
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:837 in mailfrom
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:658 in send_message
/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp_connection.rb:54 in deliver!
/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:101 in block in deliver!
/app/vendor/ruby-2.4.4/lib/ruby/2.4.0/net/smtp.rb:519 in start
/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:109 in start_smtp_session
/gems/mail-2.7.1/lib/mail/network/delivery_methods/smtp.rb:100 in deliver!
/gems/mail-2.7.1/lib/mail/message.rb:276 in deliver!

Я пытался найтичто такое разрешенные символы в to, но я не смог его найти.

Интересно, можно ли что-нибудь сделать, чтобы избежать символов, я попробовал CGI.escape, но это не помогло. кажется, эффект, который я хотел

"%22JOE+BLOGGS%5C%22+%3Cjoe.bloggs%40example.com%3E"
#<Mail::Message:92412660, Multipart: false, Headers: <To: %22JOE+BLOGGS%5C%22+%3Cjoe.bloggs%40example.com%3E>>

1 Ответ

1 голос
/ 01 ноября 2019

Адреса электронной почты для стандартов "to" определены IETF в RFC 822 , который был создан в 1982 году (!!) и является немного сложным для чтения. Вот некоторые сжатые детали, поясняющие формат адреса электронной почты чуть более четко.

Я бы предложил создать свой собственный вспомогательный метод "средство форматирования адреса электронной почты", который удаляет входные данные от клиентов любогонелегальные персонажи. Существует множество мнений по поводу лучшего регулярного выражения для форматирования электронной почты адресов самих (без имени) в Ruby - отличное место для проверки идей - Rubular.com .

Для вашего удобства место для start может выглядеть примерно так:

def format_email(str)
  email = str.match(/<(.*?)>/)[0]
  name = str.remove(email).gsub(/[^a-z0-9\s]/i, '').strip

  "#{name} #{email}"
end

Этот метод сначала вытаскивает email из строки, захватывая что-либо между двумя угловыми скобками<..>. Затем он находит name, удаляя совпадающее электронное письмо из строки, затем удаляя любые не алфавитно-цифровые символы и, наконец, удаляя любые пробелы, оставшиеся от концов.

Используя предоставленные вами примеры, этот метод даст:

format_email "\"Joe Bloggs\" <joe.bloggs@example.com>"
=> "Joe Bloggs <joe.bloggs@example.com>"

format_email "\"Joe B\"log-gs\" <joe.bloggs@example.com>"
=> "Joe Bloggs <joe.bloggs@example.com>"

format_email "\"JOE BLOGGS\\\" <joe.bloggs@example.com>"
=> "JOE BLOGGS <joe.bloggs@example.com>"

Возможно, вы захотите сделать этот маленький метод более многословным, фактически проверив формат самого адреса электронной почты, убедившись, что мы не удаляем ничего важного из имени и т. Д. Это всего лишьпростой и быстрый пример того, как творческие соки форматируются по электронной почте: -)

...