Land #3680, add specs for Rex::MIME
commit
6bd3675f03
|
@ -25,8 +25,9 @@ class Header
|
|||
next
|
||||
end
|
||||
|
||||
var,val = line.split(':')
|
||||
next if not val
|
||||
var, val = line.split(':', 2)
|
||||
next if val.nil?
|
||||
|
||||
self.headers << [ var.to_s.strip, val.to_s.strip ]
|
||||
prev = self.headers.length - 1
|
||||
end
|
||||
|
|
|
@ -24,9 +24,8 @@ class Message
|
|||
self.header.parse(head)
|
||||
ctype = self.header.find('Content-Type')
|
||||
|
||||
if ctype and ctype[1] and ctype[1] =~ /multipart\/mixed;\s*boundary=([^\s]+)/
|
||||
if ctype and ctype[1] and ctype[1] =~ /multipart\/mixed;\s*boundary="?([A-Za-z0-9'\(\)\+\_,\-\.\/:=\?^\s]+)"?/
|
||||
self.bound = $1
|
||||
|
||||
chunks = body.to_s.split(/--#{self.bound}(--)?\r?\n/)
|
||||
self.content = chunks.shift.to_s.gsub(/\s+$/, '')
|
||||
self.content << "\r\n" if not self.content.empty?
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# -*- coding:binary -*-
|
||||
require 'spec_helper'
|
||||
|
||||
require 'rex/mime'
|
||||
|
||||
describe Rex::MIME::Encoding do
|
||||
|
||||
subject do
|
||||
mod = Class.new
|
||||
mod.extend described_class
|
||||
mod
|
||||
end
|
||||
|
||||
describe "#force_crlf" do
|
||||
it "deletes \\r characters" do
|
||||
expect(subject.force_crlf("Test\r1\r")).to_not include("\\r")
|
||||
end
|
||||
|
||||
it "substitutes \\n characters by \\r\\n sequences" do
|
||||
expect(subject.force_crlf("Test 2\n")).to end_with("\r\n")
|
||||
end
|
||||
|
||||
it "preserves \r\n sequences" do
|
||||
expect(subject.force_crlf("\r\nTest 3\r\n")).to eq("\r\nTest 3\r\n")
|
||||
end
|
||||
|
||||
it "first deletes \\r characters, then substitutes \\n characters" do
|
||||
expect(subject.force_crlf("\rTest 4\r\n\r\r\n")).to eq("Test 4\r\n\r\n")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,151 @@
|
|||
# -*- coding:binary -*-
|
||||
require 'spec_helper'
|
||||
|
||||
require 'rex/mime'
|
||||
|
||||
describe Rex::MIME::Header do
|
||||
|
||||
let(:mime_headers_test) do
|
||||
<<-EOS
|
||||
Content-Type: text/plain;
|
||||
Content-Disposition: attachment; filename="test.txt"
|
||||
EOS
|
||||
end
|
||||
|
||||
subject do
|
||||
described_class.new
|
||||
end
|
||||
|
||||
describe "#initialize" do
|
||||
subject(:header_class) do
|
||||
described_class.allocate
|
||||
end
|
||||
|
||||
it "returns an Array" do
|
||||
expect(header_class.send(:initialize)).to be_a(Array)
|
||||
end
|
||||
|
||||
it "creates an empty headers array by default" do
|
||||
expect(header_class.send(:initialize)).to be_empty
|
||||
end
|
||||
|
||||
it "populates headers array with data from argument" do
|
||||
header_class.send(:initialize, mime_headers_test)
|
||||
expect(header_class.headers.length).to be(2)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#add" do
|
||||
it "returns the added entry" do
|
||||
expect(subject.add('var', 'val')).to eq(['var', 'val'])
|
||||
end
|
||||
|
||||
it "adds a new entry into the headers array" do
|
||||
subject.add('var', 'val')
|
||||
expect(subject.headers.length).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#set" do
|
||||
it "returns the set value" do
|
||||
expect(subject.set('var', 'val')).to eq('val')
|
||||
end
|
||||
|
||||
it "modifies the header entry if it exists" do
|
||||
subject.add('var', 'val')
|
||||
subject.set('var', 'val2')
|
||||
expect(subject.headers.length).to eq(1)
|
||||
expect(subject.headers[0]).to eq(['var', 'val2'])
|
||||
end
|
||||
|
||||
it "creates the header entry if doesn't exist" do
|
||||
subject.set('var2', 'val2')
|
||||
expect(subject.headers.length).to eq(1)
|
||||
expect(subject.headers[0]).to eq(['var2', 'val2'])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#remove" do
|
||||
it "doesn't remove any header if index doesn't exist" do
|
||||
subject.add('var', 'val')
|
||||
subject.remove(10000)
|
||||
expect(subject.headers.length).to eq(1)
|
||||
end
|
||||
|
||||
it "doesn't remove any header if var name doesn't exist" do
|
||||
subject.add('var', 'val')
|
||||
subject.remove('var2')
|
||||
expect(subject.headers.length).to eq(1)
|
||||
end
|
||||
|
||||
it "removes header entry if index exists" do
|
||||
subject.add('var', 'val')
|
||||
subject.remove(0)
|
||||
expect(subject.headers.length).to eq(0)
|
||||
end
|
||||
|
||||
it "removes any header entry with var name" do
|
||||
subject.add('var', 'val')
|
||||
subject.add('var2', 'val2')
|
||||
subject.add('var', 'val3')
|
||||
subject.remove('var')
|
||||
expect(subject.headers.length).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#find" do
|
||||
it "returns nil if header index doesn't exist" do
|
||||
expect(subject.find(1)).to be_nil
|
||||
end
|
||||
|
||||
it "returns nil if header var name doesn't exist" do
|
||||
expect(subject.find('var')).to be_nil
|
||||
end
|
||||
|
||||
it "returns the header at index if exists" do
|
||||
subject.add('var', 'val')
|
||||
expect(subject.find(0)).to eq(['var', 'val'])
|
||||
end
|
||||
|
||||
it "returns the first header with var name if exists" do
|
||||
subject.add('var', 'val')
|
||||
subject.add('var', 'val2')
|
||||
subject.add('var', 'val3')
|
||||
expect(subject.find('var')).to eq(['var', 'val'])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_s" do
|
||||
it "returns empty String if there aren't headers" do
|
||||
expect(subject.to_s).to be_empty
|
||||
end
|
||||
|
||||
it "returns string with headers separated by \\r\\n sequences" do
|
||||
subject.add('var', 'val')
|
||||
subject.add('var', 'val2')
|
||||
subject.add('var3', 'val3')
|
||||
expect(subject.to_s).to eq("var: val\r\nvar: val2\r\nvar3: val3\r\n")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#parse" do
|
||||
let(:complex_header) do
|
||||
'Date: Wed,20 Aug 2014 08:45:38 -0500'
|
||||
end
|
||||
|
||||
it "parses headers separated by lines" do
|
||||
subject.parse(mime_headers_test)
|
||||
expect(subject.headers.length).to eq(2)
|
||||
end
|
||||
|
||||
it "parses headers names and values separated by :" do
|
||||
subject.parse(mime_headers_test)
|
||||
expect(subject.headers).to eq([['Content-Type', 'text/plain;'], ['Content-Disposition', 'attachment; filename="test.txt"']])
|
||||
end
|
||||
|
||||
it "parses headers with ':' characters in the value" do
|
||||
subject.parse(complex_header)
|
||||
expect(subject.headers).to eq([['Date', 'Wed,20 Aug 2014 08:45:38 -0500']])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,412 @@
|
|||
# -*- coding:binary -*-
|
||||
require 'spec_helper'
|
||||
|
||||
require 'rex/mime'
|
||||
require 'rex/text'
|
||||
|
||||
describe Rex::MIME::Message do
|
||||
|
||||
subject do
|
||||
described_class.new
|
||||
end
|
||||
|
||||
describe "#initialize" do
|
||||
subject(:message_class) do
|
||||
described_class.allocate
|
||||
end
|
||||
|
||||
let(:raw_message) do
|
||||
message = "MIME-Version: 1.0\r\n"
|
||||
message << "Content-Type: multipart/mixed; boundary=\"_Part_12_3195573780_381739540\"\r\n"
|
||||
message << "Subject: Pull Request\r\n"
|
||||
message << "Date: Wed,20 Aug 2014 08:45:38 -0500\r\n"
|
||||
message << "Message-ID: <WRobqc7gEyQVIQwEkLS7FN3ZNhS1Xj9pU2szC24rggMg@tqUqGjjSLEvssbwm>\r\n"
|
||||
message << "From: contributor@msfdev.int\r\n"
|
||||
message << "To: msfdev@msfdev.int\r\n"
|
||||
message << "\r\n"
|
||||
message << "--_Part_12_3195573780_381739540\r\n"
|
||||
message << "Content-Disposition: inline; filename=\"content\"\r\n"
|
||||
message << "Content-Type: application/octet-stream; name=\"content\"\r\n"
|
||||
message << "Content-Transfer-Encoding: base64\r\n"
|
||||
message << "\r\n"
|
||||
message << "Q29udGVudHM=\r\n"
|
||||
message << "\r\n"
|
||||
message << "--_Part_12_3195573780_381739540--\r\n"
|
||||
|
||||
message
|
||||
end
|
||||
|
||||
it "creates a new Rex::MIME::Header" do
|
||||
message_class.send(:initialize)
|
||||
expect(message_class.header).to be_a(Rex::MIME::Header)
|
||||
end
|
||||
|
||||
it "creates an empty array of parts" do
|
||||
message_class.send(:initialize)
|
||||
expect(message_class.parts).to be_empty
|
||||
end
|
||||
|
||||
it "creates a random bound" do
|
||||
message_class.send(:initialize)
|
||||
expect(message_class.bound).to include('_Part_')
|
||||
end
|
||||
|
||||
it "allows to populate headers from argument" do
|
||||
message_class.send(:initialize, raw_message)
|
||||
expect(message_class.header.headers.length).to eq(7)
|
||||
end
|
||||
|
||||
it "allows to create a MIME-Version header from argument" do
|
||||
message_class.send(:initialize, raw_message)
|
||||
expect(message_class.header.find('MIME-Version')).to eq(['MIME-Version', '1.0'])
|
||||
end
|
||||
|
||||
it "allows to create a Content-Type header from argument" do
|
||||
message_class.send(:initialize, raw_message)
|
||||
expect(message_class.header.find('Content-Type')).to eq(['Content-Type', "multipart/mixed; boundary=\"_Part_12_3195573780_381739540\""])
|
||||
end
|
||||
|
||||
it "allows to create a Subject header from argument" do
|
||||
message_class.send(:initialize, raw_message)
|
||||
expect(message_class.header.find('Subject')).to eq(['Subject', 'Pull Request'])
|
||||
end
|
||||
|
||||
it "allows to create a Date header from argument" do
|
||||
message_class.send(:initialize, raw_message)
|
||||
expect(message_class.header.find('Date')).to eq(['Date', 'Wed,20 Aug 2014 08:45:38 -0500'])
|
||||
end
|
||||
|
||||
it "allows to create a Message-ID header from argument" do
|
||||
message_class.send(:initialize, raw_message)
|
||||
expect(message_class.header.find('Message-ID')).to eq(['Message-ID', '<WRobqc7gEyQVIQwEkLS7FN3ZNhS1Xj9pU2szC24rggMg@tqUqGjjSLEvssbwm>'])
|
||||
end
|
||||
|
||||
it "allows to create a From header from argument" do
|
||||
message_class.send(:initialize, raw_message)
|
||||
expect(message_class.header.find('From')).to eq(['From', 'contributor@msfdev.int'])
|
||||
end
|
||||
|
||||
it "allows to create a To header from argument" do
|
||||
message_class.send(:initialize, raw_message)
|
||||
expect(message_class.header.find('To')).to eq(['To', 'msfdev@msfdev.int'])
|
||||
end
|
||||
|
||||
it "allows to populate parts from argument" do
|
||||
message_class.send(:initialize, raw_message)
|
||||
expect(message_class.parts.length).to eq(1)
|
||||
end
|
||||
|
||||
it "allows to populate parts headers from argument" do
|
||||
message_class.send(:initialize, raw_message)
|
||||
part = message_class.parts[0]
|
||||
expect(part.header.headers.length).to eq(3)
|
||||
end
|
||||
|
||||
it "allows to populate parts contents from argument" do
|
||||
message_class.send(:initialize, raw_message)
|
||||
part = message_class.parts[0]
|
||||
expect(part.content).to eq("Q29udGVudHM=")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to" do
|
||||
it "returns nil if To: header doesn't exist" do
|
||||
expect(subject.to).to be_nil
|
||||
end
|
||||
|
||||
it "returns the To: header value if it exists" do
|
||||
subject.header.add('To', 'msfdev')
|
||||
expect(subject.to).to eq('msfdev')
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to=" do
|
||||
it "sets the To: header value" do
|
||||
subject.to = 'msfdev'
|
||||
expect(subject.to).to eq('msfdev')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "#from" do
|
||||
it "returns nil if From: header doesn't exist" do
|
||||
expect(subject.from).to be_nil
|
||||
end
|
||||
|
||||
it "returns the From: header value if it exists" do
|
||||
subject.header.add('From', 'msfdev')
|
||||
expect(subject.from).to eq('msfdev')
|
||||
end
|
||||
end
|
||||
|
||||
describe "#from=" do
|
||||
it "sets the From: header value" do
|
||||
subject.from = 'msfdev'
|
||||
expect(subject.from).to eq('msfdev')
|
||||
end
|
||||
end
|
||||
|
||||
describe "#subject" do
|
||||
it "returns nil if Subject: header doesn't exist" do
|
||||
expect(subject.subject).to be_nil
|
||||
end
|
||||
|
||||
it "returns the Subject: header value if it exists" do
|
||||
subject.header.add('Subject', 'msfdev')
|
||||
expect(subject.subject).to eq('msfdev')
|
||||
end
|
||||
end
|
||||
|
||||
describe "#subject=" do
|
||||
it "sets the Subject: header value" do
|
||||
subject.subject = 'msfdev'
|
||||
expect(subject.subject).to eq('msfdev')
|
||||
end
|
||||
end
|
||||
|
||||
describe "#mime_defaults" do
|
||||
it "sets the MIME-Version header" do
|
||||
subject.mime_defaults
|
||||
expect(subject.header.find('MIME-Version')).to_not be_nil
|
||||
end
|
||||
|
||||
it "sets the MIME-Version header to '1.0'" do
|
||||
subject.mime_defaults
|
||||
expect(subject.header.find('MIME-Version')).to eq(['MIME-Version', '1.0'])
|
||||
end
|
||||
|
||||
it "sets the Content-Type header" do
|
||||
subject.mime_defaults
|
||||
expect(subject.header.find('Content-Type')).to_not be_nil
|
||||
end
|
||||
|
||||
it "sets the Content-Type header to multipart/mixed" do
|
||||
subject.mime_defaults
|
||||
expect(subject.header.find('Content-Type')[1]).to include('multipart/mixed')
|
||||
end
|
||||
|
||||
it "sets the Subject header" do
|
||||
subject.mime_defaults
|
||||
expect(subject.header.find('Subject')).to_not be_nil
|
||||
end
|
||||
|
||||
it "sets the Subject header to empty string" do
|
||||
subject.mime_defaults
|
||||
expect(subject.header.find('Subject')).to eq(['Subject', ''])
|
||||
end
|
||||
|
||||
it "sets the Message-ID header" do
|
||||
subject.mime_defaults
|
||||
expect(subject.header.find('Message-ID')).to_not be_nil
|
||||
end
|
||||
|
||||
it "sets the From header" do
|
||||
subject.mime_defaults
|
||||
expect(subject.header.find('From')).to_not be_nil
|
||||
end
|
||||
|
||||
it "sets the From header to empty string" do
|
||||
subject.mime_defaults
|
||||
expect(subject.header.find('From')).to eq(['From', ''])
|
||||
end
|
||||
|
||||
it "sets the To header" do
|
||||
subject.mime_defaults
|
||||
expect(subject.header.find('To')).to_not be_nil
|
||||
end
|
||||
|
||||
it "sets the To header to empty string" do
|
||||
subject.mime_defaults
|
||||
expect(subject.header.find('To')).to eq(['To', ''])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#add_part" do
|
||||
subject(:part) do
|
||||
described_class.new.add_part(*args)
|
||||
end
|
||||
|
||||
let(:args) { [] }
|
||||
|
||||
it "returns the new part" do
|
||||
expect(part).to be_a(Rex::MIME::Part)
|
||||
end
|
||||
|
||||
it "set part's Content-Type to text/plain by default" do
|
||||
expect(part.header.find('Content-Type')[1]).to eq('text/plain')
|
||||
end
|
||||
|
||||
it "set part's Content-Transfer-Encoding to 8bit by default" do
|
||||
expect(part.header.find('Content-Transfer-Encoding')[1]).to eq('8bit')
|
||||
end
|
||||
|
||||
it "doesn't set part's Content-Disposition by default" do
|
||||
expect(part.header.find('Content-Disposition')).to be_nil
|
||||
end
|
||||
|
||||
context "with Content-Type argument" do
|
||||
let(:args) { ['', 'application/pdf'] }
|
||||
|
||||
it "creates a part Content-Type header" do
|
||||
expect(part.header.find('Content-Type')[1]).to eq('application/pdf')
|
||||
end
|
||||
end
|
||||
|
||||
context "with Content-Transfer-Encoding argument" do
|
||||
let(:args) { ['', 'application/pdf', 'binary'] }
|
||||
|
||||
it "creates a part Content-Transfer-Encoding header" do
|
||||
expect(part.header.find('Content-Transfer-Encoding')[1]).to eq('binary')
|
||||
end
|
||||
end
|
||||
|
||||
context "with Content-Disposition argument" do
|
||||
let(:args) { ['', 'application/pdf', 'binary', 'attachment; filename="fname.ext"'] }
|
||||
|
||||
it "creates a part Content-Disposition header" do
|
||||
expect(part.header.find('Content-Disposition')[1]).to eq('attachment; filename="fname.ext"')
|
||||
end
|
||||
end
|
||||
|
||||
context "with content argument" do
|
||||
let(:args) { ['msfdev'] }
|
||||
|
||||
it "creates part content" do
|
||||
expect(part.content).to eq('msfdev')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "#add_part_attachment" do
|
||||
it "requires data argument" do
|
||||
expect { subject.add_part_attachment }.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "requires name argument" do
|
||||
expect { subject.add_part_attachment('data') }.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it 'returns the new Rex::MIME::Part' do
|
||||
expect(subject.add_part_attachment('data', 'name')).to be_a(Rex::MIME::Part)
|
||||
end
|
||||
|
||||
it 'encodes the part content with base64' do
|
||||
part = subject.add_part_attachment('data', 'name')
|
||||
expect(part.content).to eq(Rex::Text.encode_base64('data', "\r\n"))
|
||||
end
|
||||
|
||||
it 'setup Content-Type as application/octet-stream' do
|
||||
part = subject.add_part_attachment('data', 'name')
|
||||
expect(part.header.find('Content-Type')[1]).to eq('application/octet-stream; name="name"')
|
||||
end
|
||||
|
||||
it 'setup Content-Transfer-Encoding as base64' do
|
||||
part = subject.add_part_attachment('data', 'name')
|
||||
expect(part.header.find('Content-Transfer-Encoding')[1]).to eq('base64')
|
||||
end
|
||||
|
||||
it 'setup Content-Disposition as attachment' do
|
||||
part = subject.add_part_attachment('data', 'name')
|
||||
expect(part.header.find('Content-Disposition')[1]).to eq('attachment; filename="name"')
|
||||
end
|
||||
end
|
||||
|
||||
describe "#add_part_inline_attachment" do
|
||||
it "requires data argument" do
|
||||
expect { subject.add_part_inline_attachment }.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "requires name argument" do
|
||||
expect { subject.add_part_inline_attachment('data') }.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it 'returns the new Rex::MIME::Part' do
|
||||
expect(subject.add_part_inline_attachment('data', 'name')).to be_a(Rex::MIME::Part)
|
||||
end
|
||||
|
||||
it 'encodes the part content with base64' do
|
||||
part = subject.add_part_inline_attachment('data', 'name')
|
||||
expect(part.content).to eq(Rex::Text.encode_base64('data', "\r\n"))
|
||||
end
|
||||
|
||||
it 'setup Content-Type as application/octet-stream' do
|
||||
part = subject.add_part_inline_attachment('data', 'name')
|
||||
expect(part.header.find('Content-Type')[1]).to eq('application/octet-stream; name="name"')
|
||||
end
|
||||
|
||||
it 'setup Content-Transfer-Encoding as base64' do
|
||||
part = subject.add_part_inline_attachment('data', 'name')
|
||||
expect(part.header.find('Content-Transfer-Encoding')[1]).to eq('base64')
|
||||
end
|
||||
|
||||
it 'setup Content-Disposition as attachment' do
|
||||
part = subject.add_part_inline_attachment('data', 'name')
|
||||
expect(part.header.find('Content-Disposition')[1]).to eq('inline; filename="name"')
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_s" do
|
||||
let(:regexp_mail) do
|
||||
regex = "MIME-Version: 1.0\r\n"
|
||||
regex << "Content-Type: multipart/mixed; boundary=\"_Part_.*\"\r\n"
|
||||
regex << "Subject: Pull Request\r\n"
|
||||
regex << "Date: .*\r\n"
|
||||
regex << "Message-ID: <.*@.*>\r\n"
|
||||
regex << "From: contributor@msfdev.int\r\n"
|
||||
regex << "To: msfdev@msfdev.int\r\n"
|
||||
regex << "\r\n"
|
||||
regex << "--_Part_.*\r\n"
|
||||
regex << "Content-Disposition: inline\r\n"
|
||||
regex << "Content-Type: text/plain\r\n"
|
||||
regex << "Content-Transfer-Encoding: base64\r\n"
|
||||
regex << "\r\n"
|
||||
regex << "Q29udGVudHM=\r\n"
|
||||
regex << "\r\n"
|
||||
regex << "--_Part_.*--\r\n"
|
||||
|
||||
Regexp.new(regex)
|
||||
end
|
||||
|
||||
let(:regexp_web) do
|
||||
regex = "\r\n"
|
||||
regex << "--_Part_.*\r\n"
|
||||
regex << "Content-Disposition: form-data; name=\"action\"\r\n"
|
||||
regex << "\r\n"
|
||||
regex << "save\r\n"
|
||||
regex << "--_Part_.*\r\n"
|
||||
regex << "Content-Disposition: form-data; name=\"file\"; filename=\"test.txt\"\r\n"
|
||||
regex << "Content-Type: application/octet-stream\r\n"
|
||||
regex << "\r\n"
|
||||
regex << "Contents\r\n"
|
||||
regex << "--_Part_.*\r\n"
|
||||
regex << "Content-Disposition: form-data; name=\"title\"\r\n"
|
||||
regex << "\r\n"
|
||||
regex << "Title\r\n"
|
||||
regex << "--_Part_.*--\r\n"
|
||||
|
||||
Regexp.new(regex)
|
||||
end
|
||||
|
||||
it "returns \\r\\n if Rex::MIME::Message is empty" do
|
||||
expect(subject.to_s).to eq("\r\n")
|
||||
end
|
||||
|
||||
it "generates valid MIME email messages" do
|
||||
subject.mime_defaults
|
||||
subject.from = "contributor@msfdev.int"
|
||||
subject.to = "msfdev@msfdev.int"
|
||||
subject.subject = "Pull Request"
|
||||
subject.add_part(Rex::Text.encode_base64("Contents", "\r\n"), "text/plain", "base64", "inline")
|
||||
expect(regexp_mail.match(subject.to_s)).to_not be_nil
|
||||
end
|
||||
|
||||
it "generates valid MIME web forms" do
|
||||
subject.add_part("save", nil, nil, "form-data; name=\"action\"")
|
||||
subject.add_part("Contents", "application/octet-stream", nil, "form-data; name=\"file\"; filename=\"test.txt\"")
|
||||
subject.add_part("Title", nil, nil, "form-data; name=\"title\"")
|
||||
expect(regexp_web.match(subject.to_s)).to_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,92 @@
|
|||
# -*- coding:binary -*-
|
||||
require 'spec_helper'
|
||||
|
||||
require 'rex/mime'
|
||||
|
||||
describe Rex::MIME::Part do
|
||||
|
||||
subject do
|
||||
described_class.new
|
||||
end
|
||||
|
||||
describe "#initialize" do
|
||||
subject(:part_class) do
|
||||
described_class.allocate
|
||||
end
|
||||
|
||||
it "initializes the Rex::MIME::Header object" do
|
||||
part_class.send(:initialize)
|
||||
expect(part_class.header).to be_a(Rex::MIME::Header)
|
||||
end
|
||||
|
||||
it "initializes the Rex::MIME::Header with an empty array of headers" do
|
||||
part_class.send(:initialize)
|
||||
expect(part_class.header.headers).to be_empty
|
||||
end
|
||||
|
||||
it "Initializes content with an empty String" do
|
||||
part_class.send(:initialize)
|
||||
expect(part_class.content).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
describe "#transfer_encoding" do
|
||||
it "returns nil if the part hasn't a Content-Transfer-Encoding header" do
|
||||
expect(subject.transfer_encoding).to be_nil
|
||||
end
|
||||
|
||||
it "returns the transfer encoding value if a Content-Transfer-Encoding header exists" do
|
||||
subject.header.add('Content-Transfer-Encoding', 'base64')
|
||||
expect(subject.transfer_encoding).to eq('base64')
|
||||
end
|
||||
end
|
||||
|
||||
describe "#binary_content?" do
|
||||
it "returns false if transfer encoding isn't defined" do
|
||||
expect(subject.binary_content?).to be_falsey
|
||||
end
|
||||
|
||||
it "returns false if transfer encoding isn't binary" do
|
||||
subject.header.add('Content-Transfer-Encoding', 'base64')
|
||||
expect(subject.binary_content?).to be_falsey
|
||||
end
|
||||
|
||||
it "returns true if transfer encoding is binary" do
|
||||
subject.header.add('Content-Transfer-Encoding', 'binary')
|
||||
expect(subject.binary_content?).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe "#content_encoded" do
|
||||
let(:content_test) do
|
||||
"\rTest1\n"
|
||||
end
|
||||
|
||||
it "returns the exact content if transfer encoding is binary" do
|
||||
subject.header.add('Content-Transfer-Encoding', 'binary')
|
||||
subject.content = content_test
|
||||
expect(subject.content_encoded).to eq(content_test)
|
||||
end
|
||||
|
||||
it "returns the content crlf encoded if transfer encoding isn't binary" do
|
||||
subject.content = content_test
|
||||
expect(subject.content_encoded).to eq("Test1\r\n")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_s" do
|
||||
it "returns headers and content separated by two \\r\\n sequences" do
|
||||
subject.header.add('var', 'val')
|
||||
subject.content = 'content'
|
||||
expect(subject.to_s).to eq("var: val\r\n\r\ncontent\r\n")
|
||||
end
|
||||
|
||||
it "returns two \\r\\n sequences if part is empty" do
|
||||
expect(subject.to_s).to eq("\r\n\r\n")
|
||||
end
|
||||
|
||||
it "ends with \\r\\n sequence" do
|
||||
expect(subject.to_s).to end_with("\r\n")
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue