ConoHaオブジェクトストレージの静的WEBページ公開機能でイメージギャラリーを作る

#Conoha(OpenStack Swift)の静的WEBページ公開機能　概要
Conohaが使用しているOpenStackのオブジェクトストレージ機能であるSwiftはAmazon S3 互換相当の機能が実装されておりAmazonS3が持っている静的ページ公開機能も実装されています（要するにWEBサーバーとしてファイルを公開できる）。

一時期「**１０円で借りれるレンタルサーバー**」との触れ込みでAmazonが大々的に宣伝してたので知ってる方も多いでしょう。
http://www.awsmicrosite.jp/s3-hosting/

オブジェクトストレージ機能は基本はRESTでファイルをバンバン貯めこんで、RESTでファイルをダウンロードするのですがその手法だとサーバーやクライアントにREST APIをコールする機能を実装する必要があり、またAPI認証キーを埋め込んだりする必要があるため特にクライアントサイドでオブジェクトストレージ機能を利用する時は通常のREST API経由では使いづらい局面が出てきます。（特にスマフォアプリ）

WEB公開機能（OpenStackでは英語で「**static website**」と呼称）があればクライアントアプリに認証キーを埋め込むことなくオブジェクトストレージのファイルを公開できます。
またサーバープログラム（バッチなど）で集めたファイルや、生成したファイルもREST APIを通さずにユーザーに公開できます。

## オブジェクトストレージのメリット

オブジェクトストレージのWEB静的ページ公開のメリットは以下
1. レンタルしているVPSサーバーインスタンスに負荷をかけることなく別インスタンスとしてファイルを公開できる
2. クライアントアプリに認証鍵を埋め込むことなくオブジェクトストレージファイルを公開できる
3. 静的ページのみなのでPHPなどのCGIは動かせないがJSは動かせるのである程度のアプリケーションは構築可能
4. オブジェクトストレージは基本的にファイル保護機能がちゃんとしており（Swiftは1ファイルを3重に保存している）データ保存に向いている
5. VPSがぶっ壊れたり、VPSのOSを変えたくなってもオブジェクトストレージのデータは別領域で動いてるのでマイグレーションが楽
6. サーバーで使うデータを極力オブジェクトストレージに置くことでVPSのデータ領域をスマート化できる。

特に1.の**VPSに負荷をかけることなく別インスタンスとしてファイルを公開できる**というのは魅力的でしょう。
VPSの負荷によって料金が発生したりするサービスであれば特にオブジェクトストレージのメリットが生かせます。

## OpenStack Swiftの静的WEBページ公開機能に関しての資料

* OpenStack本家 http://www.openstack.org/
* OpenStackドキュメント http://docs.openstack.org/
* ObjectStrageリファレンス http://docs.openstack.org/api/openstack-object-storage/1.0/content/
* Create static website http://docs.openstack.org/api/openstack-object-storage/1.0/content/static-website.html

### OpenStack Swiftのサーバー実装コード
SwiftはPythonのWSGIで実装されている。

* Githubレポジトリ　https://github.com/openstack/swift
* 静的ページ部分の実装コード https://github.com/openstack/swift/blob/116ac459a64471b09a5e989e88349c66f470ce38/swift/common/middleware/staticweb.py
* 'X-Web-Mode'で検索した結果 https://github.com/openstack/swift/search?utf8=%E2%9C%93&q=X-Web-Mode
* 'X-Container-Read' で検索した結果  https://github.com/openstack/swift/search?utf8=%E2%9C%93&q=X-Container-Read&type=Code



### その他参考
* Amazon S3 での静的ウェブサイトのホスティング http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/WebsiteHosting.html


## 実際に静的WEBページ公開モードを使用してみる

### 使えるソフト
OpenStackをGUIで操作できるCyberduckや、Conohaのコントロールパネルからは今のところWEB公開モードをONにする機能がありません。
公式のswiftコマンドか、REST APIを自前で叩く必要があります。

### 静的WEBページ公開するのに必要なたった2つの事
オブジェクトストレージを静的WEBページとして公開するために必要な事はたった2つです。
* **対象のコンテナ(ディレクトリ)をPUTする時に’X-Web-Mode: true’のヘッダーをつける**
* **対象のコンテナ(ディレクトリ)をPUTする時に'X-Container-Read: .r:*,.rlistings'のヘッダーをつける**

