refactor smtp to not clone the email

add email>headers word instead
db4
Doug Coleman 2008-08-16 17:20:18 -05:00
parent 0eea37c13d
commit 5e247325b2
2 changed files with 41 additions and 57 deletions

View File

@ -3,12 +3,6 @@ smtp.server kernel sequences namespaces logging accessors
assocs sorting ; assocs sorting ;
IN: smtp.tests IN: smtp.tests
[ t ] [
<email>
dup clone "a" "b" set-header drop
headers>> assoc-empty?
] unit-test
{ 0 0 } [ [ ] with-smtp-connection ] must-infer-as { 0 0 } [ [ ] with-smtp-connection ] must-infer-as
[ "hello\nworld" validate-address ] must-fail [ "hello\nworld" validate-address ] must-fail
@ -60,12 +54,13 @@ IN: smtp.tests
"Ed <dharmatech@factorcode.org>" "Ed <dharmatech@factorcode.org>"
} >>to } >>to
"Doug <erg@factorcode.org>" >>from "Doug <erg@factorcode.org>" >>from
prepare [
dup headers>> >alist sort-keys [ email>headers sort-keys [
drop { "Date" "Message-Id" } member? not drop { "Date" "Message-Id" } member? not
] assoc-filter ] assoc-filter
over to>> ]
rot from>> [ to>> [ extract-email ] map ]
[ from>> extract-email ] tri
] unit-test ] unit-test
[ ] [ [ 4321 mock-smtp-server ] "SMTP server" spawn drop ] unit-test [ ] [ [ 4321 mock-smtp-server ] "SMTP server" spawn drop ] unit-test

View File

@ -23,6 +23,14 @@ LOG: log-smtp-connection NOTICE ( addrspec -- )
call call
] with-client ; inline ] with-client ; inline
TUPLE: email
{ from string }
{ to array }
{ subject string }
{ body string } ;
: <email> ( -- email ) email new ;
: crlf ( -- ) "\r\n" write ; : crlf ( -- ) "\r\n" write ;
: command ( string -- ) write crlf flush ; : command ( string -- ) write crlf flush ;
@ -123,43 +131,12 @@ ERROR: invalid-header-string string ;
[ invalid-header-string ] unless ; [ invalid-header-string ] unless ;
: write-header ( key value -- ) : write-header ( key value -- )
swap [ validate-header write ]
validate-header write [ ": " write validate-header write ] bi* crlf ;
": " write
validate-header write
crlf ;
: write-headers ( assoc -- ) : write-headers ( assoc -- )
[ write-header ] assoc-each ; [ write-header ] assoc-each ;
TUPLE: email
{ from string }
{ to array }
{ subject string }
{ headers hashtable }
{ body string } ;
: <email> ( -- email ) email new ;
M: email clone
call-next-method [ clone ] change-headers ;
: (send) ( email -- )
[
helo get-ok
dup from>> mail-from get-ok
dup to>> [ rcpt-to get-ok ] each
data get-ok
dup headers>> write-headers
crlf
body>> send-body get-ok
quit get-ok
] with-smtp-connection ;
: extract-email ( recepient -- email )
#! This could be much smarter.
" " last-split1 swap or "<" ?head drop ">" ?tail drop ;
: message-id ( -- string ) : message-id ( -- string )
[ [
"<" % "<" %
@ -171,21 +148,33 @@ M: email clone
">" % ">" %
] "" make ; ] "" make ;
: set-header ( email value key -- email ) : extract-email ( recepient -- email )
pick headers>> set-at ; #! This could be much smarter.
" " last-split1 swap or "<" ?head drop ">" ?tail drop ;
: prepare ( email -- email ) : email>headers ( email -- hashtable )
clone [
dup from>> "From" set-header [ from>> "From" set ]
[ extract-email ] change-from [ to>> ", " join "To" set ]
dup to>> ", " join "To" set-header [ subject>> "Subject" set ] tri
[ [ extract-email ] map ] change-to now timestamp>rfc822 "Date" set
dup subject>> "Subject" set-header message-id "Message-Id" set
now timestamp>rfc822 "Date" set-header ] { } make-assoc ;
message-id "Message-Id" set-header ;
: (send-email) ( headers email -- )
[
helo get-ok
dup from>> extract-email mail-from get-ok
dup to>> [ extract-email rcpt-to get-ok ] each
data get-ok
swap write-headers
crlf
body>> send-body get-ok
quit get-ok
] with-smtp-connection ;
: send-email ( email -- ) : send-email ( email -- )
prepare (send) ; [ email>headers ] keep (send-email) ;
! Dirk's old AUTH CRAM-MD5 code. I don't know anything about ! Dirk's old AUTH CRAM-MD5 code. I don't know anything about
! CRAM MD5, and the old code didn't work properly either, so here ! CRAM MD5, and the old code didn't work properly either, so here