Mega Code Archive

 
Categories / Delphi / Ide Indy
 

Hotmail Delphi Style! (Part 13)

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.