문제

그 상황

전통적인 램프 스택을 사용하여 랙 스페이스 클라우드의 클라이언트를위한 비디오 교육 사이트를 만들고 있습니다 (Rackspace의 클라우드에는 Windows와 Lamp Stacks가 있습니다). 이 사이트에서 제공하는 비디오 및 기타 미디어 파일은 고객이 액세스하기 위해 돈을 청구하므로 보호되어야합니다. 이와 같은 DRM 또는 재미있는 비즈니스는 없습니다. 기본적으로 웹 루트 외부에 파일을 저장하고 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

다음은 파일의 단순화 된 버전입니다 .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을 추가하거나 변경할 희망이 없습니다.

내가 이것에 대해 가지고있는 다른 옵션이 있습니까?

업데이트: 나는 랙 스페이스 지원 으로이 동작을 확인했으며 그들은 그것에 대해 할 수있는 일이 없다고 말했습니다.

도움이 되었습니까?

해결책

요청 플래시 앱이 리디렉션을 따르면 첫 번째 요청에 대한 리디렉션으로 답변하고 두 번째 요청을 다시 작성하려고합니다.

GET .../29.jpg

에게

header("Status: 302 Moved temporarily");
header("Location: .../r.php?i=29.jpg&random=872938729348");

그런 다음 R.PHP가 두 번째 요청에 파일을 전달합니다.

그렇지 않다면 (btw. Always), 나는 바니시가 수락하고 그에 따라 행동하는 정적 파일을 전달하는 것과 함께 헤더를 전송합니다.

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top