[ { "hello" "." "world" } validate-message ] must-fail
-[ "hello\r\nworld\r\n.\r\n" ] [
+[ "aGVsbG8Kd29ybGQ=\r\n.\r\n" ] [
"hello\nworld" [ send-body ] with-string-writer
] unit-test
[
{
+ { "Content-Transfer-Encoding" "base64" }
+ { "Content-Type" "Text/plain; charset=utf-8" }
{ "From" "Doug <erg@factorcode.org>" }
+ { "MIME-Version" "1.0" }
{ "Subject" "Factor rules" }
{ "To" "Slava <slava@factorcode.org>, Ed <dharmatech@factorcode.org>" }
}
[ message-contains-dot ] when ;
: send-body ( body -- )
- string-lines
- validate-message
- [ write crlf ] each
+ utf8 encode
+ >base64-lines write crlf
"." command ;
: quit ( -- )
: auth ( -- ) smtp-auth get send-auth ;
+: encode-header ( string -- string' )
+ dup aux>> [
+ "=?utf-8?B?"
+ swap utf8 encode >base64
+ "?=" 3append
+ ] when ;
+
ERROR: invalid-header-string string ;
: validate-header ( string -- string' )
: write-header ( key value -- )
[ validate-header write ]
- [ ": " write validate-header write ] bi* crlf ;
+ [ ": " write validate-header encode-header write ] bi* crlf ;
: write-headers ( assoc -- )
[ write-header ] assoc-each ;
! This could be much smarter.
" " split1-last swap or "<" ?head drop ">" ?tail drop ;
+: utf8-mime-header ( -- alist )
+ {
+ { "MIME-Version" "1.0" }
+ { "Content-Transfer-Encoding" "base64" }
+ { "Content-Type" "Text/plain; charset=utf-8" }
+ } ;
+
: email>headers ( email -- hashtable )
[
{
} cleave
now timestamp>rfc822 "Date" set
message-id "Message-Id" set
- ] { } make-assoc ;
+ ] { } make-assoc utf8-mime-header append ;
: (send-email) ( headers email -- )
[