Книга: Программирование на языке Ruby
18.2.6. Кодирование и декодирование вложений
18.2.6. Кодирование и декодирование вложений
Для вложения в почтовое сообщение или в сообщение, отправляемое в конференцию, файл обычно кодируется. Как правило, применяется кодировка base64
, для работы с которой служит метод pack
с аргументом m
:
bin = File.read("new.gif")
str = [bin].pack("m") # str закодирована.
orig = str.unpack("m")[0] # orig == bin
Старые почтовые клиенты работали с кодировкой uuencode/uudecode. В этом случае вложение просто добавляется в конец текста сообщения и ограничивается строками begin
и end
, причем в строке begin
указываются также разрешения на доступ к файлу (которые можно и проигнорировать) и имя файла. Аргумент u метода pack
позволяет представить строку в кодировке uuencode
. Пример:
# Предположим, что mailtext содержит текст сообщения.
filename = "new.gif"
bin = File.read(filename)
encoded = [bin].pack("u")
mailtext << "begin 644 #{filename}"
mailtext << encoded
mailtext << "end"
# ...
На принимающей стороне мы должны извлечь закодированную информацию и декодировать ее методом unpack
:
# ...
# Предположим, что 'attached' содержит закодированные данные
# (включая строки begin и end).
lines = attached.split("n")
filename = /begin ddd (.*)/.scan(lines[0]).first.first
encoded = lines[1..-2].join("n")
decoded = encoded.unpack("u") # Все готово к записи в файл.
Современные почтовые клиенты работают с почтой в формате MIME; даже текстовая часть сообщения обернута в конверт (хотя клиент удаляет все заголовки, прежде чем показать сообщение пользователю).
Подробное рассмотрение формата MIME заняло бы слишком много места, да и не относится к рассматриваемой теме. Но в следующем простом примере показано, как можно закодировать и отправить сообщение, содержащее текстовую часть и двоичное вложение. Двоичные куски обычно представлены в кодировке base64
:
require 'net/smtp'
def text_plus_attachment(subject, body, filename)
marker = "MIME_boundary"
middle = "--#{marker}n"
ending = "--#{middle}--n"
content = "Content-Type: Multipart/Related; " +
"boundary=#{marker}; " +
"typw=text/plain"
head1 = <<-EOF
MIME-Version: 1.0
#{content}
Subject: #{subject}
EOF
binary = File.read(filename)
encoded = [binary].pack("m") # base64
head2 = <<EOF
Content-Description: "#{filename}"
Content-Type: image/gif; name="#{filename}"
Content-Transfer-Encoding: Base64
Content-Disposition: attachment; filename="#{filename}"
EOF
# Возвращаем...
head1 + middle + body + middle + head2 + encoded + ending
end
domain = "someserver.com"
smtp = "smtp.#{domain}"
user, pass = "elgar","enigma"
body = <<EOF
Это мое сообщение. Особо
говорить не о чем. Я вложил
небольшой GIF-файл.
-- Боб
EOF
mailtext = text_plus_attachment("Привет...",body,"new.gif")
Net::SMTP.start(smtp, 25, domain, user, pass, :plain) do |mailer|
mailer.sendmail(mailtext, '[email protected]',
['[email protected]'])
end
- 18.2.1. Получение истинно случайных чисел из Web
- 18.2.2. Запрос к официальному серверу времени
- 18.2.3. Взаимодействие с РОР-сервером
- 18.2.4. Отправка почты по протоколу SMTP
- 18.2.5. Взаимодействие с IMAP-сервером
- 18.2.6. Кодирование и декодирование вложений
- 18.2.7. Пример: шлюз между почтой и конференциями
- 18.2.8. Получение Web-страницы с известным URL
- 18.2.9. Библиотека Open-URI
- Пример 12-30. Декодирование файлов
- 1.4. Кодирование информации
- 1.4.1. Кодирование во время выполнения
- Глава 3 Кодирование текстовой и графической информации
- 6.16.12 Кодирование Record Route
- Кодирование Хаффмана
- 3.2. Кодирование графической информации
- 13.9.3 Кодирование запросов выбора вариантов
- PGP: Кодирование и шифрование информации с открытым ключом.
- Код, кодирование и декодирование
- Кодирование Шеннона-Фано
- Кодирование бинарных признаков