Title: Hotmail---Delphi Style! (Part 1/3)
Question: This is the first of a three-part series showing how to access Hotmail through the HTTPMail "protocol" that OE uses using Delphi.
Answer:
Previously published in Hardcore Delphi
(Pinnacle Publishing-Feb/Mar 2004)
Being a frequent contributor to various Delphi help sites and
Newsgroups, I have seen many questions about how to access
Hotmail e-mail from within Delphi. In this article, we explore
the way that Outlook Express communicates with Microsoft
Hotmails servers.
Overview
Since Microsoft has discontinued their free SMPT service for
Hotmail there had to be another way to access Hotmail messages
from outside the web and Outlook Express. Microsoft Hotmail
uses the WebDAV, the acronym for World Wide Web Distributed
Authoring and Versioning, protocol to communicate with
Microsoft Outlook Express. Microsoft calls it HTTPMail.
Due to the success of the HTTP protocol, WebDAV was created to
utilize HTTP for distributed authoring. It is defined in RFC
2518 and more info can be found on the IETF WEBDAV Working
Group site at http://www.ics.uci.edu/~ejw/authoring/.
Detail
Microsoft's implementation of WebDAV first appeared in Outlook
Express 4. It allowed users to access their Hotmail accounts
without having to use a browser. Microsoft continues to say
that this functionality is a beta product and it has never been
publicly documented nor has this functionality been added to
other products such as Outlook, However, Microsoft Exchange now
has WebDAV capabilities.
In this issue, we will take a look at how to communicate with
Microsoft's Hotmail servers. A thorough understanding of the
HTTPMail processing that occurs is needed to be able to handle
the command messages that you will send to Hotmail and the
responses that you will receive back from the server.
Trapping HTTPMail Traffic
Since Outlook Express uses HTTPMail to communicate with Hotmail
we are going to use Outlook Express as a tool to determine what
messages need to be sent to Hotmail and what is sent back to us
from Hotmail. We can log all of the HTTPMail traffic using
Outlook Express by turning on HTTP logging. Then we can have a
look at what is going on behind the scenes.
The HTTP logging option is accessed via the Tools...Options
dialog. Check the HTTP check box in the Troubleshooting options
on the Maintenance Tab.
Next, you need to setup Outlook Express to access your Hotmail
account. Go into Tools...Accounts and Select Add...Mail. In the
wizard, type your name and Hotmail email address. On the E-Mail
Server Names page of the wizard, you can see that it has
already selected HTTP as the Type and Hotmail as the HTTP
service provider. Click Next and enter your password
information. This will create a Hotmail "Folder" in the left
pane of Outlook Express.
Now, as we connect to Hotmail, retrieve, delete, move, or send
messages, the "conversation" between Outlook Express and the
Hotmail servers will be logged in a file named HTTPMail.log
stored in this directory:
%UserProfile%\Local Settings\Application Data\Identities\
{8C3F8722-821F-47F2-B3D3-7CF974FD3718}\Microsoft\Outlook Express\.
Note that this path may differ based upon your operating system
and Outlook Express version. To view the messages sent to and
the responses from the Hotmail servers open the HTTPMail.log
file.
Connecting to Hotmail
Let's take a look at how a connection to Hotmail is made. In
the Hotmail implementation, a typical session occurs like this:
A client requests a PROPFIND of the inbox and other properties
on the URL http://services.msn.com/svcs/hotmail/httpmail.asp
sending the XML in Listing 1 as payload in the HTTP Request
object. Note that long URLs in the listings are wrapped.
Listing 1. Query Folders PROPFIND payload.
HTTPMAIL: 14:48:03 [tx]
PROPFIND
http://services.msn.com/svcs/hotmail/httpmail.asp
xmlns:D="DAV:"
xmlns:h="http://schemas.microsoft.com/hotmail/"
xmlns:hm="urn:schemas:httpmail:"
The request is then redirected to http://oe.hotmail.com/ where
the server requests an MD5 Digest authentication. Upon
authorization, a cookie is sent back for the authenticated
session and the client is redirected to the URL where the
Users Folders are stored. Finally, the inbox and other
properties from the PROPFIND are returned in the XML format
shown in Listing 2.
Listing 2. Query Folders Response.
HTTPMAIL: 12:08:23 [rx]
HTTP/1.1 304 Not Modified
Server: Microsoft-IIS/5.0
Date: Mon, 30 Sep 2002 17:08:24 GMT
P3P:CP="BUS CUR CONo FIN IVDo ONL OUR PHY SAMo TELo"
Connection: close
Set-Cookie:
X-Dav-Error: 200 No error
HMServer: H: OE17.law4.internal.hotmail.com
V: WIN2K 09.05.50.0030 i
D: Sep 12 2002 19:44:14
xmlns:D="DAV:"
xmlns:m="urn:schemas:mailheader:"
xmlns:hm="urn:schemas:httpmail:"
xmlns:c="urn:schemas:contacts:"
xmlns:h="http://schemas.microsoft.com/hotmail/"
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/
{long value snipped}
http://contacts.msn.com/cgi-bin/
hmdata/{username}@hotmail.com/
abdata/
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/
folders/ACTIVE/
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/
folders/sendmsg/
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/
folders/sAVeD/
http://law4.oe.hotmail.com/
cgi-bin/hmdata/
{username}@hotmail.com/
folders/trAsH/
http://law4.oe.hotmail.com/
cgi-bin/hmdata/
{username}@hotmail.com/
folders/
30
{long value snipped}
HTTP/1.1 200 OK
To get the user's folders, the client requests a PROPFIND of
the URL stored in the msgfolderroot (a DAV collection). The XML
shown in Listing 3 is sent with the request and the response
from Hotmail is shown in Listing 4.
Listing 3. GetFolderInfo PROPFIND payload.
HTTPMAIL: 14:48:04 [tx]
PROPFIND
http://law4.oe.hotmail.com/cgi-bin/hmdata/
{username}@hotmail.com/folders/
xmlns:D="DAV:"
xmlns:hm="urn:schemas:httpmail:"
Listing 4. GetFolderInfo Response.
HTTPMAIL: 14:48:05 [rx]
HTTP/1.1 207 Multi-Status
Server: Microsoft-IIS/5.0
X-Dav-Error: 200 No error
HMServer: H: OE12.law4.internal.hotmail.com
V: WIN2K 09.05.50.0030 i
D: Sep 12 2002 19:44:14
xmlns:D="DAV:"
xmlns:m="urn:schemas:mailheader:"
xmlns:hm="urn:schemas:httpmail:"
xmlns:c="urn:schemas:contacts:"
xmlns:h="http://schemas.microsoft.com/hotmail/"
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
msnpromo/
1
msnpromo
0
1
1
1
msnpromo
HTTP/1.1 200 OK
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
ACTIVE/
1
inbox
0
1
0
0
inbox
HTTP/1.1 200 OK
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
sAVeD/
1
sentitems
0
1
0
4
sentitems
HTTP/1.1 200 OK
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
trAsH/
1
deleteditems
0
1
0
0
deleteditems
HTTP/1.1 200 OK
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
HM_BuLkMail_/
1
Junk Mail
bulkmail
0
1
0
0
bulkmail
HTTP/1.1 200 OK
In the response, we can see the URL's to our mailboxes. The
Inbox is actually named ACTIVE. The full XML for the Inbox with
all its properties is shown in Listing 5.
Listing 5. Full Inbox XML.
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
ACTIVE/
1
inbox
0
1
0
0
inbox
HTTP/1.1 200 OK
So what does this XML tell us? The URL of our Inbox is in the
D:href node, the Display Name of our inbox is in the hm:special
node. The total count of messages that are in the Inbox is in
the D:visiblecount node while the unread message count is in
the m:unreadcount node.
To get message headers the client requests a PROPFIND of each
message folder collection to get the message headers for the
respective folder. In Listing 6, a PROPFIND is sent with the
GetMessageInfo Payload.
Listing 6. GetMessageInfo PROPFIND payload.
HTTPMAIL: 14:55:19 [tx]
PROPFIND
http://law4.oe.hotmail.com/cgi-bin/hmdata/
{username}@hotmail.com/folders/ACTIVE/
xmlns:D="DAV:"
xmlns:hm="urn:schemas:httpmail:"
xmlns:m="urn:schemas:mailheader:"
HTTPMAIL: 12:00:00 [rx]
HTTP/1.1 207 Multi-Status
X-Dav-Error: 200 No error
HMServer: H: OE40.law4.internal.hotmail.com
V: WIN2K 09.05.50.0030 i
D: Dec 9 2003 12:00:00
xmlns:D="DAV:"
xmlns:m="urn:schemas:mailheader:"
xmlns:hm="urn:schemas:httpmail:"
xmlns:c="urn:schemas:contacts:"
xmlns:h="http://schemas.microsoft.com/hotmail/"
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
ACTIVE/MSG1034106929.42
0
Eddie Shipman
testing
2003-04-25T12:00:00
1797
HTTP/1.1 200 OK
The D:href node contains the link to the actual message, the
h:read node let's us know if the message has been read, value
of 0 means the message is unread. Each message's info is
encapsulated in a D:response node in the XML that is returned
from the server. The URL of the message will be used to obtain
the message body. Since I only had one message in my Inbox,
only one D:response node is returned. There are other message
properties in the node as you can see.
To get the message from the server, the client posts a GET with
the URL of the message. The message body and other info are
transmitted in the response stream so we will be able to parse
and display it from there. (see Listing 7)
Listing 7. Get Message body.
HTTPMAIL: 12:00:00 [tx]
GET http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/ACTIVE/
MSG1034106929.42
To mark the message as read, a PROPPATCH is sent to change the
message's read property. (see Listing 8) If multiple messages
are to be marked as read, a BPROPPATCH is sent with the message
hrefs being sent in the target node.
Listing 8. Mark messages Read
(Marking a single message read).
HTTPMAIL: 12:00:00 [tx]
PROPPATCH http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
ACTIVE/MSG1034106929.42
xmlns:D="DAV:"
xmlns:hm="urn:schemas:httpmail:"
1
(Marking multiple messages unread)
HTTPMAIL: 12:00:00 [tx]
BPROPPATCH http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
ACTIVE
xmlns:D="DAV:"
xmlns:hm="urn:schemas:httpmail:"
MSG1034106929.42
MSG1034085513.77
MSG1033688014.245
0
Deleting Messages and Emptying the Trash
To delete messages, a MOVE command is actually sent to move the
message to the deleted items folder (Trash). When deleting
multiple messages, a BMOVE command is sent, see Listing 9. In
either case, the response XML is similar to the XML in Listing
10.
Listing 9. Moving multiple messages (Send to Trash)
{Deleting single messages}
HTTPMAIL: 12:00:00 [tx]
MOVE http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/trAsH/
MSG1032970800.271
{Deleting multiple messages}
HTTPMAIL: 12:00:00 [tx]
BMOVE http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/ACTIVE/
MSG1032970800.271
MSG1033672506.171
MSG1033686142.49
MSG1033688014.245
Listing 10. BMOVE response
HTTPMAIL: 12:00:00 [rx]
HTTP/1.1 207 Multi-Status
Server: Microsoft-IIS/5.0
Date: Wed, 25 Apr 2003 12:00:00 GMT
P3P:CP="BUS CUR CONo FIN IVDo ONL OUR PHY SAMo TELo"
Connection: close
Set-Cookie:
X-Dav-Error: 200 No error
HMServer: H: OE47.law4.internal.hotmail.com
V: WIN2K 09.05.50.0030 i
D: Dec 9 2003 12:00:00
xmlns:D="DAV:"
xmlns:m="urn:schemas:mailheader:"
xmlns:hm="urn:schemas:httpmail:"
xmlns:c="urn:schemas:contacts:"
xmlns:h="http://schemas.microsoft.com/hotmail/"
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
ACTIVE/MSG1032970800.271
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
trAsH/MSG1032970800.271
HTTP/1.1 201 Created
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
ACTIVE MSG1033672506.171
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
trAsH/MSG1033672506.171
HTTP/1.1 201 Created
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
ACTIVE MSG1033686142.49
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
trAsH/MSG1033686142.49
HTTP/1.1 201 Created
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
ACTIVE MSG1033688014.245
http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/
trAsH/MSG1033688014.245
HTTP/1.1 201 Created
In emptying the Trash folder, a BDELETE command is sent and the
list of messages in the folder is sent in the target node;
Listing 11.
Listing 11. Empty Trash Folder (BDELETE)
HTTPMAIL: 12:00:00 [tx]
BDELETE http://law4.oe.hotmail.com/cgi-bin/
hmdata/{username}@hotmail.com/folders/trAsH/
MSG1032970800.271
MSG1033672506.171
MSG1033686142.49
MSG1033688014.245
Conclusion
In this issue, we looked at the basics of how Outlook Express
communicates with Microsoft's Hotmail servers. This was needed
to understand the HTTP traffic that is passed between Hotmail's
servers and application that we will build in the next issue.