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
この問題を解決するには、urlをちょっといじる。
openucに書き換えるだけでよい。
こんな感じ。
https://drive.google.com/uc?id=1QDGsTNesm_JKLy5Tgojz70kZdPDo5cjk
確かに変な画面内でコンテンツを開くという問題はなくなった。

1-2. 課題2つ目

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

きっと仮想サーバごとに、コンテンツ提供の方法がダウンロードか、そのままブラウザで表示させるかが異なるのだろう。

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ドライブにアップロードした。
    https://drive.google.com/uc?id=1-G5TkDMgZBAeH2t8TudaVRF9BMwgRAGy
  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

$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プログラムにアクセスすると・・・

うまくいった!

3.感想

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