Rex::MIME::Message can now parse as well as write
git-svn-id: file:///home/svn/framework3/trunk@9257 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
d33dc27e26
commit
14363ca2e8
|
@ -5,12 +5,12 @@ class Header
|
|||
require 'rex/text'
|
||||
|
||||
attr_accessor :headers
|
||||
|
||||
|
||||
def initialize(data='')
|
||||
self.headers = []
|
||||
parse(data)
|
||||
end
|
||||
|
||||
|
||||
def parse(data)
|
||||
prev = nil
|
||||
data.gsub("\r", '').split("\n").each do |line|
|
||||
|
@ -23,17 +23,17 @@ class Header
|
|||
self.headers[prev][1] << line.strip
|
||||
next
|
||||
end
|
||||
|
||||
|
||||
var,val = line.split(':')
|
||||
self.headers << [ var.strip, val.strip ]
|
||||
self.headers << [ var.to_s.strip, val.to_s.strip ]
|
||||
prev = self.headers.length - 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def to_s
|
||||
self.headers.map{ |pair| "#{pair[0]}: #{pair[1]}\r\n" }.join
|
||||
end
|
||||
|
||||
|
||||
def find(idx)
|
||||
if (idx.class == ::Fixnum)
|
||||
return self.headers[idx]
|
||||
|
@ -46,7 +46,7 @@ class Header
|
|||
end
|
||||
nil
|
||||
end
|
||||
|
||||
|
||||
def set(var, val)
|
||||
hdr = self.find(var) || self.add(var, '')
|
||||
hdr[1] = val
|
||||
|
@ -56,7 +56,7 @@ class Header
|
|||
self.headers << [var, val]
|
||||
self.headers[-1]
|
||||
end
|
||||
|
||||
|
||||
def remove(idx)
|
||||
if (idx.class == ::Fixnum)
|
||||
self.headers.delete_at(idx)
|
||||
|
@ -67,9 +67,10 @@ class Header
|
|||
self.headers.delete_at(i)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -4,47 +4,71 @@ class Message
|
|||
|
||||
require 'rex/mime/header'
|
||||
require 'rex/mime/part'
|
||||
require 'rex/text'
|
||||
require 'rex/text'
|
||||
|
||||
attr_accessor :header, :parts, :bound, :content
|
||||
|
||||
def initialize
|
||||
def initialize(data=nil)
|
||||
self.header = Rex::MIME::Header.new
|
||||
self.parts = []
|
||||
self.bound = "_Part_#{rand(1024)}_#{rand(0xffffffff)}_#{rand(0xffffffff)}"
|
||||
self.content = ''
|
||||
if data
|
||||
head,body = data.split(/\r?\n\r?\n/, 2)
|
||||
|
||||
self.header.parse(head)
|
||||
ctype = self.header.find('Content-Type')
|
||||
|
||||
if ctype and ctype[1] and ctype[1] =~ /multipart\/mixed;\s*boundary=([^\s]+)/
|
||||
self.bound = $1
|
||||
|
||||
chunks = body.to_s.split(/--#{self.bound}(--)?\r?\n/)
|
||||
self.content = chunks.shift.to_s.gsub(/\s+$/, '')
|
||||
|
||||
chunks.each do |chunk|
|
||||
break if chunk == "--"
|
||||
head,body = chunk.split(/\r?\n\r?\n/, 2)
|
||||
part = Rex::MIME::Part.new
|
||||
part.header.parse(head)
|
||||
part.content = body.gsub(/\s+$/, '')
|
||||
self.parts << part
|
||||
end
|
||||
else
|
||||
self.content = body.to_s.gsub(/\s+$/, '')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def to
|
||||
(self.header.find('To') || [nil, nil])[1]
|
||||
end
|
||||
|
||||
|
||||
def to=(val)
|
||||
self.header.set("To", val)
|
||||
end
|
||||
|
||||
|
||||
def from=(val)
|
||||
self.header.set("From", val)
|
||||
self.header.set("From", val)
|
||||
end
|
||||
|
||||
|
||||
def from
|
||||
(self.header.find('From') || [nil, nil])[1]
|
||||
end
|
||||
|
||||
|
||||
def subject=(val)
|
||||
self.header.set("Subject", val)
|
||||
self.header.set("Subject", val)
|
||||
end
|
||||
|
||||
|
||||
def subject
|
||||
(self.header.find('Subject') || [nil, nil])[1]
|
||||
end
|
||||
|
||||
|
||||
def mime_defaults
|
||||
self.header.set("MIME-Version", "1.0")
|
||||
self.header.set("Content-Type", "multipart/mixed; boundary=\"#{self.bound}\"")
|
||||
self.header.set("Subject", '') # placeholder
|
||||
self.header.set("Date", Time.now.strftime("%a,%e %b %Y %H:%M:%S %z"))
|
||||
self.header.set("Message-ID",
|
||||
self.header.set("Message-ID",
|
||||
"<"+
|
||||
Rex::Text.rand_text_alphanumeric(rand(20)+40)+
|
||||
"@"+
|
||||
|
@ -55,24 +79,24 @@ class Message
|
|||
self.header.set("To", '') # placeholder
|
||||
end
|
||||
|
||||
|
||||
|
||||
def add_part(data='', content_type='text/plain', transfer_encoding="8bit", content_disposition=nil)
|
||||
part = Rex::MIME::Part.new
|
||||
part.header.set("Content-Type", content_type)
|
||||
|
||||
|
||||
if (transfer_encoding)
|
||||
part.header.set("Content-Transfer-Encoding", transfer_encoding)
|
||||
end
|
||||
|
||||
|
||||
if (content_disposition)
|
||||
part.header.set("Content-Disposition", content_disposition)
|
||||
end
|
||||
|
||||
|
||||
part.content = data
|
||||
self.parts << part
|
||||
part
|
||||
end
|
||||
|
||||
|
||||
def add_part_attachment(data, name)
|
||||
self.add_part(
|
||||
Rex::Text.encode_base64(data, "\r\n"),
|
||||
|
@ -81,7 +105,7 @@ class Message
|
|||
"attachment; filename=\"#{name}\""
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
|
||||
def add_part_inline_attachment(data, name)
|
||||
self.add_part(
|
||||
|
@ -91,22 +115,25 @@ class Message
|
|||
"inline; filename=\"#{name}\""
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
def to_s
|
||||
msg = self.header.to_s + "\r\n"
|
||||
|
||||
|
||||
msg << self.content + "\r\n"
|
||||
|
||||
|
||||
self.parts.each do |part|
|
||||
msg << "--" + self.bound + "\r\n"
|
||||
msg << part.to_s
|
||||
end
|
||||
|
||||
msg << "--" + self.bound + "--\r\n"
|
||||
|
||||
if self.parts.length > 0
|
||||
msg << "--" + self.bound + "--\r\n"
|
||||
end
|
||||
|
||||
msg
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue