Hotmail解析結果

1999年10月30日 とよしま

概容

hotmailをweb以外から利用する場合、特殊な方法を用いる事で効率的にメールデータにアクセスできる。本稿はhotmailをPOP3対応の通常のメーラーから読むために開発予定のPOP3 to Web-Mail Gateway開発のために書かれた。また、この資料を作成するにあたり、Outlook Expressの通信内容を参考にした。


プロトコル

hotmailで使用されるプロトコルは、HTTP/1.1をベースに、若干独自拡張を施したものである。また、認証にはDigest認証を用いるので、これに対応していなければならない。独自拡張は主に、リクエストコマンドの追加と、レスポンスステータスの追加である。これらについては次に説明を示す。Digest認証についてはrfc-2617を参考の事。また、本来Digest認証はHTTP/1.1の元に実装されるべきであるが、HTTP/1.0上に実装してもhotmailを利用するにあたって問題は確認されていない。また、User-AgentはOutlook Expressを名乗る必要がある、ということに注意しなければならない。

 

追加されたリクエストコマンド

コマンド

解説

PROPFIND

Login中のユーザーに属する、各種データにアクセスするためのURLと付随情報を調査する。どのデータに関して調査するかはcontentとして送信されるXMLに記述される。このコマンドは複数の要求を同時に発行することができるようになっている。

PROPPATCH

Login中のユーザーに属する各データ固有の情報を変更する。主にメールの未読フラグの変更等に利用される。

MOVE

階層化されている各データを別階層に移動する。主にメールをごみ箱へ移動させる等に利用される。

 

追加されたレスポンスステータス

コード

解説

207 Multi-Status

PROPFINDに対する応答として返す。要求ごとのレスポンスとステータスを要求だけ列挙したものをXMLとして返答してくる。

 


サーバーへのアクセス

hotmailへの入り口となるURLはhttp://services.msn.com/svcs/hotmail/httpmail.asp となっている。ただし、通常このアドレスは301/302等を返してくるので、Locationに従って再度別サーバーにアクセスすることになるはずである。移動後のアドレスは常に変更される可能性があるため、アクセス時には必ずこのアドレスから調べるべきである。

 

ログイン

ログインを開始するためには上で示したURLへPROPFINDを送信する必要がある。正しいアドレスにアクセスすると、401を返してくる。この際要求される認証がDigest認証となっている。クライアントはユーザー名、パスワードに従いDigestを計算し、それらを含め、再度サーバーにPROPFINDとして送る。このレスポンスとして207が返って来たならログインは成功である。PROPFINDとして送るデータは取得したい情報をXMLで列挙したものである。次に代表的な送信内容の例を示す。

 

<?xml version="1.0"?>

<D:propfind xmlns:D="DAV:" xmlns:h="http://schemas.microsoft.com/hotmail/" xmlns:hm="urn:schemas:httpmail:">

     <D:prop>

         <h:adbar/>

         <hm:contacts/>

         <hm:inbox/>

         <hm:outbox/>

         <hm:sendmsg/>

         <hm:sentitems/>

         <hm:deleteditems/>

         <hm:drafts/>

         <hm:msgfolderroot/>

         <h:sig/>

     </D:prop>

</D:propfind>

 

D:propの内側にあるのが要求する情報の列挙となっている。レスポンスは以下の通り。

 

<?xml version="1.0" encoding="windows-1252"?>

<D:multistatus 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/">

     <D:response>

         <D:href>http:///</D:href>

         <D:propstat>

              <D:prop>

                   <hm:contacts>http:///abdata/</hm:contacts>

                   <hm:inbox>http:///folders/ACTIVE/</hm:inbox>

                   <hm:sendmsg>http:///sendmsg/</hm:sendmsg>

                   <hm:sentitems>http:///folders/sAVeD/</hm:sentitems>

                   <hm:deleteditems>http:///folders/trAsH/</hm:deleteditems>

                   <hm:msgfolderroot>http:///folders/</hm:msgfolderroot>

                   <h:sig>______________________________________________________

