Services_Amazon_SQSが、マルチバイトを含むリクエストだと動作しない理由
Services_Amazon_SQSで、マルチバイト文字を含めたデータを送ると、
The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
という、要はこちらが計算して送っているHMACの値と、Amazon側で計算した値が違うのでエラーということで失敗してしまう。
マルチバイトはそもそも送れない?のかと、Amazon側のGetting Started Guideで使っているPHPスクリプトでも試してみると、マルチバイトでも問題なく動いた。
成功するかどうかの違いは、Content-Typeのcharset
いろいろ差分を見ていてわかったのは、リクエスト時のHTTPヘッダのContent-Typeに、application/x-www-form-urlencoded; charset=utf-8
と、charset指定が無いと失敗するということ。
Services_Amazon_SQSを直せるか
答えは否。HTTPリクエストを投げる、HTTP_Reqeust2も修正が必要となり、修正箇所も影響が読めない微妙な感じ。
Services/Amazon/SQS.phpで、Content-Typeを明示的に設定する。
--- SQS.php 2010-01-16 17:39:19.000000000 +0900 +++ SQS.php.new 2010-01-16 17:41:45.000000000 +0900 @@ -287,6 +287,7 @@ $request->setUrl($url); $request->setMethod(HTTP_Request2::METHOD_POST); $request->setHeader('User-Agent', $this->_getUserAgent()); + $request->setHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'); $request->addPostParameter($params); $count = 0;
HTTP/Request2.php で、getBody() の Content-Typeでの条件分岐を、完全一致でなく、前方一致に書き換える。
--- Request2.php.orig 2010-01-15 16:45:18.000000000 +0900 +++ Request2.php 2010-01-16 17:36:03.000000000 +0900 @@ -554,7 +554,7 @@ if (self::METHOD_POST == $this->method && (!empty($this->postParams) || !empty($this->uploads)) ) { - if ('application/x-www-form-urlencoded' == $this->headers['content-type']) { + if (0 === strpos($this->headers['content-type'], 'application/x-www-form-urlencoded')) { $body = http_build_query($this->postParams, '', '&'); if (!$this->getConfig('use_brackets')) { $body = preg_replace('/%5B\d+%5D=/', '=', $body);