smtp: make content-type configurable

db4
Slava Pestov 2009-04-17 17:52:41 -05:00
parent 86e97b0d9c
commit 4c3d5cffac
5 changed files with 30 additions and 24 deletions

View File

@ -1,3 +1,5 @@
Elie Chaftari Elie Chaftari
Dirk Vleugels Dirk Vleugels
Slava Pestov Slava Pestov
Doug Coleman
Daniel Ehrenberg

View File

@ -36,6 +36,7 @@ SYMBOL: data-mode
: process ( -- ) : process ( -- )
read-crlf { read-crlf {
{ [ dup not ] [ f ] }
{ {
[ dup [ "HELO" head? ] [ "EHLO" head? ] bi or ] [ dup [ "HELO" head? ] [ "EHLO" head? ] bi or ]
[ "220 and..?\r\n" write flush t ] [ "220 and..?\r\n" write flush t ]

View File

@ -1,7 +1,7 @@
! Copyright (C) 2008 Doug Coleman. ! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors kernel quotations help.syntax help.markup USING: accessors kernel quotations help.syntax help.markup
io.sockets strings calendar ; io.sockets strings calendar io.encodings.utf8 ;
IN: smtp IN: smtp
HELP: smtp-domain HELP: smtp-domain
@ -41,7 +41,9 @@ HELP: email
{ { $slot "to" } "The recipients of the e-mail. A sequence of e-mail addresses." } { { $slot "to" } "The recipients of the e-mail. A sequence of e-mail addresses." }
{ { $slot "cc" } "Carbon-copy. A sequence of e-mail addresses." } { { $slot "cc" } "Carbon-copy. A sequence of e-mail addresses." }
{ { $slot "bcc" } "Blind carbon-copy. A sequence of e-mail addresses." } { { $slot "bcc" } "Blind carbon-copy. A sequence of e-mail addresses." }
{ { $slot "subject" } " The subject of the e-mail. A string." } { { $slot "subject" } "The subject of the e-mail. A string." }
{ { $slot "content-type" } { "The MIME type of the body. A string, default is " { $snippet "text/plain" } "." } }
{ { $slot "encoding" } { "An encoding to send the body as. Default is " { $link utf8 } "." } }
{ { $slot "body" } " The body of the e-mail. A string." } { { $slot "body" } " The body of the e-mail. A string." }
} }
"The " { $slot "from" } " and " { $slot "to" } " slots are required; the rest are optional." "The " { $slot "from" } " and " { $slot "to" } " slots are required; the rest are optional."

View File

@ -16,7 +16,7 @@ IN: smtp.tests
[ { "hello" "." "world" } validate-message ] must-fail [ { "hello" "." "world" } validate-message ] must-fail
[ "aGVsbG8Kd29ybGQ=\r\n.\r\n" ] [ [ "aGVsbG8Kd29ybGQ=\r\n.\r\n" ] [
"hello\nworld" [ send-body ] with-string-writer T{ email { body "hello\nworld" } } [ send-body ] with-string-writer
] unit-test ] unit-test
[ { "500 syntax error" } <response> check-response ] [ { "500 syntax error" } <response> check-response ]
@ -51,7 +51,7 @@ IN: smtp.tests
[ [
{ {
{ "Content-Transfer-Encoding" "base64" } { "Content-Transfer-Encoding" "base64" }
{ "Content-Type" "Text/plain; charset=utf-8" } { "Content-Type" "text/plain; charset=UTF-8" }
{ "From" "Doug <erg@factorcode.org>" } { "From" "Doug <erg@factorcode.org>" }
{ "MIME-Version" "1.0" } { "MIME-Version" "1.0" }
{ "Subject" "Factor rules" } { "Subject" "Factor rules" }

View File

@ -1,12 +1,12 @@
! Copyright (C) 2007, 2008 Elie CHAFTARI, Dirk Vleugels, ! Copyright (C) 2007, 2008 Elie CHAFTARI, Dirk Vleugels,
! Slava Pestov, Doug Coleman. ! Slava Pestov, Doug Coleman, Daniel Ehrenberg.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: arrays namespaces make io io.encodings.string USING: arrays namespaces make io io.encodings.string io.encodings.utf8
io.encodings.utf8 io.timeouts io.sockets io.sockets.secure io.encodings.iana io.timeouts io.sockets io.sockets.secure
io.encodings.ascii kernel logging sequences combinators io.encodings.ascii kernel logging sequences combinators splitting
splitting assocs strings math.order math.parser random system assocs strings math.order math.parser random system calendar summary
calendar summary calendar.format accessors sets hashtables calendar.format accessors sets hashtables base64 debugger classes
base64 debugger classes prettyprint io.crlf ; prettyprint io.crlf words ;
IN: smtp IN: smtp
SYMBOL: smtp-domain SYMBOL: smtp-domain
@ -44,6 +44,8 @@ TUPLE: email
{ cc array } { cc array }
{ bcc array } { bcc array }
{ subject string } { subject string }
{ content-type string initial: "text/plain" }
{ encoding word initial: utf8 }
{ body string } ; { body string } ;
: <email> ( -- email ) email new ; inline : <email> ( -- email ) email new ; inline
@ -85,8 +87,8 @@ M: message-contains-dot summary ( obj -- string )
"." over member? "." over member?
[ message-contains-dot ] when ; [ message-contains-dot ] when ;
: send-body ( body -- ) : send-body ( email -- )
utf8 encode [ body>> ] [ encoding>> ] bi encode
>base64-lines write crlf >base64-lines write crlf
"." command ; "." command ;
@ -195,24 +197,23 @@ ERROR: invalid-header-string string ;
! This could be much smarter. ! This could be much smarter.
" " split1-last swap or "<" ?head drop ">" ?tail drop ; " " split1-last swap or "<" ?head drop ">" ?tail drop ;
: utf8-mime-header ( -- alist ) : email-content-type ( email -- content-type )
{ [ content-type>> ] [ encoding>> encoding>name ] bi "; charset=" glue ;
{ "MIME-Version" "1.0" }
{ "Content-Transfer-Encoding" "base64" }
{ "Content-Type" "Text/plain; charset=utf-8" }
} ;
: email>headers ( email -- hashtable ) : email>headers ( email -- assoc )
[ [
now timestamp>rfc822 "Date" set
message-id "Message-Id" set
"1.0" "MIME-Version" set
"base64" "Content-Transfer-Encoding" set
{ {
[ from>> "From" set ] [ from>> "From" set ]
[ to>> ", " join "To" set ] [ to>> ", " join "To" set ]
[ cc>> ", " join [ "Cc" set ] unless-empty ] [ cc>> ", " join [ "Cc" set ] unless-empty ]
[ subject>> "Subject" set ] [ subject>> "Subject" set ]
[ email-content-type "Content-Type" set ]
} cleave } cleave
now timestamp>rfc822 "Date" set ] { } make-assoc ;
message-id "Message-Id" set
] { } make-assoc utf8-mime-header append ;
: (send-email) ( headers email -- ) : (send-email) ( headers email -- )
[ [
@ -227,7 +228,7 @@ ERROR: invalid-header-string string ;
data get-ok data get-ok
swap write-headers swap write-headers
crlf crlf
body>> send-body get-ok send-body get-ok
quit get-ok quit get-ok
] with-smtp-connection ; ] with-smtp-connection ;