Сохранить HTTP_REFERER с mod_rewrite? - PullRequest
       39

Сохранить HTTP_REFERER с mod_rewrite?

0 голосов
/ 27 августа 2010

На самом деле я пытаюсь передать реферерам внутри .htaccess. Я пытаюсь сделать так, чтобы значение referer было отправлено в скрипт PHP, где это значение будет сохранено в базе данных. В некоторых случаях (в зависимости от реферера) изображение должно быть заблокировано (горячая ссылка), а в некоторых других случаях изображение должно отображаться нормально. Но это не сработает :-( Моя текущая попытка выглядит следующим образом (только для тестирования, поэтому в настоящее время обрабатывается каждое изображение):

RewriteCond %{REQUEST_URI} (.*)jpg$
RewriteCond %{ENV:verified}  ^$  
RewriteRule (.*)jpg$   /include/referrer.php?ref=%{REQUEST_FILENAME}&uri=%{REQUEST_URI}&query=%{QUERY_STRING}&env=%{ENV:verified} [E=verified:yes]

RewriteCond %{REQUEST_URI} (.*)jpg$
RewriteCond %{ENV:verified} ^yes$
RewriteRule ^(.*)$    %{REQUEST_FILENAME} [E=verified:no]

Referrer.php выглядит так:

<?
 log_img($_REQUEST['uri'].' - "'.$_REQUEST['env'].'"');
?>

Проблема в том, что referrer.php вызывается, но изображение не будет отображаться, что очевидно, поскольку второе правило не достигнуто.

Я также пытался отобразить изображение внутри referrer.php, например:

<?
 log_img($_REQUEST['uri'].' - "'.$_REQUEST['env'].'"');
 $src = str_replace($_SERVER['DOCUMENT_ROOT'],'',$_REQUEST['ref']);
?>
<img src="<? echo $src ?>" />

Но затем снова вызывается .htaccess, и я столкнусь с бесконечными циклами.

Вопрос теперь: как я могу получить доступ ко второму правилу или как я могу достичь того, что я хочу сделать. Есть ли способ сделать это?

Спасибо за вашу помощь, Lars

1 Ответ

0 голосов
/ 21 сентября 2010

Ваше текущее решение не работает, потому что mod_rewrite может использоваться только для перезаписи запроса в один пункт назначения, но вы, похоже, хотите, чтобы запрос отклонился от вашего PHP-скрипта, а затем продолжил работу с изображением. Может быть возможно вызвать подзапрос, который вызовет запуск сценария PHP, но я не думаю, что было бы возможно контролировать, продолжал ли исходный запрос к изображению в этом сценарии.

Лучший способ действий здесь - распечатать PHP-файл с фактическими данными изображения (а не с тегом изображения, ссылающимся на изображение) после того, как он выполнит любую проверку / регистрацию, которую вы намереваетесь сделать. Вы можете сделать это с readfile(), при условии, что вы отправляете правильные заголовки. Убедившись, что файл является одним из изображений, которые вы хотите отправить (а не какой-либо произвольный файл в вашей системе ...), вам по крайней мере потребуется определить соответствующий тип контента , а затем распечатать из данных. Также неплохо бы учитывать кеширование (см. этот ответ , а также этот ).

Сочетая некоторые из упомянутых приемов, простой псевдо-пример скрипта-реферера будет следующим. Обратите внимание, что вам следует изучить лучший способ реализации описанных методов, и вам необходимо уделять особое внимание безопасности, поскольку вы открываете файлы и распечатываете их содержимое.

$filename = /* sanitized file name */;

log_img(/* log some data about the request */);

if (file_exists($filename) && allowedToView($filename)) {
    // Assume we're not on PHP 5.3...
    $types = array(
        'gif' => 'image/gif',
        'png' => 'image/png',
        'jpg' => 'image/jpg',
    );
    $parts = pathinfo($filename);
    $ext   = strtolower($parts['extension']);

    if (array_key_exists($ext, $types)) {
        $mime = $types[$ext];
        $size = filesize($filename);
        $expires  = 60 * 60 * 24 * 30;

        if (!empty($_SERVER['IF-MODIFIED-SINCE'])) {
            $modified = filemtime($filename);
            $cached   = strtotime($_SERVER['IF-MODIFIED-SINCE']);

            if ($modified <= $cached) {
                header('HTTP/1.1 304 Not Modified');
                exit();
            }
        } 

        header("Content-Type: $mime");
        header("Content-Length: $size");
        header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $expires)
            . ' GMT');
        header('Cache-control: private, max-age=' . $expires);
        readfile($filename);
        exit();
    }
}

header("HTTP/1.0 404 Not Found");
exit();

А что касается файла .htaccess, он будет выглядеть примерно так (материал, который вы добавили в строку запроса, в любом случае доступен в $_SERVER, поэтому я не вижу смысла вручную передавать его в скрипт ):

RewriteEngine on

RewriteRule \.(jpg|png|gif)$ /include/referrer.php [NC]
...