[cl-smtp-cvs] CVS cl-smtp

jidzikowski jidzikowski at common-lisp.net
Thu Apr 22 10:51:34 UTC 2010


Update of /project/cl-smtp/cvsroot/cl-smtp
In directory cl-net:/tmp/cvs-serv16391

Modified Files:
	CHANGELOG cl-smtp.lisp 
Log Message:
Fixed encoding errors in header strings



--- /project/cl-smtp/cvsroot/cl-smtp/CHANGELOG	2010/04/20 10:19:21	1.15
+++ /project/cl-smtp/cvsroot/cl-smtp/CHANGELOG	2010/04/22 10:51:34	1.16
@@ -1,3 +1,9 @@
+Version 20100422.1
+2010.04.22
+Fixed encoding errors in header strings,
+new function q-encode-str to encode strings in header
+Change cl-smtp.lisp, CHANGELOG
+
 Version 20100420.1
 2010.04.20
 Fixed error when send more than 1 attachment, 
--- /project/cl-smtp/cvsroot/cl-smtp/cl-smtp.lisp	2008/04/12 19:40:36	1.13
+++ /project/cl-smtp/cvsroot/cl-smtp/cl-smtp.lisp	2010/04/22 10:51:34	1.14
@@ -62,6 +62,28 @@
   #+allegro (excl:string-to-base64-string str)
   #-allegro (cl-base64:string-to-base64-string str))
 
+(defun q-encode-str (str &key (external-format 
+                               (flex:make-external-format :iso-8859-15)))
+  (let ((line-has-non-ascii nil))
+    (with-output-to-string (s)
+      (loop for c across str do
+           (cond
+             ((< 127 (char-code c))
+              (unless line-has-non-ascii
+                (format s "=?~A?Q?" (flex:external-format-name external-format))
+                (setf line-has-non-ascii t))
+              (loop for byte across (flex:string-to-octets 
+                                     (make-string 1 :initial-element c)
+                                     :external-format external-format)
+                 do (format s "=~2,'0X" byte)))
+             (t 
+              (when line-has-non-ascii
+                (format s "?=")
+                (setf line-has-non-ascii nil))
+              (format s "~C" c))))
+      (when line-has-non-ascii
+        (format s "?=")))))
+
 (define-condition smtp-error (error)
   ())
 
@@ -104,7 +126,13 @@
     lines))
 
 (defun do-with-smtp-mail (host from to thunk &key port authentication ssl local-hostname)
-  (usocket:with-client-socket (socket stream host port)
+  (usocket:with-client-socket (socket stream host port 
+                                      :element-type '(unsigned-byte 8))
+    (setf stream (flexi-streams:make-flexi-stream 
+                                 stream
+                                 :external-format 
+                                 (flexi-streams:make-external-format 
+                                  :latin-1 :eol-style :lf)))
     (let ((stream (smtp-handshake stream
                                   :authentication authentication 
                                   :ssl ssl
@@ -155,6 +183,7 @@
                           :authentication authentication 
                           :ssl ssl
                           :local-hostname local-hostname)
+    (setf (in-header stream) nil)
     (let* ((boundary (make-random-boundary))
            (html-boundary (if (and attachments html-message)
                               (make-random-boundary)
@@ -288,9 +317,9 @@
            (setf stream 
                  #+allegro (socket:make-ssl-client-stream stream)
                  #-allegro
-                 (let ((s stream))
+                 (let ((s (flexi-streams:flexi-stream-stream stream)))
                    (cl+ssl:make-ssl-client-stream 
-                    (cl+ssl:stream-fd stream)
+                    (cl+ssl:stream-fd s)
                     :close-callback (lambda () (close s)))))
            #-allegro
            (setf stream (flexi-streams:make-flexi-stream 
@@ -360,14 +389,16 @@
    server connected to on STREAM.  The server is expected to have
    previously accepted the DATA SMTP command."
   (write-to-smtp stream (format nil "Date: ~A" (get-email-date-string)))
-  (write-to-smtp stream (format nil "From: ~@[~A <~]~A~@[>~]" 
-				display-name from display-name))
+  (if display-name
+      (write-to-smtp stream (format nil "From: ~A <~A>" 
+				(q-encode-str display-name) from))
+      (write-to-smtp stream (format nil "From: ~A" from)))
   (write-to-smtp stream (format nil "To: ~{ ~a~^,~}" to))
   (when cc
     (write-to-smtp stream (format nil "Cc: ~{ ~a~^,~}" cc)))
-  (write-to-smtp stream (format nil "Subject: ~A" subject))
+  (write-to-smtp stream (format nil "Subject: ~A" (q-encode-str subject)))
   (write-to-smtp stream (format nil "X-Mailer: cl-smtp ~A" 
-				*x-mailer*))
+				(q-encode-str *x-mailer*)))
   (when reply-to
     (write-to-smtp stream (format nil "Reply-To: ~A" reply-to)))
   (when (and extra-headers
@@ -388,7 +419,7 @@
 
 (defun write-to-smtp (stream command)
   (print-debug (format nil "to server: ~A" command)) 
-  (write-string command stream)
+  (write-sequence command stream)
   (write-char #\Return stream)
   (write-char #\NewLine stream)
   (force-output stream))





More information about the Cl-smtp-cvs mailing list