Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MailMessage can not send mails with attachment in Pharo7 #3163

Open
SabineMa opened this Issue Apr 11, 2019 · 6 comments

Comments

3 participants
@SabineMa
Copy link
Contributor

SabineMa commented Apr 11, 2019

In Pharo 7 it is no longer possible to send mails with an attachment with MailMessage.
This is the test example code. Works fine in Pharo 6 (needs to load zinc before for sending of the mails):

	| theMailMessage     theTestMailAddress theSmtpClient|
	theTestMailAddress := 'xxxx'.  
	theMailMessage := MailMessage empty  
		addAlternativePart: 'This is plain text.' contentType: 'text/plain';
		addAlternativePart: '<html><head></head><body>This is html text</body></html>'
			contentType: 'text/html';
		yourself.
 	theMailMessage	 
		addAttachmentFrom: ((File openForReadFileNamed: ('/Users/sabine/Desktop/belege/mini.png')))
		withName: 'MINI.PNG'.
	theMailMessage setField: 'from' toString: theTestMailAddress.
 	theMailMessage regenerateBodyFromParts.
 	theMailMessage
		setField: 'to'
		toString: theTestMailAddress , ' <' , theTestMailAddress , '>'.
	theMailMessage setField: 'reply-to' toString: theTestMailAddress.
		(theSmtpClient := ZdcSecureSMTPClient new)
		user: 'xxxx';
		password: 'xxxx'.
	theSmtpClient
		openOnHost: (NetNameResolver addressForName: 'smtp.strato.de')
		port: 465.
	theSmtpClient
		mailFrom: theTestMailAddress
		to: {theTestMailAddress}
		text: theMailMessage text.
	^ theSmtpClient
		quit;
		close;
		yourself

In Pharo7, the mail is sent but the file attached is empty.

After a lot of investigating I found the reason. In MailMessage>>regenerateText, this code causes the problem

encodedBodyText := body content.
self decoderClass ifNotNil: 
	[ encodedBodyText := self decoderClass mimeEncode: encodedBodyText readStream ].
	str nextPutAll: encodedBodyText].

Explanation: In case of an attachment, the decoderClass is not nil and encodedBodyText will be a Stream.
In Pharo 7 now, there is nothing written when doing str nextPutAll: anInstanceOfStream.
In Pharo6 that seemed to work.

With the original code, the mailText is generated like this:

| theMailMessage |
theMailMessage := MailMessage empty  
		addAlternativePart: 'This is plain text.' contentType: 'text/plain';
		addAlternativePart: '<html><head></head><body>This is html text</body></html>' contentType: 'text/html';
		yourself.
theMailMessage	 
		addAttachmentFrom: ((File openForReadFileNamed: ('/Users/sabine/Desktop/belege/mini.png')))
		withName: 'MINI.PNG'.
theMailMessage setField: 'from' toString: 'test@test.de'.
theMailMessage regenerateBodyFromParts.
theMailMessage text

results in

Mime-version: 1.0
From: test@test.de
Content-type: multipart/alternative;boundary="==CelesteAttachment97051=="

--==CelesteAttachment97051==
Content-type: text/plain

This is plain text.
--==CelesteAttachment97051==
Content-type: text/html

<html><head></head><body>This is html text</body></html>
--==CelesteAttachment97051==
Content-transfer-encoding: base64
Content-disposition: attachment;filename="MINI.PNG"
Content-type: application/octet-stream


--==CelesteAttachment97051==--

You see-> the file contents is missing

Now I change the method MailMessage>>regenerateText (last line) to

str nextPutAll: encodedBodyText **contents** (adding contents)

then the same test code results in this

Mime-version: 1.0
From: test@test.de
Content-type: multipart/alternative;boundary="==CelesteAttachment48880=="


--==CelesteAttachment48880==
Content-type: text/plain

This is plain text.
--==CelesteAttachment48880==
Content-type: text/html

<html><head></head><body>This is html text</body></html>
--==CelesteAttachment48880==
Content-transfer-encoding: base64
Content-disposition: attachment;filename="MINI.PNG"
Content-type: application/octet-stream

