Googleドライブを静的サイトサーバとして利用する

# 0.やりたいこと
自サーバにはphpファイル1個のみを置く。
`file_get_contents(Googleドライブにアップしたhtmlファイル)`をやることで、
あたかもコンテンツを持ったサーバであるかのように扱いたい。
これができると、パソコンやスマホなどから容易にページが更新できて便利だ(ftp接続が要らない)。

# 1.課題
普通にhtmlファイルをアップしてGoogleドライブの画面から素直にリンクを取得しても、うまくいかない。2つ工夫する必要がある。
## 1-1. 課題1つ目
1つは、「Googleドライブ専用の画面」が開き、その内部でコンテンツを開いてしまうという問題。
例えば、こんな感じ。
[https://drive.google.com/open?id=1QDGsTNesm_JKLy5Tgojz70kZdPDo5cjk](https://drive.google.com/open?id=1QDGsTNesm_JKLy5Tgojz70kZdPDo5cjk)
この問題を解決するには、urlをちょっといじる。
`open`を`uc`に書き換えるだけでよい。
こんな感じ。
[https://drive.google.com/uc?id=1QDGsTNesm_JKLy5Tgojz70kZdPDo5cjk](https://drive.google.com/uc?id=1QDGsTNesm_JKLy5Tgojz70kZdPDo5cjk)
確かに変な画面内でコンテンツを開くという問題はなくなった。

## 1-2. 課題2つ目
しかし、1-1節の方法でhtmlファイルを共有しようとすると、Googleドライブはhtmlファイルをダウンロードさせようとする。ダウンロードせずに直接表示したいのに。。。
<sub><sub>[https://drive.google.com/uc?id=1QDGsTNesm_JKLy5Tgojz70kZdPDo5cjk&export=view](https://drive.google.com/uc?id=1QDGsTNesm_JKLy5Tgojz70kZdPDo5cjk&export=view)としても、[https://drive.google.com/uc?id=1QDGsTNesm_JKLy5Tgojz70kZdPDo5cjk&export=view#dummy.html](https://drive.google.com/uc?id=1QDGsTNesm_JKLy5Tgojz70kZdPDo5cjk&export=view#dummy.html)としても結果は変わらず。</sub></sub>
しかし、bmpなどの画像ファイルではなぜかうまくいく。(ダウンロードではなく普通にブラウザで表示してくれる)
こんな感じ。
[https://drive.google.com/uc?id=1LtcHFzaYa1bahScgEZRFjxuStIgZ0Udx]
(https://drive.google.com/uc?id=1LtcHFzaYa1bahScgEZRFjxuStIgZ0Udx)
いろいろやってみると、`uc`を使ったとき、Googleドライブではファイルの種類ごとに異なる仮想サーバへリダイレクトし、そこからコンテンツ提供しているようだとわかった。
<sub><sub>例えばbmp形式やpng形式では「doc-04-3c-docs.googleusercontent.com」から、
html形式では「doc-04-b4-docs.googleusercontent.com」からだった。
さらに、htmlファイルの拡張子を変更し、test.pngというファイルとしてアップロードしたものを表示しようとすると、これもバレて、「test.png.html」というファイルとしてダウンロードが開始してしまった。
</sub></sub>
きっと仮想サーバごとに、コンテンツ提供の方法がダウンロードか、そのままブラウザで表示させるかが異なるのだろう。

# 2. 実験

1-2節の問題を解消し、ブラウザ上でGoogleドライブに保存したhtmlファイルを表示させるため、次のような方法を考えた。
「空のbmpファイルを作り、内部にhtmlソースを書き込み、これをGoogleドライブにアップロードする(2-1節)。
これをサーバサイドプログラムがちゃんと認識すれば、内部にあるhtmlソース通りに表示できるだろう(2-2節)。」

## 2-1. bmpファイルにhtmlを埋め込む
bmpは画像のフォーマットの一種だ。他の形式と比較して極めて単純な構造を持っていて、バイナリエディタなどで16進(あるいは256進)表示すると、画像の画素の並びに従ってbitが記録されていることが分かる。構造が簡単な故に改編なども容易だ。そのため、「画像に画像以外の情報を埋め込む」には最適なフォーマットであるといえる。
次の手順でhtmlソースを埋め込んだ。

1. c.bmpを作成し、ペイントで開き、24色1000px×1000pxとした
2. バイナリエディタStirlingでb.bmpを開き、FFの連続が開始しているところから、`<html>hello world</html>`という文字列を上書きした。バイト数が変わらないように気を付けた。(これが変わるとファイルが壊れてしまう)
3. これをGoogleドライブにアップロードした。<br>[https://drive.google.com/uc?id=1-G5TkDMgZBAeH2t8TudaVRF9BMwgRAGy](https://drive.google.com/uc?id=1-G5TkDMgZBAeH2t8TudaVRF9BMwgRAGy)<br>
4. 手順3のリンクを開くと、大きな白地の画像の、左下にかすかに黒い小さな線があるのが分かるだろうか。これが`<html>hello world</html>`という情報を表現している。
5. このファイルをダウンロードし、再びバイナリエディタで開いた。確かに`<html>hello world</html>`という情報は残っていた(圧縮などが自動で書けられ、壊されてしまう可能性があり、調べた)

以上で、Googleドライブはhtmlファイルを、専用画面でもダウンロードでもなく、ブラウザに直接表示することになった。但しbmp画像として。

## 2-2. サーバ上でbmpファイルからhtmlを取り出す

2-1節で作ったbmp画像からhtmlファイルを取り出すのは自サーバのphpファイルの仕事だ。
次のようなプログラムを書こう。やってることは、「file_get_contensでページを取得したら、そこから`<html>`～`</html>`を取り出して、それを表示してね」という単純な処理だ。

```php
<?php

$asBmp =  file_get_contents("https://drive.google.com/uc?id=1-G5TkDMgZBAeH2t8TudaVRF9BMwgRAGy");
/* urlパラメータ「id」でファイルIDを動的に変えたいなら次の通り
$asBmp =  file_get_contents("https://drive.google.com/uc?id=".$_GET['id']);
*/

$start = strpos($asBmp, '<html');
$end = strpos($asBmp, '</html>')+7;

$html = substr($asBmp, $start, $end-$start);

print $html;


```

このphpプログラムにアクセスすると・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319477/45f1ecc7-679a-07f2-329e-fcb78ed5e998.png)
うまくいった！

# 3.感想
こんな手垢のつきまくったであろう手法で出来ることなのだから、きっとこれは想定外の脆弱性などではなく、裏技の類なのだろうと思った。(だからここで公開した。)
何はともあれ、これによって、「パソコン上でファイルを更新すれば後は自動でホームページが更新される」という仕組みが完成した。うれしい。