URL に特定のファイル拡張子がある場合、RackSpace Cloud は $_SESSION を削除します
-
20-09-2019 - |
質問
状況
従来の LAMP スタックを使用して、RackSpace クラウド上にクライアント用のビデオ トレーニング サイトを作成しています (RackSpace のクラウドには Windows スタックと LAMP スタックの両方があります)。このサイトで提供しているビデオやその他のメディア ファイルは、クライアントがアクセスに料金を請求するため、保護する必要があります。DRM やそのような面白いビジネスはありません。基本的に、ファイルを Web ルートの外部に保存し、ユーザーがファイルにアクセスできるようになる前に、PHP を使用してユーザーを認証します。mod_rewrite を使用して PHP 経由でリクエストを実行します。
そこで、ユーザーが次の URL でファイルをリクエストしたとします。
http://www.example.com/uploads/preview_image/29.jpg
mod_rewrite を使用して、その URL を次のように書き換えています。
http://www.example.com/files.php?path=%2Fuploads%2Fpreview_image%2F29.jpg
以下は、files.php スクリプトの簡略版です。
<?php
// Setups the environment and sets $logged_in
// This part requires $_SESSION
require_once('../../includes/user_config.php');
if (!$logged_in) {
// Redirect non-authenticated users
header('Location: login.php');
}
// This user is authenticated, continue
$content_type = "image/jpeg";
// getAbsolutePathForRequestedResource() takes
// a Query Parameter called path and uses DB
// lookups and some string manipulation to get
// an absolute path. This part doesn't have
// any bearing on the problem at hand
$file_path = getAbsolutePathForRequestedResource($_GET['path']);
// At this point $file_path looks something like
// this: "/path/to/a/place/outside/the/webroot"
if (file_exists($file_path) && !is_dir($file_path)) {
header("Content-Type: $content_type");
header('Content-Length: ' . filesize($file_path));
echo file_get_contents($file_path);
} else {
header('HTTP/1.0 404 Not Found');
header('Status: 404 Not Found');
echo '404 Not Found';
}
exit();
?>
問題
まず最初に言っておきますが、これは私にとって完璧に機能します。ローカルのテストマシンでは魅力的に動作します。ただし、クラウドにデプロイすると機能しなくなります。いくつかのデバッグの後、クラウドへのリクエストに .JPG、.PNG、または .SWF などの特定のファイル拡張子が付いている場合 (つまり、(通常は静的なメディア ファイルの拡張子)、リクエストは Varnish と呼ばれるキャッシュ システムにルーティングされます。このルーティングの最終結果は、このプロセス全体が PHP スクリプトに到達するまでにセッションが存在しないことになります。
URL の拡張子を .PHP に変更するか、クエリ パラメータを追加すると、Varnish がバイパスされ、PHP スクリプトがセッションを取得できます。問題ないですよね?無意味なクエリ パラメータをリクエストに追加するだけです。
ここに摩擦があります: このシステムを通じて私が提供しているメディア ファイルは、私がまったく制御できないコンパイル済み SWF ファイルを通じてリクエストされています。これらはサードパーティ ソフトウェアによって生成されており、要求された URL を追加または変更することはできません。
これに関して他に選択肢はありますか?
アップデート: RackSpace サポートにこの動作を確認しましたが、それについては何もできないと言われたことに注意してください。
解決
リクエストしている Flash アプリがリダイレクトに従っている場合、最初のリクエストではリダイレクトで応答し、2 番目のリクエストを書き換えようとします。
GET .../29.jpg
に
header("Status: 302 Moved temporarily");
header("Location: .../r.php?i=29.jpg&random=872938729348");
次に、r.php は 2 番目のリクエストでファイルを配信します。
そうでない場合は(ところで。常に)、Varnish が受け入れてそれに応じて動作する静的ファイルを配信するとともに、ヘッダーを明示的に送信します。
header("Cache-Control: no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
そして:私なら、 exit();
最初のコマンドの後に header()
ステートメントを使用して、スクリプトの残りの部分が実行されないようにします。 header()
ヘッダーのみを送信します。
使用するほうが信頼性も高いと思います ob_start()
PHP ファイルに空白があると、ヘッダーを追加するときに迷惑なエラーが発生する可能性があるためです。
他のヒント
私も同じ状況にあり、より良い答えを求めて Rackspace に連絡しました。
とった!彼らは、キャッシュをバイパス/変更するための 6 つの方法を概説した FAQ をまとめました。
http://cloudsites.rackspacecloud.com/index.php/How_can_I_bypass_the_cache%3F