🧐 出先で大容量ファイルを送りたいとき、みなさんどうしてます?

例えばクライアントのパソコンからデータを持ち帰らなきゃいけない場合、みなさんどうなさっていますか?

いちばん良いのはUSBメモリにコピーして帰ることですが、わたしの場合、急に立ち寄ったため持っていないこともしばしば。

そうなるとクライアントのメールアカウントをお借りして自分宛にメールを送信する方法が考えられますが、動画などだと容量が多過ぎたり、JS や Excel などのファイルは送信そのものがブロックされることもあります。

代替手段として次に思い浮かべるのは、ギガファイル便などのストレージサービスあたりでしょうか。大変便利なサービスでわたしもしばしば利用していましたが、個別に発行されるダウンロードURLや設定したパスワードを正しくメモする必要があり、スムーズな送信方法とは言えません。

だから自分で作りました。ブラウザで開くだけの自分専用簡単アップローダー「☁️ Cloudlet」。こちらのエントリは開発ログを兼ねた説明書のようなものとなっています。

もしエントリを読んで興味を持っていただけたら、ぜひダウンロードして使ってみてください。Cloudlet は Web サービスではなく、PHP と JavaScript で構成されたプログラムパッケージです。ご自身でPHPが動作するレンタルサーバ(必要であればドメインも)をご用意いただく必要があります。

✨ Cloudlet の特徴

  • ブラウザ経由で簡単アップロード
  • 自分でURLを決められるから、シンプルで覚えやすいURLで運用可能
  • 日本語ファイル名も文字化けなしで送信可能
  • UI は日本語/英語が自動で切り替わります
  • 複数ファイルの同時アップロードに対応
  • 同名ファイルは自動で _1, _2 ... を付けて保存(上書き防止)
  • レスポンシブ対応でスマホからでもアップロード可能

☁️ Cloudlet のアップロード画面をシンプルにした理由

まずアップロード画面ですが、パスワード認証をつけるべきかは最後まで悩みました。しかしもっともシンプルなファイル送信体験を実現するため、あえて認証はつけていません。

もちろん「検索エンジンにインデックスさせない」「危険なファイル(.php や .exe などのスクリプト/実行ファイル)のアップロードを禁止する」「ファイル名をHTMLエスケープしてXSS(クロスサイトスクリプティング)を防ぐ」「basename() でパス情報を除去する」など、最低限のセキュリティ対策は施していますが、基本的にはURLが他人に知られないことを前提とした設計になっています。

🧾 ファイル名が変わったら意味がない

当初は極力シンプルに、アップロード画面だけ用意してダウンロードはFTPで直接行うつもりでした。しかしクライアントからいただく資料などは、ファイル名が重要な意味を持ちます。FTPでダウンロードする場合、そのファイル名が文字化けしてしまうことに開発早々気がつきました。

結局日本語ファイル名の文字化け対策としてダウンロードページを設け、ダウンロード時に HTTP レスポンスヘッダーで正しいファイル名を再指定するといった手法を取ることに。

header('Content-Disposition: attachment; filename="' . $safe_output_name . '"; filename*=UTF-8\'\'' . rawurlencode($safe_output_name));

🔒 セキュリティ的には大丈夫なの?

Cloudlet は「URLを知っている本人だけが使うこと」を前提とした、自分専用の簡易アップローダーです。したがってログイン機能やユーザーごとの認証は設けていませんが、それでも最低限のセキュリティ対策は施しています。

具体的には、パストラバーサル(../etc/passwd など)やヘッダーインジェクションといった基本的な攻撃を防ぐためのチェックを組み込んでいます。ファイル名にバックスラッシュやクォートが含まれている場合も、安全な文字列として扱われるよう加工してあります。

アップロード画面にはパスワードはありませんが、ダウンロード画面は一応のパスワード認証付きです。とはいえ、Cloudlet の本質的な安全性は「他人に知られない URL」で運用するという点にあります。その意味では、自分専用・短期運用に適したツールと言えるでしょう。

  • basename() によるパスの正規化
    $filename = basename($_GET['file']);
    /etc/passwd などのパストラバーサル攻撃を防止
  • realpath() で実際のファイルパスを検証
    $filepath = realpath($upload_dir . $filename);
    シンボリックリンクや相対パスを解決し、意図外の場所へのアクセスを防ぐ
  • strpos() による安全確認
    if (strpos($filepath, $real_upload_dir) !== 0)
    uploads 外の読み取りをブロック
  • is_file() でファイルの存在チェック
    !is_file($filepath)
    ディレクトリや壊れたリンクを無視
  • str_replace() によるヘッダー注入対策
    $safe_output_name = str_replace(['"', '\\'], '', $filename);
    HTTPヘッダーインジェクション防止
  • readfile() で直接ストリーム出力
    大きなファイルでも安定してダウンロード

といった対策を行なっています。最初は軽い気持ちで作り始めたのに、次から次へと問題が発覚して対策するうちにどんどんプロジェクトが巨大化し煩雑になっていく、これは開発あるあるかもしれませんね。

⚙️ Cloudlet の設定方法

  1. Dottiq Tools から ZIP ファイルをダウンロードして解凍
  2. auth.php$correct_password を任意の文字列に変更
  3. サーバにアップロード。uploads フォルダのパーミッションを 707 に設定
  4. root.htaccess.txtuploads.htaccess.txt をそれぞれ .htaccess にリネーム

🖱️ Cloudlet の使用方法

  1. アップロード用 URL にブラウザでアクセス

  2. ファイルを選択 or ドロップしてアップロードボタンをクリック

  3. /login.php にアクセスし、設定したパスワードを入力
  4. チェックを入れてダウンロード
  5. 不要になったファイルは手動で削除(推奨)

アイディア次第で様々な使い方が可能

  • ノーコードな社内ファイル受け取りフォームとして
    関係者だけにダウンロード画面を共有すればOK
  • USB代わりの一時ストレージ
    Mac↔Windowsのやりとりもスムーズに
  • スマホ⇔PC間の写真・動画転送
    レスポンシブ対応でスマホからも操作可
  • 現場からの素材提出に
    撮影スタッフや外注先とのデータ受け渡しにも
  • 外出先で使う資料の事前送信
    自宅でアップして、現地でダウンロード

あなたの作業が少しでもスムーズになることを願っています☁️

ダウンロードはこちらからどうぞ:
👉 Dottiq Tools