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(' ')

filename = /begin ddd (.*)/.scan(lines[0]).first.first

encoded = lines[1..-2].join(' ')

decoded = encoded.unpack('u') # Все готово к записи в файл.

Современные почтовые клиенты работают с почтой в формате MIME; даже текстовая часть сообщения обернута в конверт (хотя клиент удаляет все заголовки, прежде чем показать сообщение пользователю).

Подробное рассмотрение формата MIME заняло бы слишком много места, да и не относится к рассматриваемой теме. Но в следующем простом примере показано, как можно закодировать и отправить сообщение, содержащее текстовую часть и двоичное вложение. Двоичные куски обычно представлены в кодировке base64:

require 'net/smtp'

def text_plus_attachment(subject, body, filename)

 marker = 'MIME_boundary'

 middle = '--#{marker} '

 ending = '--#{middle}-- '

 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.7. Пример: шлюз между почтой и конференциями

В онлайновых сообществах общение происходит разными способами. К наиболее распространенным относятся списки рассылки и конференции (новостные группы).

Но не каждый хочет подписываться на список рассылки и ежедневно получать десятки сообщений; кто-то предпочитает время от времени заходить в конференцию и просматривать новые сообщения. С другой стороны, есть люди, которым система Usenet кажется слишком медлительной — они хотели бы видеть сообщение, пока еще электроны не успели остыть.

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату