Sending an HTML email with an attachment - ruby

I have a question about net/smtp
For html emails you have to set this in the header of the email content-type: text/html . However, if you want to send an attachment you have to change it to content-type: multipart/mixed. Which would make the html email...not html anymore.
So the question is.. how do I accomplish both? HTML and attachment?
Thank you

Each attachment has its own MIME type
Each part of a multipart email has its own MIME type. So, while the email's content-type is "multipart/mixed", each attachment has its own MIME type (text, HTML, etc).
Here is an example multipart email from MIME and HTML in Email by Doug Steinwand:
To: whoever#someplace.com
Subject: MIME test
Content-type: multipart/mixed; boundary="theBoundaryString"
--theBoundaryString
Plain text message goes in this part. Notice that it
has a blank line before it starts, meaning that this
part has no additional headers.
--theBoundaryString
Content-Type: text/html
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Content-Base: "http://somewebsite.com/"
<body><font size=4>This</font> is a
<i>test</i>.
--theBoundaryString--
Here you can see that the text attachment has no explicit content type. When an attachment has no explicit content type, it is US ASCII TEXT. The HTML attachment has a content type of "text/html". There could be other attachments, each with their own MIME type.
Consider using the "mail" Gem
The mail gem makes sending and parsing multi-part emails very easy. It is stable, well maintained, and widely used.
This example from its README shows how to send a multi-part mail with a text part and an HTML part:
mail = Mail.deliver do
to 'nicolas#test.lindsaar.net.au'
from 'Mikel Lindsaar <mikel#test.lindsaar.net.au>'
subject 'First multipart email sent with Mail'
text_part do
body 'This is plain text'
end
html_part do
content_type 'text/html; charset=UTF-8'
body '<h1>This is HTML</h1>'
end
end

Related

Can Content-Disposition filename be used for text fields in multipart forms with Spring Webclient?