,.rlistings　はWEBページからファイルをリスティングする機能なので危険だと感じる人はカットしましょう。

要するにX-Web-Mode:trueで対象のコンテナをWEB公開モードにし、X-Container-Read: .r:*,でファイルを認証なしでだれでも読めるようにします。

公式のドキュメントではswiftコマンドでの実例が載っています
http://docs.openstack.org/api/openstack-object-storage/1.0/content/Examples_for_static_web-dle4025.html


## ファイルのリスティング機能について

ファイルのリスティングをONにして実際にConohaのオブジェクトストレージのWEBページにアクセスするとこんな画面になります。
https://objectstore-r1nd1001.cnode.jp/v1/93a6500c0a1e4c68b976e5e46527145c/bgi_sample/
![CBIMGdasda001.png](https://qiita-image-store.s3.amazonaws.com/0/36931/7d6bb979-ee35-aae3-d898-0695e8e48e69.png)

Chrome/FirefoxでアクセスするとXML画面、IEで開くとテキスト画面になります。
何が起きてるかというとコンテナの内容をリスティングするのは同じですが、ブラウザがAcceptするファイル形式でファイル一覧を返しているようです。
https://github.com/openstack/swift/blob/116ac459a64471b09a5e989e88349c66f470ce38/swift/container/server.py#L480
サーバーのコードを見ると(text/xml/json)形式で切り分けている。

なのでアプリケーションでファイルのリスティング機能をつかってディレクトリ画面などを作りたい時はJSON形式で受け取れるようリクエストを投げて結果のJSONをパースするとよいでしょう。

以下はcurlのコード

```
MacBook-Pro:$ curl -v -H 'accept:application/json' https://objectstore-r1nd1001.cnode.jp/v1/93a6500c0a1e4c68b976e5e46527145c/hogehoge/
* About to connect() to objectstore-r1nd1001.cnode.jp port 443 (#0)
* Server certificate:
* subject: OU=Domain Control Validated; CN=*.cnode.jp
* start date: 2014-05-13 05:51:04 GMT
* expire date: 2015-06-30 10:45:47 GMT
* subjectAltName: objectstore-r1nd1001.cnode.jp matched
* issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign Domain Validation CA - G2
* SSL certificate verify ok.
> GET /v1/93a6500c0a1e4c68b976e5e46527145c/hogehoge/ HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5
> Host: objectstore-r1nd1001.cnode.jp
> accept:application/json
>
< HTTP/1.1 200 OK
< Content-Length: 471
< X-Container-Object-Count: 3
< Accept-Ranges: bytes
< X-Container-Meta-Web-Listings-Css: listing.css
< X-Timestamp: 1411233287.36524
< X-Container-Bytes-Used: 563108
< Content-Type: application/json; charset=utf-8
< X-Trans-Id: tx0225201af559492dbfd96-00541e8177
< Date: Sun, 21 Sep 2014 07:42:47 GMT
<
* Connection #0 to host objectstore-r1nd1001.cnode.jp left intact
[{"hash": "cfdb15bb18c3e46ecd839fd6990ebf1f", "last_modified": "2014-09-21T06:05:37.963190", "bytes": 154853, "name": "1.jpg", "content_type": "image/jpeg"}, {"hash": "da6b629c0d05554e788d92d1b268a35a", "last_modified": "2014-09-21T06:10:21.248710", "bytes": 267132, "name": "2.jpg", "content_type": "image/jpeg"}, {"hash": "cd839775aaae6ce13987208b5c1708de", "last_modified": "2014-09-21T06:12:37.863000", "bytes": 141123, "name": "3.jpg", "content_type": "image/jpeg"}]* Closing connection #0
MacBook-Pro:~ Siori$
```

## オブジェクトストレージの静的ページ公開機能をつかって画像ギャラリーサイトを構築してみる


### 画像ギャラリーサイトを構築するためライブラリを落としてくる
静的ページ（JS,CSS)で動的な画像閲覧サイトを構築するためにBootstrap-Image-Galleryをダウンロードします。
https://github.com/blueimp/Bootstrap-Image-Gallery/releases


