The advantage of POP mail protocol is that it is an open standard and has a complete documentation, which enables POP Mail customers to write Program It is not that difficult. As long as you have mastered the basic knowledge of pop and SMTP, you can write a proxy program to execute various tasks, such as filtering advertisements and spam, or providing the automatic response service of e-mail.
Hotmail is the most influential web mail system in the world. Unfortunately, when we want to write an independent client program for Hotmail (a client program that is not accessed through a browser, hotmail does not provide pop gateway.
Although Hotmail does not support pop, browsers are not the only way to access Hotmail. For example, Outlook Express can be used to directly connect to a standard Hotmail or MSN mailbox to extract, delete, move, or send emails. Using the HTTP packet monitor, we can monitor the communication process between Outlook Express and Hotmail, and analyze how the client program connects to the Hotmail mailbox.
Outlook Express uses an undisclosed protocol, usually called httpmail, to access Hotmail with a set of HTTP/1.1 extensions. This article introduces some features of httpmail and the process of using C # client program to access Hotmail. The example program in this article uses com interoperation to use XMLHTTP as a transmission service. The XMLHTTP component provides a complete HTTP implementation. In addition to the authentication function, it can also set custom HTTP headers before sending HTTP requests to the server.
1. Connect to httpmail Gateway
The default httpmail gateway for Hotmail is http://services.msn.com/svcs/hotmail/httpmail.asp. Httpmail is actually a standard WebDAV service, but it has not been published yet. When compiling a C # program, we can conveniently call the various TCP and HTTP classes provided by the. NET Framework in the system. Net namespace. In addition, because we want to operate WebDAV, it is easiest to connect to Hotmail using XMLHTTP in the C # environment. You only need to reference the msxml2 component for direct access. Note thatCodeIn the snippet, variables with the suffix of the slide line are the member fields declared in the sample code:
// Obtain the namespace using msxml2;... // create the object XMLHTTP _ = new XMLHTTP (); |
To connect to the security server, the WebDAV protocol requires HTTP/1.1 verification. The first request sent by the httpmail client program uses the WebDAV PROPFIND method to find a set of attributes, including the URL of the Hotmail advertisement bar and the location of the mailbox Folder:
<? XML version = "1.0"?> <D: propfind xmlns: D = "Dav:" xmlns: H = "http://schemas.microsoft.com/hotmail/" xmlns: Hm = "urn: schemas: httpmail:"> <D: prop> |
When sending the first request via XMLHTTP, first specify the WebDAV server URL and then generate the content of the XML request:
// Specify the server URL string serverurl = "http://services.msn.com/svcs/hotmail/httpmail.asp"; // construct the query string folderquery = NULL; folderquery + = "<? XML version = '1. 0'?> <D: propfind xmlns: D = 'dav: '"; folderquery + =" xmlns: H = 'HTTP: // schemas.microsoft.com/hotmail/' "; folderquery + =" xmlns: hm = 'urn: schemas: httpmail: '> <D: prop> |
The XMLHTTP component provides an open () method to establish a connection with the HTTP server:
Void open (string method, string URL, bool async, string user, string password ); |
The first parameter of the open () method specifies the HTTP method used to open the connection, such as get, post, put, or PROPFIND, through these HTTP methods, we can extract Folder Information, collect emails, or send new emails. To connect to the Hotmail gateway, we specify the PROPFIND method to query the mailbox. Note that the open () method allows asynchronous calling (enabled by default). asynchronous calling is the most ideal method for email client programs with graphical user interfaces. Since the sample program in this article is a console application, we set this parameter to false.
To perform identity authentication, we specify the username and password in the open () method. When using the XMLHTTP component, if the open () method does not provide the username and password parameters, but the website requires authentication, XMLHTTP will display a logon window. To open the connection to the Hotmail gateway, we set the header of the PROPFIND request to the content of the XML query. The message body is left blank and the message is sent:
// Open a connection to the Hotmail server XMLHTTP _. open ("PROPFIND", serverurl, false, username, password); // send the request XMLHTTP _. setRequestHeader ("PROPFIND", folderquery); XMLHTTP _. send (null ); |
2. Analyze the folder list in the mailbox
Requests sent to services.msn.com usually undergo several redirection requests. After server load balancing, the requests are finally transmitted to an idle Hotmail server for authentication. On the client side, the interaction process for redirection and authentication is handled by the XMLHTTP component. After a connection is established, the server also requires setting cookies to verify the validity of the current session. This work is also automatically handled by the XMLHTTP component. After an initial connection request is sent, the server returns an XML response:
// Obtain the response content string folderlist = XMLHTTP _. responsetext; |
the response returned by the server contains many useful information, including the URL location of the folder in the mailbox. The following is an example:
...
adpane = off *...
http://law15.oe.hotmail.com /...
http://law15.oe.hotmail.com /...
http://law15.oe.hotmail.com /...
http://law15.oe.hotmail.com /...
http://law15.oe.hotmail.com /...
http://law15.oe.hotmail.com /...
...
|
In the console sample program in this article, the two folders we are interested in are the inbox and the sender folder, which are used to receive and send mails respectively.
There are many ways to parse XML in the C # environment. Because we are sure that all the XML documents involved in the Code are always legal, we can take advantage of the fast speed of system. xml. xmltextreader. Xmltextreader is a "Forward-only" Reader. The XML character data is converted into a forward stream to initialize the XML reader:
// Initialize inboxurl _ = NULL; sendurl _ = NULL; // load XML stringreader reader = new stringreader (folderlist); xmltextreader xml = new xmltextreader (Reader ); |
Traverse each node and select the HM: inbox and HM: sendmsg nodes, which represent the inbox and the sender respectively:
// Read XML data while (XML. Read () {// is an XML element? If (XML. nodetype = xmlnodetype. element) {// obtain the node string name = xml. Name; // does the node represent the inbox? If (name = "Hm: inbox") {// Save the inbox url xml. Read (); inboxurl _ = xml. value;} // does this node represent the sender? If (name = "Hm: sendmsg") {// Save the sending url xml. Read (); sendurl _ = xml. Value ;}}} |
You can send and receive emails only by obtaining the valid inbox and sending URL of the current session.
Iii. List folder content
After obtaining the URL of the mailbox folder (such as Inbox), you can send a WebDAV request to the URL of the folder to list its content. The example program defines a managed mailitem to save the information of a content (that is, a mail) in the folder. Folder content listing starts from initializing a mailitems array:
// Initialize arraylist mailitems = new arraylist (); |
To obtain basic mail information such as the subject, recipient address, and sender address, we need to use the following XML WebDAV query:
<? XML version = "1.0"?> <D: propfind xmlns: D = "Dav:" xmlns: Hm = "urn: schemas: httpmail:" xmlns: M = "urn: schemas: mailheader:"> <D: prop> <D: isfolder/> <HM: Read/> <m: hasattachment/> <m: To/> <m: From/> <m: subject/> <m: Date/> <D: getcontentlength/> </D: prop> </D: propfind> |
Generate the C # code of the preceding XML query string:
// Construct the query string getmailquery = NULL; getmailquery + = "<? XML version = '1. 0'?> <D: propfind xmlns: D = 'dav: '"; getmailquery + =" xmlns: Hm = 'urn: schemas: httpmail:' "; getmailquery + =" xmlns: M = 'urn: schemas: mailheader: '> <D: prop> <D: isfolder/> "; getmailquery + =" <HM: Read/> <m: hasattachment/> <m: To/> <m: From/> <m: Subject/> "; getmailquery + =" <m: Date/> <D: getcontentlength/> </D: prop> </D: propfind> "; |
Like the previous method for obtaining the mailbox folder list, the above request is also sent via XMLHTTP using the PROPFIND method. This time, we set the Request body to a query string. Because the user identity of the current session has been verified, you do not need to provide the username and password in the XMLHTTP open () call:
// Obtain the mail Information XMLHTTP _. Open ("PROPFIND", folderurl, false, null, null); XMLHTTP _. Send (getmailquery); string folderinfo = XMLHTTP _. responsetext; |
If the request is successful, the XML response stream returned by the server contains information about each email in the folder:
<D: multistatus> <D: Response> <D: href> http://sea1.oe.hotmail.com/cgi-bin/hmdata... </D: href> <D: propstat> <D: prop> <HM: Read> 1 </HM: Read> <m: To/> <m: from> Mark Anderson </M: From> <m: Subject> re: New Information </M: Subject> <m: Date> 2002-08-06t16: 38: 39 </m: date> <D: getcontentlength> 1238 </D: getcontentlength> </D: prop> <D: Status> HTTP/1.1 200 OK </D: Status> </D: propstat> </D: Response>... |
Observe the response returned by the server. We find that each node contains a group of domains that identify the email. For example, you can mark and extract the email. Next, we will use system. xml. xmltextreader to parse the XML data stream again. First, initialize the stream reader:
Mailitem = NULL; // load XML stringreader reader = new stringreader (folderinfo); xmltextreader xml = new xmltextreader (Reader ); |
4. analyze basic email information
In order to parse the entire XML document once, we create a new mailitem instance every time an element is opened, and the instance is saved at the end of the tag. During this period, we extract and set the mailitem domain:
// read XML data while (XML. read () {string name = xml. name; xmlnodetype nodetype = xml. nodetype; // is an email? If (name = "D: Response") {// start? If (nodetype = xmlnodetype. element) {// create a new mailitem = new mailitem () ;}// end? If (nodetype = xmlnodetype. endelement) {// save email mailitems. Add (mailitem); // clear the variable mailitem = NULL;} // is an element? If (nodetype = xmlnodetype. element) {// URL attribute of the email if (name = "D: href") {// continue to read XML. read (); mailitem. url = xml. value;} // The "read" attribute of the email if (name = "Hm: Read") {// continue to read XML. read (); mailitem. isread = (XML. value = "1");} // attributes of other mailitems ...}} |
The code above enumerates every mailitem in the specified folder and extracts the following attributes of each mailitem:
XML node description D: href is used to extract the mail url hm: read if the mail has been read, the mark is set to M: to recipient M: from sender M: Subject mail subject M: date time Mark D: size of the getcontentlength message (number of bytes) |
5. receive emails
After you enumerate the mailitem in the folder, you can use the mailitem URL to obtain the email itself. You only need to send an HTTP/1.1 GET request to the Hotmail server. In the loadmail () function in the sample code, enter a mailitem instance as the parameter and return the mail content:
/// <Summary> /// download the email specified by mailitem /// </Summary> Public String loadmail (mailitem) {// the URL of the email string mailurl = mailitem. URL; // open the Hotmail server to connect to XMLHTTP _. open ("get", mailurl, false, null, null); // send the XMLHTTP _. send (null); // obtain the response string maildata = XMLHTTP _. responsetext; // return mail data return maildata ;} |
6. send an email
The loadmail () method gets an email by sending an HTTP/1.1 GET request. Similarly, when using Hotmail to send an email, we submit a POST request, as shown in the sendmail () method below.
/// <Summary> /// send an email /// </Summary> Public void Sendmail (string from, string fromname, string to, string subject, string body) {...} |
First, prepare the quotation marks and the time mark of the email:
// Quote string quote = "\ u0022"; // time mark datetime now = datetime. now; string timestamp = now. tostring ("DDD, DD Mmm yyyy hh: mm: SS "); |
Httpmail uses a communication mode similar to SMTP. Outlook Express uses the MIME format to send emails. In this example, only plain text emails are sent:
// Construct the POST request content string postbody = NULL; // mail header. postbody + = "mail from: <" + from + "> \ r \ n"; postbody + = "rcpt to: <" + to + "> \ r \ n "; postbody + = "\ r \ n"; postbody + = "from:" + quote + fromname + quote + "<" + from + "> \ r \ n "; postbody + = "to: <" + to + "> \ r \ n"; postbody + = "Subject:" + Subject + "\ r \ n "; postbody + = "Date:" + timestamp + "-0000 \ n"; postbody + = "\ r \ n"; // mail body postbody + = body; |
When sending an email, we need to set the Content-Type request header to message/rfc821, indicating that the request contains a message following rfc821. The last thing to do is to send the email to the server:
// Open the XMLHTTP _. open ("Post", sendurl _, false, null, null); // send the request XMLHTTP _. setRequestHeader ("Content-Type", "message/rfc821"); XMLHTTP _. send (postbody ); |
As long as the target address is correct, Hotmail will send the email to the destination.
Conclusion:
Hotmail is the world's largest free web mail provider. However, the httpmail protocol used by Hotmail is not public, which makes it difficult to write client programs that directly access Hotmail. This article demonstrates how to use the XMLHTTP component to directly connect to Hotmail in the C # environment, and how to send and receive emails, it proves that using httpmail to connect to Hotmail is as simple as using POP3, IMAP4, SMTP, and other protocols.