Windows Azure Storage APIのベースはREST API なのですが、直接触ったことがなかったのちょっとトライしてみました。試してみたのは、一番簡単なファイルダウンロードというか取得。もちろんPublicコンテナではなく、PrivateコンテナなのでKeyのやりとりをしなくていけません。
API
ファイルをダウンロードするには、的には、以下のURLに書かれているGet Blobを行います。
リクエストはGETで、以下のURLに対して行います。
Method | URI |
---|---|
GET | http://myaccount.blob.core.windows.net/mycontainer/myblob |
いくつか、リクエストヘッダを付けなければいけません。必死なのは、上から3つで、あとは任意です。
Request Header | Description |
---|---|
Authorization | 必須 |
Data or x-ms-date | どちらか必須。こんな形式、Sun, 09 May 2011 22:36:25 GMT |
x-ms-version | 必須。Versioning for the Blob, Queue, and Table services in Windows Azure |
Range | 任意 |
x-ms-range | 任意 |
x-ms-lease-id: |
任意 |
x-ms-range-get-content-md5: true | 任意 |
それらを1つのリクエストとして、Blobに投げてやるとファイルが取得できます。
取得部分
static void Main(string[] args) { // BlobのURI string url = "http://xxx.blob.core.windows.net/hoge/fuga.txt"; var req = (HttpWebRequest)WebRequest.Create(url); // GETする req.Method = "GET"; // 必須ヘッダを付ける req.Headers.Add("x-ms-version", "2009-09-19"); req.Headers.Add("x-ms-date" , DateTime.UtcNow.ToString("R", System.Globalization.CultureInfo.InvariantCulture)); // ヘッダにサインする string authHeader = SignRequest(req); req.Headers.Add("Authorization", "SharedKeyLite " + AccountName + ":" + authHeader); // レスポンスを取得して、コンソールに表示。 try { var res = req.GetResponse(); var con = new System.IO.StreamReader(res.GetResponseStream()).ReadToEnd(); Console.WriteLine(con); } catch (WebException e) { Console.WriteLine(e); Console.WriteLine(((HttpWebResponse)e.Response).StatusDescription); } Console.Write("Press ENTER to exit."); Console.ReadLine(); }
Authorization
Authorizationヘッダを付加しなくてなりませんがコレが面倒くさい。スキーマの説明は以下のURL。
どうやら2つ付加する方法がって、普通の方法と、Liteな方法。
- Shared Key Authentication
- Shared Key Lite Authentication
普通の方法は、以下のヘッダをに対して署名する方法。必須ヘッダでないところは単に改行で構わない。
StringToSign = VERB + "\n" +
Content-Encoding + "\n"
Content-Language + "\n"
Content-Length + "\n"
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
If-Modified-Since + "\n"
If-Match + "\n"
If-None-Match + "\n"
If-Unmodified-Since + "\n"
Range + "\n"
CanonicalizedHeaders +
CanonicalizedResource;
もうちょとわかりやすくすると以下。\nと、/* */によるコメントは実際つかない。任意のヘッダは付けなくてもいいが改行が必要。
GET\n /*HTTP Verb*/
\n /*Content-Encoding*/
\n /*Content-Language*/
\n /*Content-Length*/
\n /*Content-MD5*/
\n /*Content-Type*/
\n /*Date*/
\n /*If-Modified-Since */
\n /*If-Match*/
\n /*If-None-Match*/
\n /*If-Unmodified-Since*/
\n /*Range*/
x-ms-date:Sun, 11 Oct 2009 21:49:13 GMT\n
x-ms-version:2009-09-19\n /*CanonicalizedHeaders*/
/myaccount/myaccount/mycontainered\
ncomp:metadata\n
restype:container\n
timeout:20 /*CanonicalizedResource*/
Liteな方法は以下。署名に必要なヘッダが少なくなっている。
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;
以下、HttpWebRequestを入力して、署名するメソッド。Programming Windows Azure (洋書)を参考にさせていただいた。詳細は原著を当っていただきたい。
static string SignRequest(HttpWebRequest request) { StringBuilder stringToSign = new StringBuilder(); //1行目 Verbを付ける。 GET/PUT/POST stringToSign.Append(request.Method + "\n"); //2行目。Content-MD5 を付ける。任意なので、無ければ改行 stringToSign.Append("\n"); //3行目。Content-Typeを付ける。リクエストから取り出す stringToSign.Append(request.ContentType + "\n"); //4行目 Date。x-ms-dateがあるので、改行だけでかまわない。 stringToSign.Append("\n"); // x-ms で始るも取り出す List<string> httpStorageHeaderNameArray = new List<string>(); foreach (string key in request.Headers.Keys) { if (key.ToLowerInvariant().StartsWith("x-ms", StringComparison.Ordinal)) { httpStorageHeaderNameArray.Add(key.ToLowerInvariant()); } } // ソートする httpStorageHeaderNameArray.Sort(); // key : value の形式 foreach (string key in httpStorageHeaderNameArray) { stringToSign.Append(key + ":" + request.Headers[key] + "\n"); } // 最後に CanonicatlPathを付ける。/アカウント名/リクエストURI stringToSign.Append("/" + AccountName + request.RequestUri.AbsolutePath); // UTF8 => Byte変換 byte[] dataToMAC = System.Text.Encoding.UTF8.GetBytes(stringToSign.ToString()); var skey = Convert.FromBase64String(AccountKey); Console.WriteLine(stringToSign); using (var hmacsha256 = new System.Security.Cryptography.HMACSHA256(skey)) { return Convert.ToBase64String(hmacsha256.ComputeHash(dataToMAC)); } }
実際に、stringToSignには、以下のような値がはいり、それに対して署名が行われます。
GET
x-ms-date:Tue, 05 Apr 2011 14:22:59 GMT
x-ms-version:2009-09-19
/xxx/hoge/fuga.txt
結局は、以下の計算を行って署名を作らなければならないということになります。
Signature=Base64(HMAC-SHA256(UTF8(StringToSign)))
まとめ
REST APIは面倒くさい。.NETな人は、素直にStorage Client Libraryを使った方がよいと思われる。
これをC++でというのは、ちょいとハードル高いのだろうな(ぼそっ)
参考にしたよう洋書はコレ。電子版を安くかいました。
- 作者: Sriram Krishnan
- 出版社/メーカー: Oreilly & Associates Inc
- 発売日: 2010/05/25
- メディア: ペーパーバック
- クリック: 6回
- この商品を含むブログ (1件) を見る
和書は、最近でたこれですかね。
- 作者: Sriram Krishnan,安納順一(監訳),砂金信一郎(監訳),佐藤直樹(監訳),関田文雄(監訳),野村一行(監訳),玉川竜司
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/02/28
- メディア: 大型本
- 購入: 2人 クリック: 27回
- この商品を含むブログ (1件) を見る