[thelist] Friday Freebie Part 1 of 2

Scott Dexter sgd at ti3.com
Fri Sep 22 16:23:18 CDT 2000


(Ya want to know how to send email asynchronously? I got ya covered. Next
week I'll add sending attachments through this method)

<tip type="IIS/SMTP" author="Scott Dexter" email="sgd at thinksafely.org">
(this has a couple caveats, but the biggest one to note is without fun NT
access permission tweaking, I'm expecting you to have IIS and its SMTP
server running on the same box)

Don't use CDONTS (even the acronym is a good reminder). Don't use ASPMail.
Don't worry about talking to the email server directly. Do it the fast
smooth --asynchronous-- way: drop a file off and let the SMTP server handle
it.

Here's what you need to cook this up:
1) IIS 4
2) IIS' SMTP Server installed on the same server
3) ASP and VBScript
(Part 3 could be putting this stuff into a component (dll), ask me)
4) a little MIME knowledge

Working backwards, let's start with a little MIME, shall we?
<insert image of midget in white face-paint trying to get out of an
invisible box>

MIME (Multi-purpose Internet Mail Extensions) is an extension of SMTP
(Simple Mail Transfer Protocol), that allows some description of the data to
cue the recipient into using the right application to view the contents. You
may have already dealt with MIME types and not even know it. "text/html"
anyone? how about "text/css" ? --Those are MIME types, and tell the
recipient (your browser) how to handle the data.

What does knowing MIME do for us? Well, in order to just drop a file off and
go, and expect IIS' SMTP server to send it out, we have to write the file in
raw MIME format. It's not that tough, but ya gots to know what goes where.
--We get to generate our own email headers. On top of that, if we want to
send attachments, we have to play with MIME and know the right way to
package it.

Email process overview:
1) we gotta generate a unique filename
2) enumerate through our headers and write it to file (with the filename
above)
3) we move that file to the SMTP Pickup directory, where the SMTP Server
nabs it

1) creating a unique filename
	Because we may have multiple people firing this off, we need to
ensure we don't step on anyone else.
<%
Function GenMIMEName()
    Randomize   ' Initialize random-number generator.
    RandomNbr = Int((1000000 * Rnd) + 0)
    RandomNbr = Right("0000000" + RandomNbr, 6)
    GenMIMEName = Request.ServerVariables("REMOTE_ADDR") & "_" & RandomNbr &
".email"
End Function
%>

2) We need to have some specific headers and such, here's what a MIME email
looks like before its sent out:

Return-Path:<support at ti3.com>
Date: Mon, Aug 28 2000 17:41 -0600
To: <sgd at ti3.com>
From: <support at ti3.com>
Subject: [Friday Freebie] Look, ma no CDONTS!
MIME-Version: 1.0
Content-Type: text/plain; charset="US-ASCII"
Content-transfer-encoding: 7bit

This is the body of the email. I'm the company liability!


--So this is pretty straightforward then, right? We gotta worry about a
couple things: creating the date in the right format, and making sure we
have at least one blank line after the headers to indicate the start of the
body. To create the date, we need to spit it out in "ddd, mmm dd yyyy hh:nn
gggg" --try this:

<%
function GenMIMEDate(byval mydate, byval gggg)
' mydate is already a date type, no error checking here!
' gggg is expected to already be in offset from GMT format, i.e. "-0600"
' we need to return ddd, mmm dd yyyy hh:nn gggg
ddd = weekdayname(weekday(mydate),True)
mmm = monthname(month(mydate),True)
dd = day(mydate)
yyyy = year(mydate)
hh = hour(mydate)
nn = minute(mydate)
GenMIMEDate = ddd &", "& mmm &" "& dd &" "& yyyy &" "& hh &":"& nn &" "&
gggg
end function
%>

-- I played with dummy proofing the offset, but for now let's just assume
that we already now it, as its not the point of this tip ;)

So here's what I have to generate our headers and email
<%
function GenMIMEHeaders(byval replyto, byval from, byval mto, byval subject)
replyto = "<"& replyto &">"
from = "<"& from &">"
sendto = split(mto,",")
for each addr in sendto
	tolist = "<"& addr &">," & tolist
Next
tolist = Left(tolist,len(tolist)-1) ' take off the last comma
headers = "Return-Path:"&replyto & vbNewLine
headers = headers & "Date: " & GenMIMEDate(Now,"-0600") & vbNewLine
headers = headers & "To:"& tolist & vbNewLine
headers = headers & "From:"& from & vbNewLine
headers = headers & "Subject: "& subject & vbNewLine
headers = headers & "MIME-Version: 1.0" & vbNewLine
headers = headers & "Content-Type: text/plain; charset=""US-ASCII""" &
vbNewLine
GenMIMEHeaders = headers & "Content-transfer-encoding: 7bit" & vbNewLine &
vbNewLine
end function

function GenMIMEEmail(byval from, byval mto, byval subject, byval body)
GenMIMEEmail = GenMIMEHeaders(from,from,mto,subject) & body
end function
%>

--Notice we're able to take in a comma delimited list of To: addresses. That
way we can send to multiple people at once (from the department of
redundancy department)

Also notice I've separated creating the headers with attaching the body.
This on purpose, because next week (this is getting long as it is) I'm gonna
expand to include attachments.

Now we gotta write it to a file, in a temporary spot. This is because if we
create the file in the Pickup directory, the SMTP server will try to slurp
it up before we're done, and that's Bad. Oh yeah, where the hell is this
Pickup directory? --\InetPub\MailRoot\Pickup (using the default install name
for the Inet root). Create a directory for the temp spot; we use
D:\InetPub\MailRoot\Pickup\TempMail.

Let's write it to file, shall we?
<%
Sub WriteEmail(byval email, byval filename)
Dim ForAppending,fs,a,logstr
' drop the email to a file
ForAppending = 8
filename = "D:\InetPub\Mailroot\Pickup\tempmail\" & filename
Set fs = CreateObject("Scripting.FileSystemObject")
Set a = fs.OpenTextFile(filename, ForAppending, True)
a.Write(email)
a.Close
Set a = Nothing
Set fs = Nothing
End Sub
%>

3) Move the temp file into the Pickup directory
Well, so far we gots the email being generated with all the MIME we need
(for now), and we're writing it to the file system with no probs. Now we
gotta move it to the Pickup directory to actually get it sent. I'll reopen
the WriteEmail subroutine and tweak a few things to get it done:

<%
Sub WriteEmail(byval email, byval filename)
Dim ForAppending,fs,a,logstr
' drop the email to a file
tempdir ="tempmail\"
pickupdir = "D:\InetPub\Mailroot\Pickup\"
ForAppending = 8
tempfilename = pickupdir & tempdir & filename
Set fs = CreateObject("Scripting.FileSystemObject")
Set a = fs.OpenTextFile(tempfilename, ForAppending, True)
a.Write(email)
a.Close
Set a = Nothing
fs.MoveFile tempfilename, pickupdir & filename
Set fs = Nothing
End Sub
%>


Phew.

Now, let's see the function calls in action:

<%
' watch out for line wrap
email = genMIMEEmail("support at ti3.com","sgd at ti3.com","[Friday Freebie] Look,
ma no CDONTS!","This is the body of the email. I'm the company liability!")

WriteEmail email,GenMIMEName
%>

Gee, that was simple, wasn't it?

Next week, I'll add in attachments.
</tip>


sgd
--
work: http://www.ti3.com/
non: http://thinksafely.org/




More information about the thelist mailing list