Working with the Service-Now API (for example) requires the request to provide the following:
POST /api/now/attachment/upload HTTP/1.1
Host: somehost.testenv.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MadHyZrFTrZu0gW
cache-control: no-cache
Content-Disposition: form-data; name="table_name"
some_table
Content-Disposition: form-data; name="table_sys_id"
82c9aca7kljasdfkljhasdfec8dfdb61d961920
Content-Disposition: form-data; name="uploadFile"; filename="undefined"
Content-Type: file
------WebKitFormBoundary7MA4YWxkTrZu0gW—
The above is generated from using Postman and providing form-data key value pairs.
However, based off the abstract of the RFC that defines Content-Disposition: https://www.rfc-editor.org/rfc/rfc2183.
Two values for this
header field are described in this memo; one for the ordinary linear
presentation of the body part, and another to facilitate the use of
mail to transfer files.
The Content-Disposition class used in Spring Webflux (https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/ContentDisposition.html) contains only an internal field for "filename" that is a string.
Is the ContentDisposition class in org.springframework.http missing a component as per RFC-2183 regarding a standard value (ordinary linear presentation of the body part)?
The HTTP request that is generated by the spring code automagically is as follows:
POST /api/now/attachment/upload HTTP/1.1
user-agent: ReactorNetty/0.7.9.RELEASE
transfer-encoding: chunked
host: somehost.testenv.com
accept: */*
accept-encoding: gzip
Content-Type: multipart/form-data;boundary=o-0JsSvUdGo98NDHJSWTwjvgzlRSXsmJ98-pWQ;charset=UTF-8
This is the source code that generates the above HTTP request:
MultipartBodyBuilder mbuilder = new MultipartBodyBuilder();
mbuilder.part("table_name", snConfig.getChangeRecordTableName());
mbuilder.part("table_sys_id", result.get(0).getSysId());
mbuilder.part("uploadFile", someFile);
return client.post()
.uri(snConfig.getEndpointAttachmentUpload())
.contentType(MediaType.MULTIPART_FORM_DATA)
.syncBody(mbuilder.build())
.retrieve()
.bodyToMono(AttachmentUploadResult.class);
It looks like the code is storing all of the MultipartBodyBuilder components into a single multipart/form-data, which is not the same format as the working HTTP Request.
However, even by manually providing the Content-Disposition headers, one can only create a name/value pair where the value is the "filename".
Is Content-Disposition missing functionality? Is this possible with WebClient?
Looks like this isn't supported within WebClient after digging on this for a long while.

Mail RFC embedded image using cid for text/plain

While I remember email messages could contain embedded images in HTML and plain text I noted today Outlook 2013 and Windows 10 Mail app does not display it.
Is this something the RFC standard has removed the "[cid:]" definition?
Below is the formatted mail:
(save as *.eml to display its content)
MIME-Version: 1.0
Date: Tue, 6 Feb 2018 10:12:53 +0100
From: Test User 2 <test.user2#lab.local>
Subject: TEst in plain text
Thread-Topic: TEst in plain text
To: Test User 1 <test.user1#lab.local>
Content-Type: multipart/mixed;
boundary="_60A9E784-DBBE-4378-9A84-01D36C2226AF_"
--_60A9E784-DBBE-4378-9A84-01D36C2226AF_
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"
test
[cid:BBCLOGO#23AD2D600E]
--_60A9E784-DBBE-4378-9A84-01D36C2226AF_
Content-Type: image/jpg; name="23AD2D600EF4C69FF4D5479A8BB7FE73.jpg"
Content-ID: <BBCLOGO#23AD2D600E>
Content-Transfer-Encoding: base64
Content-Disposition: inline;
filename="23AD2D600EF4C69FF4D5479A8BB7FE73.jpg"
/9j/4AAQSkZJRgABAgAAZABkAAD/2wBDAAIBAQEBAQIBAQIDAgECAwMCAgICAwMDAwMDAwMFAwQE
BAQDBQUFBgYGBQUHBwgIBwcKCgoKCgwMDAwMDAwMDAz/2wBDAQICAgQDBAcFBQcKCAcICgwMDAwM
DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAAyADIDAREA
AhEBAxEB/8QAHAAAAgIDAQEAAAAAAAAAAAAAAAcFCAIEBgMJ/8QAOBAAAQIFAQYBBw0BAAAAAAAA
AQIDAAQFBhETBwgSITFRQTQ1QmFicYEUFiIyMzZDY3KEkZSh8P/EABoBAAIDAQEAAAAAAAAAAAAA
AAAFAgMEBgH/xAAnEQACAgECBQMFAAAAAAAAAAAAAQIRAwQxBRIhUYEyQcEiYZHw8f/aAAwDAQAC
EQMRAD8A+mmqvvHWUJw1V94KAk7YtG67zmzJWzJuTTqcaikBKUIz041rwlOccsmKsmWONXJ0SjBy
2Oxn93W76Lbc3cVbmWwZZovCUkm1zLyiPROAgD1kE4HOMsdfCUkkvguenaVsXeqvvG+jOGqvvBQB
qr7wUBjABtUOmKrVak6MhXAubfalgrGcF1wIzj4xGcuVN9j2Kt0Wyt23KPalIaodCZSxT2RhKU9V
HxUo+Kj4kxzGTI5u2NYxUVSN6IEhBbzVl0e3Lgkq7R2ksCqJeMwy2MI1WSjKwByBUFjOPEZ6kw74
dmc4tP2MGpgk7XuLKGJmCAAgAmNnzM1MX1R0SbZdmBOSywhHMkIeSs/wBmKs7ShK+xPH6kWyjmBq
EACd3tZeZXLUKbSgmTbVNtrc9ELcDSkpPrIQT8Ia8La+rwY9WthLw3MYQAEAEhalbNtXNT7g4StM
nMNTCm0nBWlCwpSQT0yMiIZYc8Wu6JQlTTLbsPszTCJmXUFsOJC0LT0UlQyCPeI5dqhsZx4Ak962
4kO1GmWq0DxMoXPPHIxl06SBjuAhR+MOOGY+jl4MWql1SFDDQyBAAQAEAFm9hE9P1HZVSX6ivjcS
h1htRAB0mX1stg47JSB7hHO62KWV0MsDuCOvjKXFV9rdQqFR2lVp6pK4nkTb0ujljDTKy00AB7CR
7+sdLpYpY412FeV3JnOxeVhABk006+4llhJW8shKUJBJJPIAAQN0B3dm7u9+3OUTFUbFJpZwS5OA
6xHssjCs/qKYxZdfCG3Vl8NPKX2LDUyny9Jp0vS5QYlJZtEu0D4IbSEJ/wAEIZS5nYwSpUe8eHor
9tmw2rXxWPnVbLzQqGkhp6UeyjULecKS5zGSCBggDl1hlo9Ysa5ZbGXNgcnaErcNqXHak38iuOSd
lH8kJ1kkJXjqULH0VD1pJhvjyxmri7McoOO5HxMiOfdf+zd82dXOnnXw6/lwp4j5+P6bNN4+Rxwp
NgQAEABABD3591pryD6o8++RdfxItwepb+NyGTb28lZP6Hl//ft46L87fvkWH//Z
--_60A9E784-DBBE-4378-9A84-01D36C2226AF_--
You're referring to RFC 2387, "The MIME Multipart/Related Content-type"
To refer to an attachment by the value of its Content-ID (CID) MIME header field, it's as simple as:
<img src="cid:BBCLOGO#23AD2D600E">
Note that your body must be HTML, such as Content-Type: text/html; chaset="us-ascii", as indicated by RFC 2045 §5.
Outlook should do this automatically when you place images in your message body. If you need further help configuring that, there is probably a more appropriate Q&A site than (the programming-centric) Stack Overflow.

Getting Jmeter to generate the boundary dashes in the Content-Type header (eg boundary=--V0a4bfux...)

This what my HTTP request is generating
Content-Type: multipart/form-data; boundary=V0a4bfuxfGhaH_Voo_Gu6oAEtj5FJNcp; charset=UTF-8
However, when compared to the POST data, it is lacking the 2 dashes in the front, which causes the server to reject the request:
--V0a4bfuxfGhaH_Voo_Gu6oAEtj5FJNcp
Content-Disposition: form-data; data="dataToBeSent"
--V0a4bfuxfGhaH_Voo_Gu6oAEtj5FJNcp--
How do I get Jmeter to generate the dashes in the header?
(besides from manually creating the multipart form)
Note:
I am using the 'Use multipart/formdata for POST' option.
If I intercept the request and manually add the dashes in the header, the
server accepts the request.
You don't need to generate these values, the solution is to tick Use multipart/form-data for POST box in the HTTP Request sampler (or in the HTTP Request Defaults)
If you have any definition of Content-Type header in the HTTP Header Manager - you need to remove it and let JMeter generate appropriate Content-Type header on its own.
The header doesn't need the dashes. This is simply how multipart/form-data works. The body is built as follows:
--<boundary>
<headers>
<content>
--<boundary>
<headers>
<content>
--<boundary>--
The -- part indicates a new part starts. The body ends with ---- to indicate no new parts will follow.

JMeter Multipart JSON Request Form Data

I am trying to construct a HTTP Request through JMeter that uses a multipart data body.
I have a HTTP Header Manager that has COntent-Type set to multipart/form-data; boundary=AaB03x. I selected 'Use multipart/form-data for POST'.
I then have a data body created as,
`-----------------------------AaB03x
Content-Type: application/json
Content-Disposition: form-data; name="part1"
{"jsonKey1": "JsonValue1" }
-----------------------------AaB03x
Content-Type: application/json
Content-Disposition: form-data; name="part2"
{
"jsonKey2": "JsonValue2"
}
-----------------------------AaB03x
Content-Type: application/octet-stream
Content-Disposition: form-data; name="part3"
File Content here!!!!
-----------------------------AaB03x`
When I run this, I see that the request doesnt send the body correctly, instead it just sends some random data as,
POST data:
--vKOghkU7riRQbaANmmGpMs7j9TxCTUp3S2T0vE--
And gives an error response of,
`{"errorMsg":"Unable read headers from MultipartStream.","messageCode":"UnableReadHeadersFromMultipartStream","httpStat us":"BAD_REQUEST","requestName":"RequestName"}`
My second question is:
the part3 of the request sends a file to upload. Can I pass the file path somehow?
Given you set your own boundary and build your request manually I believe you need to uncheck Use multipart/form-data for POST in the HTTP Request Sampler
If your file encoding isn't very "exotic" you can try using __FileToString() function just instead of File Content here!!!!.
Looking into RFC 7578, it seems you also need a trailing -- at the end of the last line
You should try sending your JSON data as parameters. Also put your file path in the section for that... And even some servers don't actually need MIME type explicitly declared, you can check yours with some online tool like this one.
Your HTTP Request could look smethnig like:

Mail gem - how to clean up the body string

I'm trying to read an email using ruby mail gem.
But mail.body.decoded returns me not just the body message. How can I clean up this body message and remove unwanted text like:
-20cf30433c9a437cc304939017ef\nContent-Type: text/plain; charset=ISO-8859-1\nContent-
message = $stdin.read
mail = Mail.read_from_string(message)
puts mail.body.decoded
--20cf30433c9a437cc304939017ef\nContent-Type: text/plain; charset=ISO-8859-1\nContent-Transfer-Encoding: quoted-printable\n\n REAL BODY TEXT \\n\n--20cf30433c9a437cc304939017ef\nContent-Type: text/html; charset=ISO-8859-1\nContent-Transfer-Encoding: quoted-printable\n\n<br clear=3D\"all\">--20cf30433c9a437cc304939017ef--
How can I clean up this email body mail message extracting only the REAL BODY TEXT , without ANY header ?
I'm creating a simple Ticket System based in Ruby on Rails, and a ticket is created when an email is received by ticket#mydomain.com. But when the message is in HTML format the BODY TEXT is surrounded by HEADERs text.
If you have a properly formatted email, you can use Mail helper methods:
mail = Mail.new(email_string)
mail.text_part # finds the first text/plain part
mail.html_part # finds the first text/html part
This doesn't always work if you have e.g. single part messages (text only) or receive email from the internet at large since you can't rely on formatting from every client out there. Believe me, I've learned the hard way.
looks like you've got a multipart email, so you can use
mail.parts[0].body.decoded
These will probably come in handy too:
mail.multipart?
mail.parts.length
The gem documentation at github is pretty decent
With the mail gem, you can do:
text = mail.multipart? ? mail.text_part.decoded : mail.body.decoded`
Add the mail gem and just use email body format with mail.parts[1].body.decoded.

Resources