Подменить URL файла

Тема в разделе "PHP", создана пользователем HatoL, 29 окт 2012.

Статус темы:
Закрыта.
Модераторы: latteo
  1. HatoL

    HatoL

    Регистр.:
    5 фев 2008
    Сообщения:
    206
    Симпатии:
    36
    Пользователь заходит на сайт http://example.ru. Далее щелкает на ссылку на этом сайте, например на http://example.ru/audio.mp3. Браузер выдает диалог скачивания файла, пользователь жмет кнопку сохранить, ему предлагается сохранить файл под именем auido.mp3. Но на самом деле он скачивает файл с другого сервера и с другим именем (например 234887098ds0u33.mp3). Так можно сделать? Не закачивая файл на свой сервер конечно. Я только знаю, что с помощью mod_rewrite или вручную писав header('...') можно выдать файл со своего сервера. А можно ли с чужого?
     
  2. Alexandr3

    Alexandr3

    Заблокирован
    Регистр.:
    22 апр 2008
    Сообщения:
    429
    Симпатии:
    96
    HatoL нравится это.
  3. HatoL

    HatoL

    Регистр.:
    5 фев 2008
    Сообщения:
    206
    Симпатии:
    36
    Да не, нельзя видимо. Если в mod_rewrite второй указываешь ссылку со своего сайта (то есть без префикса http), то все это работает следующим образом: так как все находится на одном сервере, модуль апача просто берет файл с другого места в компе и подсовывает его. А если с ссылкой на другой сайт, то тут либо выкачивать содержимое на свой сервер, а потом отдавать клиенту, либо надо порыскать в спецификации HTTP протокола, но я уверен, что там нет такого. Есть только редирект (301 например), но он все равно выдаст конечное название файла (браузер реально перенаправит клиента и известит об этом адресной строкой). А такого HTTP-кода, чтобы не извещал браузер, я уверен, нет.

    P. S. за статьи спасибо.
     
  4. begemot3

    begemot3 Постоялец

    Регистр.:
    18 янв 2009
    Сообщения:
    52
    Симпатии:
    13
    Есть у Апача модуль mod_proxy можно им попробовать.

    А вообще можно сделать так:

    http://shaman.asiadata.ru/node/217

    Вот там указан алгоритм для отдачи локального файла, тебе останется только считать этот файл с удаленной машины перед тем как отдавать
     
  5. vladitot

    vladitot Писатель

    Регистр.:
    11 сен 2012
    Сообщения:
    1
    Симпатии:
    0
    Пусть юзер нажимает не на /audio.mp3 а на audio.php
    На этой странице(audio.php) на php загрузите файл к себе на сервер, а потом подсунь на скачивание.
    Ссылки же свои можно подправить с помощью .htaccess
    Cron'ом удаляйте файлы скачанные каждые N часов. Это будет проще, чем мозги иметь свои разными разностями =)
     
  6. recasher2k12

    recasher2k12

    Регистр.:
    19 фев 2012
    Сообщения:
    156
    Симпатии:
    78
    Можно сделать, но только с JavaScript. Правда имя файла ты все равно не скроешь, то есть там уже как браузеру передастся. А вот переход по ссылке на файл /audio.mp3 ты можешь сделать любой. Далее по событию onclick делаешь e.preventDefault(); и в location.href прописываешь адрес того файла, который нужно скачать (можно любой url, если на другом домене, то ссылка должна начинаться с http://)
    Пример:
     
    latteo нравится это.
  7. testerQ

    testerQ Писатель

    Регистр.:
    20 ноя 2012
    Сообщения:
    1
    Симпатии:
    1
    Пример реализации с помощью nginx + php.
    1. кусок конфига nginx:
    Код:
    server {
            listen          80;
            server_name      ###########;
         
            rewrite ^/d/(.*?)/(.*?) /download.php?id=$1&name=$2 last;
     
            location ~* ^/internal_redirect/(.*?)/(.*?)/(.*?) {
                    # этот локешн не возможно вызвать из вне
                    internal;
                    resolver 8.8.8.8;
                 
                    # для удобства назначаем имена переменным, полученым из урла
                    set $srv  $1;
                    set $fn  $2;
                    set $durl $3;
                 
                    # задаем заголовки, которые будут переданы на удаленный сервер
                    proxy_set_header Host $srv;
                    proxy_set_header Referrer $srv;
                    proxy_set_header User-Agent 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.46 Safari/535.11';
     
                    # прячем заголовок который получили в ответ
                    proxy_hide_header Content-Disposition;
                    # прописываем свое значение, с указанием желаемого названия файла (то что увидит пользователь в диалоге сохранения)
                    add_header Content-Disposition 'attachment; filename="$fn"';
     
                    # перенаправляем запрос
                    proxy_pass http://$durl;
                    proxy_max_temp_file_size 0;
            }
     
            location ~ \.php$ {
                    fastcgi_pass    phpbackend;
                    include        /etc/nginx/fastcgi_params;
            }
    }
    2. download.php:
    PHP:
    <?php
     
    // Предположим где-то есть список урлов файлов с ключем id
    $data = array(
        
    => 'http://server.com/bla/bla/audio.mp3',
        
    => 'http://server3.com/bla1/bla2/audio5.mp3',
    );
     
    if (isset(
    $_REQUEST['id']) && isset($data[intval($_REQUEST['id'])])) {
        
    $url $data[intval($_REQUEST['id'])];
        
    $name = isset($_REQUEST['name']) ? $_REQUEST['name'] : 'noname';
        
    $host parse_url($urlPHP_URL_HOST);
     
        
    // “X-Accel-Redirect” производит внутреннее перенаправление на указанный URI
        // именно поэтому в конфиге nginx для этого локейшена есть директива internal
        
    header('X-Accel-Redirect: /internal_redirect/' $host '/' $name '/' $url);
    } else {
        
    // мы не знаем такого файла
        
    header('Location: /404.html');
    }

    вы размещаете ссылки на своем сайте вида http : //mydomain.com/d/ID/NAME, где ID - идентификатор файла, а NAME - название, которое покажется в диалоге загрузки конечному пользователю, например:
    http : //mydomain.com/d/1/Song.mp3 - будет показано Song.mp3
    http : //mydomain.com/d/3/Fu.mp3 - будет показано Fu.mp3

    при запросе такой ссылки сработает редирект на download.php, который в свою очередь проверит знаем ли мы такой файл и сделает редирект обратно в нгинкс, который уже скачает файл и отдаст клиенту, оптимальность такого метода в том, что нгинкс потратит намного меньше ресурсов на скачивание и отдачу.

    зы: конфиг чуть порезан, поэтому надо напильником его, но основная мысль передана.
     
    Горбушка нравится это.
  8. yasi

    yasi Создатель

    Регистр.:
    23 июл 2007
    Сообщения:
    32
    Симпатии:
    29
    Проще
    Передаем имя файла в php (реврайтом, или как удобнее). В начале в заголовке выводим имя
    Код:
        header( 'Content-Disposition: attachment; filename="audio.mp3"' );
    Ну и сам файл отдаем:
    Код:
      readfile($file);  
     
  9. ExpZerg

    ExpZerg Создатель

    Регистр.:
    29 июл 2012
    Сообщения:
    20
    Симпатии:
    8
    Например могу дать свой пример, но ссылки в большенстве статичны... те идут с одного сервака,
    пример
    ссылка зашифрована через base64
    качаеться через loads.php

    Код:
    <?php
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="site.ru_'.$_GET[fname].'"');
    echo file_get_contents('http://site2.ru/?url='.$_GET[url].'');
    ?>
    
    в браузере пишеться что отдаеться с Site.ru

    можно например передавать в зашифрованном виде полную ссылку на файл а отдавать его например как

    site.ru/loads.php?=base64(полная ссылка)=&mp3=имя файла
     
  10. Mashonka

    Mashonka Создатель

    Регистр.:
    17 янв 2013
    Сообщения:
    32
    Симпатии:
    3
    Для защиты контента раздавайте файлы создавая мягкие ссылки (php symlink() ) - вида [дата_оконч_действия].crc_random_name и кроном проходите раз в сутки и удаляйте устаревшие ссылки(инф: мягкая ссылка указывает на жесткую ссылку т.е. на имя файла, которое может быть не в пределах текущего диска http://younglinux.info/bash/linktheory.php).
     
Статус темы:
Закрыта.