Get Your Private, Free Email at http://www.hotmail.com

</h:sig>

              </D:prop>

              <D:status>HTTP/1.1 200 OK</D:status>

         </D:propstat>

     </D:response>

</D:multistatus>

 

要求に対応したURLを応答してくる。以下の操作はここで得た各URLに対してPROPFINDを送信することで行う。また、ログイン時にはリクエストヘッダに「Depth: 0」と「Brief: t」を付加しておく必要がある。

 

フォルダ情報の問い合わせ

ログイン時に得たURLに対してPROPFINDを送信することで任意の階層のデータが取り出せる。

リクエストの例は次の通り。

 

<?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>

 

レスポンスの例は次の通り。

 

<?xml version="1.0" encoding="windows-1252"?>

<D:multistatus 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/">

     <D:response>

         <D:href>http:///folders/ACTIVE/MSGxxxxxxxxx</D:href>

         <D:propstat>

              <D:prop>

                   <hm:read>0</hm:read>

                   <m:to></m:to>

                   <m:from>=?iso-2022-jp?B?SG90bWFpbCAbJEIlQSE8JWAwbEYxGyhC?=</m:from>

                   <m:subject>=?iso-2022-jp?B?SG90bWFpbCAbJEIkWCRoJCYkMyQ9GyhCIQ==?=</m:subject>

                   <m:date>1999-10-30T03:14:25</m:date>

                   <D:getcontentlength>233</D:getcontentlength>

              </D:prop>

              <D:status>HTTP/1.1 200 OK</D:status>

         </D:propstat>

     </D:response>

</D:multistatus>

 

この通信で、inboxには1つのメールがあったため、そのメールヘッダ情報がやりとりとされている。複数メールがある場合には、D:responseが複数列挙される事になる。また、フォルダ情報取得時にはヘッダに「Brief: t」と「Depth: 1,noroot」を付ける必要がある。

 

メールの読み出し