iVBORw0KGgoAAAANSUhEUgAAAGkAAABVCAYAAABKOsrsAAAK0WlDQ1BJQ0MgUHJvZmlsZQAA
SImVlwdUU2kWgP/3XjoJLSECUkJvgnQCSAk9FEE62AhJSEIJIQUVGyqDIzgWVERAHdEREQXH
AshYEFFsg2DFOiCDijIOFmyo7AOWMLN7dvfsPeee/8vN/W955//fuQ8AijZHIsmE1QHIEsul
0cF+jMSkZAb+CSABBFCAGzDkcGUSVlRUOEBlcv27vL8DoLH1pu1YrH///7+KBo8v4wIARaGc
ypNxs1A+juo3rkQq........................I CUT THIS.....
2ESsALsIW4gtxe7HnsBewN7G9mPf43A4Os4C54YLwSXh0nFLcetxO3H1uBZcF64PN4zH43.Go
NN5YQpCYlX78uzeOk9YA6qc17kkIqexYYWTAim+1SRK+RB3/modJIZJBoLVMi/+ZYXwt9oj1
vEgTjIDPAud7G8px7CAACJVKtStqL6uhQXbddVeTyKzz4mOo77DVJknhTXrTd2wYqhq1Bjok
tka0gQbqAjVC8LzURyefuY9InZzNmvpqrO6upvH/v+i2j0i9gMx9ROojUi+YgV4wxD5J6iNS
L5iBXjDEPknqI1IvmIFeMMQ+SeojUi+YgV4wxD5J6iNSL5iBXjDE/wNZOW/N+sRaYQAAAABJ
RU5ErkJggg==
--==CelesteAttachment48880==--

@SabineMa

This comment has been minimized.

Copy link
Contributor Author

SabineMa commented Apr 11, 2019

I think this would be an easy fix because if encodedBodyText is a string already, it does not matter, sending 'contents' to it

@svenvc

This comment has been minimized.

Copy link
Contributor

svenvc commented Apr 11, 2019

Yes, this is also what I did recently, send #contents to the readStream in MailMessage>>#regenerateText

It also took me some time to understand what was happening ;-)

I was just a bit unsure about the solution, as it felt more like a hack, and I was in a hurry.

Since we have now two similar fixes, it will probably be OK.

SabineMa added a commit to SabineMa/pharo that referenced this issue Apr 11, 2019

@SabineMa

This comment has been minimized.

Copy link
Contributor Author

SabineMa commented Apr 11, 2019

Thank you Sven. Honest to have found the same as you. And I created my first pull request with this, hope it is fine.

@akgrant43

This comment has been minimized.

Copy link
Collaborator

akgrant43 commented Apr 12, 2019

Hi @SabineMa ,

MailMessage uses MIMEDocument internally, which is extremely limited in its functionality.

I started to use ZnMimePart instead, but then got sidetracked on other projects. If you find yourself needing to extend MIMEDocument you might like to think about switching to ZnMimePart.

HTH,
Alistair

@svenvc

This comment has been minimized.

Copy link
Contributor

svenvc commented Apr 13, 2019

Alistair,

How would you rewrite Sabine's or any other example with MailMessage using ZnMimePart ?

Sven

@akgrant43

This comment has been minimized.

Copy link
Collaborator

akgrant43 commented Apr 16, 2019

Hi Sven,

Sorry for the slow reply. I haven't looked directly at integrating MailMessage with ZnMimePart, but... MailMessage uses MIMEDocument to hold the body of the message. From memory, MailMessage simply passes the source document off to MIMEDocument to parse, so it shouldn't be too difficult to replace MIMEDocument with ZnMimePart. MIMEDocument is missing a lot of functionality, and adding the missing functionality would largely duplicate what ZnMimePart and friends already does. So I think any effort would be much better value by working on replacing MIMEDocument with ZnMimePart.

Cheers,
Alistair

@MarcusDenker MarcusDenker added this to To do in Pharo7 Backporting via automation Apr 18, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.