Corredor

ウェブ、プログラミングの勉強メモ。

Oracle Object Storage API を操作する Node.js スクリプトを日本語圏向けに微修正

唐突に Oracle Object Storage の話をする。

オブジェクトストレージとは

Object Storage とは、ファイルを「オブジェクト」という概念で操作できるようにしたアーキテクチャ。

スラッシュ / でディレクトリ風の階層も表現できたりするので、REST API の URL として直接表現しやすかったりする。「ファイル = オブジェクト」と思って良い。

クラウドサービスで見かけることが多く、「Amazon Simple Storage Service (AWS S3)」や「Google Cloud Storage (GCS)」が有名。

Oracle Object Storage Service もこうしたクラウドサービスの中の一つで、Oracle Cloud Infrastracture (IaaS) の中の1機能として使える。

Oracle Object Storage API

で、この Oracle Object Storage だが、REST API 経由でファイルを取得したり保存したりできる。

REST API でやり取りするためにはリクエストヘッダに署名を設定したりする必要があるのだが、コチラは各種言語でのサンプルコードが以下に載っている。

Node.js 版のサンプルコードは以下のハッシュ。

コレで通信時の基礎を作っておき、あとは Object Storage API をコールするように URL パスやリクエストボディなんかを設定して使えば良い、というモノだ。

今回の趣旨は、このコードの整理と、日本語圏で問題になるバグを見つけたので、それを修正して使いやすくする、というところ。

サンプルコードのバグ

Node.js 版のサンプルコードのみであれば、以下のいずれかの URL で確認できる。

Version 1.0.1 となっていて、普通に使っているとほとんど問題なかったのだが、日本語を含むファイルを PUT した時に、ファイルの末尾数文字が欠落するというバグがあった。

原因は、51行目の以下の部分。

request.setHeader("Content-Length", options.body.length);

察しの良い方はもう分かるだろう。少し前にココ単体で記事にしたのだが、String.length で文字列の長さを求めて Content-Length ヘッダに設定しているのが問題。日本語のようなマルチバイトも「1文字」とカウントしてしまい、「2バイト」ないしは「3バイト」とカウントしていないせいで、全角の文字数分だけのバイト数、ファイルの末尾が千切れる事態になった。

ということで、この行を次のように直すと、日本語を含むファイルを送信しても大丈夫になる。

request.setHeader('Content-Length', Buffer.byteLength(options.body, 'utf8'));

ココだけ直して、それ以外はサンプルコードを見れば使えます、という人は、この先は見なくても良い。

サンプルコードを Promise 化して使いやすくしてみた

このサンプルコードはコールバック形式で書きづらいので、Promise として呼べるように加工してみた。

詳しくは以下の Gist を参照のこと。

元のサンプルコードからそうだが、http-signaturejssha というライブラリが必要なので npm install すること。

oracle-cloud-rest-api-wrapper.js はイジらず、settings.js の設定情報を変更し、examples.js のように利用すれば OK、という流れ。

主に Object Storage のコールのために作ったが、呼び方を変えれば getUser() のようにユーザ情報なんかも拾えたりする。どんな API があるのかは以下を参照。

以上

さすがは米国企業、body.length でおっけーしょ、というノリ。マルチバイトが当たり前な国の人のことも考えたってください…。

Openstack Object Storage Swift Essentials

Openstack Object Storage Swift Essentials

Object storage A Complete Guide - 2019 Edition (English Edition)

Object storage A Complete Guide - 2019 Edition (English Edition)