ASP FormMail
Coding Details
View the source code for this ASP script.The script is fairly simple with four basic steps.
- Check the request to ensure a valid form submission.
- Process (most of) the control form fields passed.
- If no errors occured in the previous steps, create and send the email.
- Produce an output page displaying either errors or the data that was emailed.
Note that the script does not necessarily stop processing when an error occurs. Instead, error messages are stored in a global array and processing continues where possible. Then all the error messages can be displayed on the final step.
The details for each step are discussed below.
Checking for a Valid Form Submission
The script first checks for form data in the request, no data means that there is nothing to process.
'Check for form data.
if Request.ServerVariables("Content_Length") = 0 then
call AddErrorMsg("No form data submitted.")
end if
Then it does the bot check (if enabled).
'If bot checking is enabled, check the elapsed time.
if botCheckFlag then
startTime = Session(botCheckID)
if not IsDate(startTime) then
call AddErrorMsg("Invalid submission.")
elseif DateDiff("s", startTime, Now()) < botCheckMinTime then
call AddErrorMsg("Invalid submission.")
end if
end if
The next check is to determine if the host in the referering URL is permitted.
'Check if the referering host is allowed.
if UBound(allowedHosts) >= 0 then
host = GetHost(Request.ServerVariables("HTTP_REFERER"))
if host = "" then
call AddErrorMsg("No referer.")
elseif not InList(host, allowedHosts) then
call AddErrorMsg("Unauthorized host: '" & host & "'.")
end if
end if
The HTTP_REFERER environment variable contains the URL of the
form that submitted the request. This is passed to the GetHost()
function which parses out the host name, i.e. the characters between the the
beginning "http://" (or "https://") and the next "/" character.
The script then looks in the allowedHosts list for a match. Any
requests from an unauthorized host name generates an error message.
Processing the Control Fields
The only required control field is _recipients. The script
ensures that at least one recipient is specified. It then checks that each
is a valid email address and is permitted via the
allowedRecipients list.
'Check the email recipients.
if Request.Form("_recipients") = "" then
call AddErrorMsg("No email recipient(s) specified.")
else
recipients = Split(Request.Form("_recipients"), ",")
for each addr in recipients
addr = Trim(addr)
if not IsValidEmailAddress(addr) then
call AddErrorMsg("Invalid email address in recipient list: " _
& addr & ".")
elseif UBound(allowedRecipients) >= 0 then
if not inList(addr, allowedRecipients) then
call AddErrorMsg( _
"Unauthorized email address in recipient list: " & addr & ".")
end if
end if
next
recipients = Join(recipients, ",")
end if
Next is the _replyToField or _ccToField control
field. These work a little differently. The value is taken to be the name of
another field present in the form data. The script takes the value of this
other field to be used as the Reply-To or CC
address.
'Check for a cc-to or reply-to address.
ccToAddr = ""
replyToAddr = ""
name = Trim(Request.Form("_ccToField"))
if name <> "" then
if not allowCcToFlag then
call AddErrorMsg( _
"Configuration error: use of _ccToField not permitted.")
else
ccToAddr = Request.Form(name)
if ccToAddr <> "" then
if not IsValidEmailAddress(ccToAddr) then
call AddErrorMsg("Invalid email address in " & name _
& " field: " & ccToAddr & ".")
end if
end if
end if
else
name = Trim(Request.Form("_replyToField"))
if name <> "" then
replyToAddr = Request.Form(name)
if replyToAddr <> "" then
if not IsValidEmailAddress(replyToAddr) then
call AddErrorMsg("Invalid email address in " & name _
& " field: " & replyToAddr & ".")
end if
end if
end if
end if
Note that if _ccToField is used, _replyToField
will be ignored.
Again, since the resulting value is suppose to be an email addresses, it is checked to ensure it is in the correct format.
The script then gets the email subject line from the _subject
control field.
'Get the subject text.
subject = Request.Form("_subject")
The _requiredFields control field is processed next. Like
_recipients, it may have multiple values separated by commas, so
these checked individually. And like _replyToField or
_ccToField, those values are taken to be the names of other form
fields.
'If required fields are specified, check them.
if Request.Form("_requiredFields") <> "" then
required = Split(Request.Form("_requiredFields"), ",")
for each name in required
name = Trim(name)
if Left(name, 1) <> "_" and Request.Form(name) = "" then
call AddErrorMsg("Missing value for " & name)
end if
next
end if
If any of the specified fields has a null string value, an error message is generated. Note that any field whose name starts with an underscore is ignored, as that is reserved for the control fields.
The _fieldOrder control field is handled next, resulting in an
array of field names which will be used to display the form fields in that
specified order.
'If a field order was given, use it. Otherwise use the order the fields
'were received in.
str = ""
if Request.Form("_fieldOrder") <> "" then
fieldOrder = Split(Request.Form("_fieldOrder"), ",")
for each name in fieldOrder
if str <> "" then
str = str & ","
end if
str = str & Trim(name)
next
fieldOrder = Split(str, ",")
else
fieldOrder = FormFieldList()
end if
Generating the Email
If no errors have been detected so far, the next step is building the email. The script contructs the body of the email note, using HTML formatting.
'If there were no errors, build the email note and send it.
if UBound(errorMsgs) < 0 then
'Build table of form fields and values.
body = "<table border=""0"" cellpadding=""2"" cellspacing=""0"">" _
& vbCrLf
for each name in fieldOrder
body = body _
& "<tr valign=""top"">" _
& "<td><strong>" & name & ":</strong></td>" _
& "<td>" & Request.Form(name) & "</td>" _
& "</tr>" & vbCrLf
next
body = body & "</table>" & vbCrLf
Note the use of the fieldOrder array. It is simply an array of
field names generated in the previous step using either the
_fieldOrder control field or (when that control field is not used)
by a function called FormFieldList().
This function corrects a small problem with VBScript. While it's possible to simply loop through all the form fields using a statement like...
for each name in Request.Form
...
next
VBScript doesn't guarantee that the field names will be given in the same order as they appear in the form request sent by the browser.
To ensure that the fields are listed in the order received, the
FormFieldList() function is used to generate the names in an
array in the proper order.
The _envars control field is checked here to append a display
of any requested environmental variables to the email.
'Add a table for any requested environment variables.
if Request.Form("_envars") <> "" then
body = body _
& "<p> </p>" & vbCrLf _
& "<table border=""0"" cellpadding=""2"" cellspacing=""0"">" _
& vbCrLf
envars = Split(Request.Form("_envars"), ",")
for each name in envars
name = Trim(name)
'Only show environment variables in the permitted list.
showEnvar = true
if UBound(allowedEnvars) >= 0 then
showEnvar = InList(name, allowedEnvars)
end if
if showEnvar then
body = body _
& "<tr valign=""top"">" _
& "<td><strong>" & name & ":</strong></td>" _
& "<td>" & Request.ServerVariables(name) & "</td>" _
& "</tr>" & vbCrLf
end if
next
body = body & "</table>" & vbCrLf
end if
Now the email can be sent. If an error occurs when attempting to send it, the error message is saved for display.
'Send it.
str = SendMail()
if str <> "" then
AddErrorMsg(str)
else
'Clear the bot check timestamp.
Session.Contents.Remove(botCheckID)
'Redirect if a URL was given.
if Request.Form("_redirectUrl") <> "" then
Response.Redirect(Request.Form("_redirectUrl"))
end if
end if
Displaying the Results
The final step is to build a page for display. If any errors were
encountered, these are listed. Otherwise, the script checks for the
_redirectUrl control field
If a redirect URL was specified, it redirects to that page. If not, the
script builds a simple display of the fields included in the email. If a URL
was specified in the _continueUrl control field, it adds a link
to it at the bottom of the page.