### HTMLを編集する
基本はBootstrap-Image-GalleryのGithubのREADMEを見ればわかりますが、
Bootstrap-Image-GalleryのREADMEの情報が多少古いのでJSやCSSのバージョンは変更する必要があります。
また、ConohaのオブジェクトストレージサイトはhttpsのためライブラリのJSやCSSもHTTPSのリンクに変更する必要があります。

```html:index.html
<html>
<head>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css">
<link rel="stylesheet" href="http://blueimp.github.io/Gallery/css/blueimp-gallery.min.css">
<link rel="stylesheet" href="css/bootstrap-image-gallery.css">
</head>
<body>
<!-- The Bootstrap Image Gallery lightbox, should be a child element of the document body -->
<div id="blueimp-gallery" class="blueimp-gallery">
    <!-- The container for the modal slides -->
    <div class="slides"></div>
    <!-- Controls for the borderless lightbox -->
    <h3 class="title"></h3>
    <a class="prev">‹</a>
    <a class="next">›</a>
    <a class="close">×</a>
    <a class="play-pause"></a>
    <ol class="indicator"></ol>
    <!-- The modal dialog, which will be used to wrap the lightbox content -->
    <div class="modal fade">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" aria-hidden="true">&times;</button>
                    <h4 class="modal-title"></h4>
                </div>
                <div class="modal-body next"></div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default pull-left prev">
                        <i class="glyphicon glyphicon-chevron-left"></i>
                        Previous
                    </button>
                    <button type="button" class="btn btn-primary next">
                        Next
                        <i class="glyphicon glyphicon-chevron-right"></i>
                    </button>
                </div>
            </div>
        </div>
    </div>
</div>
<div id="links">
    <a href="images/1.JPG" title="1.JPG" data-gallery>
        <img src="images/thumbnails/1.JPG" alt="1.JPG">
    </a>
    <a href="images/2.JPG" title="2.JPG" data-gallery>
        <img src="images/thumbnails/2.JPG" alt="2.JPG">
    </a>
</div>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!-- Bootstrap JS is not required, but included for the responsive demo navigation and button states -->
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>
<script src="http://blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js"></script>
<script src="js/bootstrap-image-gallery.js"></script>

</html>
```

画像のリンクの部分を自分が用意した画像に変えて、ディレクトリに画像を配置する。


### ファイルをWEB公開モードONにしてオブジェクトストレージにアップロードする
用意できたサイトをディレクトリごとオブジェクトストレージにアップロードする。
swiftコマンドを使うか、各種言語のSwiftライブラリを使用してコード書くか、自前でREST APIをコールするアプリケーションを作る。

自前で作ったアプリケーション(chinoコマンド)だとこんな感じでアップロードする
`bundle exec ruby chino.rb -w -s /tmp/bgi_sample -d /`
上記のコマンドで
* オブジェクトストレージのルートフォルダにbgi_sampleをWEB公開モードで作成
* /tmp/bgi_sampleのファイルを全部アップロードする

コードは以下に置いています
https://github.com/AKB428/Chino

### アップロードできているかを確認する
![CBIMGhjjhy002.png](https://qiita-image-store.s3.amazonaws.com/0/36931/a28e56a4-4e12-949b-979a-5a264768e26a.png)

コンテナの直下にbgi_sampleフォルダが作成されました


### サイトを確認する
実際にURLにアクセスしてみます。
https://objectstore-r1nd1001.cnode.jp/v1/93a6500c0a1e4c68b976e5e46527145c/bgi_sample/index.html

![CBIMGhjjhy003.png](https://qiita-image-store.s3.amazonaws.com/0/36931/b3ad8a9f-5114-3f69-c87e-a24cdb37064f.png)

![CBIMGhhh001.png](https://qiita-image-store.s3.amazonaws.com/0/36931/a627df42-5e02-c895-90dc-a5f649c9971e.png)

レスポンシブデザインが効いてるのでCSSもちゃんと読み込めてますし、JSも動きます。

![CBIMGhjjhy001.png](https://qiita-image-store.s3.amazonaws.com/0/36931/8e3021ab-9aea-9dbc-e05c-8e7f3f801da1.png)



以上。