Base64エンコードの画像をPOSTしようとしてはまる

In: Ruby / Rails| technology

17 11月 2011

久しぶりにRubyを使いまして。
API経由でBase64エンコードした画像をPOSTしようとしたら、いろいろとはまったのでメモ。


まずは、単純にBase64エンコードしようとした場合。

require 'base64'
Base64.encode64("abcdareijgtgue84520-2klkfurieare131243fdvm\555cdagjgisotgbvfxma")

戻ってくる値は、こんな感じ。

YWJjZGFyZWlqZ3RndWU4NDUyMC0ya2xrZnVyaWVhcmUxMzEyNDNmZHZtbWNk\n
YWdqZ2lzb3RnYnZmeG1h\n

わかりやすくするために、便宜的に入れてみましたが、60文字に1回と文字列の最後に”\n”が挿入されてきます。
画像のエンコード目的なので、こうした文字列が入り込んでくるのは歓迎できません。以下のような形で対応します。

# ruby 1.9 以上で利用可
Base64.strict_encode64("abcdareijgtgue84520-2klkfurieare131243fdvm\555cdagjgisotgbvfxma")
# ruby 1.8 系だったらこちら
Base64.encode64("abcdareijgtgue84520-2klkfurieare131243fdvm\555cdagjgisotgbvfxma").split().join()

こうすると”\n”はきれいさっぱりなくなります。

YWJjZGFyZWlqZ3RndWU4NDUyMC0ya2xrZnVyaWVhcmUxMzEyNDNmZHZtbWNkYWdqZ2lzb3RnYnZmeG1h

strict_encode64は、rubyのバージョンが古いと使えないので気をつけましょう。

さてさて、これであとはPOSTするばかり、と思ったらそんなことはなく。
POSTはできるものの、画像はうまくエンコードされずに壊れた画像が上がってきます。
いろいろ調べてみると、POSTする前と後ではこんな形で違っていたせい。

前)

YWJjZGFyZWlqZ+3RndWU4NDUyM+C0ya2xrZnVyaWVhcmUxMzEy++NDNmZHZtbWNkYWdqZ2lzb3+RnYnZmeG1h

後)

YWJjZGFyZWlqZ 3RndWU4NDUyM C0ya2xrZnVyaWVhcmUxMzEy  NDNmZHZtbWNkYWdqZ2lzb3 RnYnZmeG1h

POSTの際、requestのbodyに突っ込むと、”+” の文字がエスケープされてしまいます。
なので、こんなときはCGI.escapeを使ってあげればよろしい。

require 'cgi'
require 'base64'
CGI.escape(Base64.encode64("abcdareijgtgue84520-2klkfurieare131243fdvm\555cdagjgisotgbvfxma").split().join())

ここで、URI.escapeを使うと、URIとして使える記号(今回は”+”がそれに当たりますね)はそのままになってしまうので、そのままリクエストを投げてしまうと、違う意味で受け取られてしまいます。
対して、CGI.escapeだったら、記号も全部書き換えてくれるので、きちんとリクエストとして投げられるということになります。

Via:


Comment Form

About this blog

ゆるーく、ふわーっと、興味のままに。

自分のかたわらに置いておくメモ代わり。

Photostream