クエリが上手くいかん。遺憾・・・。

AWSのクエリに関するメモ。

どうもナニカをカン違いしているようです。というわけで、仕様見直し。

Query API Authenticationのテキトー訳

http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/using-query-api.html

クエリリクエストをHTTP or HTTPS越しに送信できます。どのプロトコルを利用するかにかかわらず、すべてのクエリリクエストにシグネチャを含めなければなりません。このセクションではシグネチャの作成方法を説明します。次の手順で説明するメソッドは、シグネチャバージョン2として知られています。

Caution
現在シグネチャバージョン1を使っている場合: バージョン1は廃止予定であるため、すぐにシグネチャバージョン2に移行すべきです。廃止の計画に関する情報とシグネチャ2と1の違いについては、Making Secure Requests to Amazon Web Servicesのページを参照してください。
To create the signature
  1. この手順の中で必要となるクエリ文字列を、整形します。
    1. UTF-8クエリ文字列コンポーネントをパラメタnameのnatural byte順にソートします。パラメタはGET URI、あるいは、(Content-Typeがapplication/x-www-form-urlencodedの場合は)POST bodyからもたらされます。
    2. パラメタnameとvalueを、次のルールに従ってURLエンコーディングします。
      • RFC3986で定義されたunreserved charactersは、どれもURLエンコードしてはいけません。これらのunreserved charactersとは、A-Z、a-z、0-9、ハイフン、アンダースコア、ピリオド、チルダです。
      • すべての他の文字を、%XY形式でエンコーディングします。ここで、XとYは、16進の0-9と大文字のA-Fです。
      • パーセントエンコードは、UTF-8文字を%XY%ZA形式に拡張します。
      • パーセントエンコードでは、スペース文字を%20とします。(標準のエンコードスキーマであるような+にはしません)
      • :Note:現在、すべてのAWSサービスのパラメタnameは、unreserved charactersを使用しています。そのため、あなたはこれらをエンコードしません。しかし、reserved charactersを使用したパラメタnameを扱うコードが欲しくなるかもしれませんし、将来使えるようになるかもしれません。
    3. エンコードしたパラメータnameとvalueは、=(ASCII character 61)で区切ります。パラメタvalueが空であっても同様です。
    4. nameとvalueの組は、&(ASCII code 38)で区切ります。
  2. 署名文字列を、次の擬似文法に従って作成します(「\n」はASCIIで改行を意味します)。HTTPRequestURIコンポーネントは、URIに沿ったHTTPの絶対パスコンポーネントですが、クエリ文字列を含みません。HTTPRequestURIが空の場合、スラッシュを前に利用します。
  3. 作成した文字列で、REC2104で規定されたHMACを計算します。キーにはSecret Access Keyを、ハッシュアルゴリズムとしてSHA256かSHA1を使用します。詳細情報はhttp://www.ietf.org/rfc/rfc2104.txtを参照してください。
  4. base64に結果の値を変換します。
  5. シグネチャリクエストパラメタとして、結果の値を利用します。
StringToSign = HTTPVerb + "\n" +
               ValueOfHostHeaderInLowercase + "\n" +
               HTTPRequestURI + "\n" +         
               CanonicalizedQueryString <from the preceding step>
Important
リクエストで送信する最終的なシグネチャは、RFC3986どおりURLエンコードされなければなりません(詳細はhttp://www.ietf.org/rfc/rfc3986.txtを参照)。利用しているツールキットが、最終的なリクエストをURLエンコードするのであれば、シグネチャのURLエンコーディングの要件はよろしく扱われます。ツールキットが、最終的なリクエストをURLエンコードをしないのであれば、リクエストに含める前にシグネチャをURLエンコードしなければなりません。最も重要なのは、シグネチャが一度だけURLエンコードされることです。よくある間違いは、シグネチャ情報を手動でURLエンコードし、ツールキットがリクエスト全体を再度エンコードすることです。

メモ

パラメタ保持

クエリのパラメタnameとvalueを保持するために、AWS SDK for JavaはTreeMapを使っています。これだとイテレータもソートも楽チンですよね。

JavaScriptにはTreeMapがないようなので、連想配列を使うことにしました。

連想配列のループ方法や、keyで要素をソートする方法を把握しました。

URIをどう扱うか

java.net.URIのようなのが欲しいので、これに縋ることに。