上記の手順でフォルダの情報を取得することで、各メールを取り出すためのURL(http://…/folders/ACTIVE/MSGxxxxxxxxx)が得られる。このアドレスに対してGETコマンドを送る事でメールを受信できる。また、このURLはユニークになっているので、そのままUIDLとして使用できる。次にGETのリクエストの例を示す。GETにはコンテントはないのでヘッダを掲載する。これはPROPFIND等を行うときも同様であり、合わせてサンプルとする。

 

GET /cgi-bin/hmdata/folders/ACTIVE/MSGxxxxxxxxx HTTP/1.1

Accept: message/rfc822, */*

Translate: f

User-Agent: Outlook Express/5.0 (MSIE 5.0; Windows 98; DigExt)

Proxy-Connection: Keep-Alive

Pragma: no-cache

Authorization: Digest username="mai__kawasumi@hotmail.com", realm="hotmail.com", qop="auth", algorithm="MD5", uri="/cgi-bin/hmdata/folders/ACTIVE/MSGxxxxxxxxx", nonce="OTQxMjUzMzcxOjcyNDZiMTVlOTFiOGFlZTUyNGE0ODRkZDBlNmNjNzdl", nc=00000004, cnonce="833a03c26c473879455249498ee51dbe", response="7d2cf965ea54b028ffb6a076e16c3287"

 

 

このリクエストに対するレスポンスの例は次の通り。

 

HTTP/1.1 200 OK

Date: Sat, 30 Oct 1999 03:16:53 GMT

Server: Apache/1.3.6 (Unix) mod_ssl/2.2.8 SSLeay/0.9.0b

Cache-Control: no-cache

Expires: Mon, 01 Jan 1999 00:00:00 GMT

Pragma: no-cache

Connection: close

Content-Type: message/rfc822

 

From: =?iso-2022-jp?B?SG90bWFpbCAbJEIlQSE8JWAwbEYxGyhC?=

Subject: =?iso-2022-jp?B?SG90bWFpbCAbJEIkWCRoJCYkMyQ9GyhCIQ==?=

Date: Sat, 30 Oct 1999 03:14:25 +0000

Mime-Version: 1.0

Content-Type: text/plain; charset=iso-2022-jp

 

$B?7$7$$%f!<%6!<$N3'MM$X(J

 

MSN Hotmail $B$X$h$&$3$=!#(JMSN Hotmail $B$O!"%$%s%?!<%M%C%H$G:G$b5^B.$K@.D9$7$F$$$k%3%_%e%K%F%#$G$9!#(J

 

$B%F%-%9%HI=<($N%V%i%&%6$G$O!"(JMSN Hotmail $B$N0lIt$N5!G=$,MxMQ$G$-$^$;$s!#(JMSN Hotmail $B$r;H$&$H!"$[$+$N(J Web $B%Z!<%8$X$N%j%s%/$d2hA|$J$I!"K-IY$JFbMF$r4^$`EE;R%a!<%k$r$d$j$H$j$9$k$3$H$,$G$-$^$9!#(J 

 

$B$<$R!"2hA|$KBP1~$7$?%V%i%&%6$G(J MSN Hotmail $B$r$*3Z$7$_$/$@$5$$!#(J

MSN Hotmail $B%9%?%C%U(J

 

 

メールを既読にする

通常受けたばかりのメールは未読状態になっている。これを既読状態にするためにはメッセージに対応するURLに対して、PROPPATCHコマンドを送信する必要がある。この時ヘッダには「Brief: t」が必要であることに注意する。成功時には200が返る。

 

<?xml version="1.0"?>

<D:propertyupdate xmlns:D="DAV:" xmlns:hm="urn:schemas:httpmail:">

     <D:set>

         <D:prop>

              <hm:read>1</hm:read>

         </D:prop>

     </D:set>

</D:propertyupdate>

 

メールをごみ箱へ移動する

読み終わったメールをごみ箱へ移動するためには、メッセージに対応するURLに対して、MOVEコマンドを送信する必要がある。この時、フォルダ情報の問い合わせ時に返ってきたごみ箱のアドレスが必要になる。以下、MOVEコマンドで、特殊な部分を上げて解説する。

 

MOVE //folders/ACTIVE/MSGxxxxxxxxx HTTP/1.1

Destination: http:///folders/trAsH/MSGxxxxxxxxx

Allow-Rename: t

Content-Length: 0

.

.

.

 

Destinationには移動先でのURLを指定する必要がある。このURLはフォルダ情報の問い合わせ結果として得られたものに、メッセージの名前(MSGxxxxxxxxx)を加えたものである。また、「Allow-Rename」に「t」を指定しておけば、移動後の名前が衝突していても、自動的に最適な名前に変更してくれるものと思われる(未確認)。レスポンスとしては以下のようなものが返ってくる。

 

HTTP/1.1 201 Created

Date: Sat, 30 Oct 1999 03:17:16 GMT

Server: Apache/1.3.6 (Unix) mod_ssl/2.2.8 SSLeay/0.9.0b

Cache-Control: no-cache

Expires: Mon, 01 Jan 1999 00:00:00 GMT

Pragma: no-cache

Location: http:///folders/trAsH/MSGxxxxxxxxx

Connection: close

Content-Type: text/html; charset=shift_jis

 

<!-- IP: xxx.xxx.xxx.xxx -->

<!-- V: 08.05.10.0008 -->

<!-- D: Thu Oct 14 16:00:25 PDT 1999 -->

 

ステータスは201で、Locationに移動後のURLが入っていることに注意する。


参考

RFC1945 -- Hypertext Transfer Protocol – HTTP/1.0

RFC2616 -- Hypertext Transfer Protocol – HTTP/1.1

RFC1321 -- The MD5 Message-Digest Algorithm

RFC2617 -- HTTP authentication: Basic and Digest Access Authentication