Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Problem z pobieraniem mp3 z serwera
Forum PHP.pl > Forum > PHP
Kiubus
Witam.
Mam na swoim serwerze pliki w formacie MP3. Chciałbym, aby była możliwość ich pobrania. Próbowałem zrobić po prostu w HTML (a href...) ale to otwiera nowe okienko. Znalazłem na internecie skrypt download.php:
  1. <?php
  2. if (isset($_GET['file']) && substr($_GET['file'], -3)=='mp3') {
  3. header('Content-type: application/x-download');
  4. header('Content-Disposition: filename="'.$_GET['file'].'"');
  5. readfile($_GET['file'] );
  6. }
  7. ?>

Po jego użyciu nakazano stosować adres do hrefa w stylu:
  1. <a href="download.php?file=plik.mp3">

Ogólnie to działa, tylko, że na 4 linki pobiera tylko 1 piosenkę do odsłuchu, resztę ściąga rozmiarze np. 23 bajtów gdzie utwór ma rozmiar 2,29 MB. Czy ktoś może mi pomóc?
Pozdrawiam!
darko
Generalnie uważałbym bardzo na ten skrypt - ma potencjalną lukę w bezpieczeństwie, ponieważ w żaden sposób nie filtrujesz danych wejściowych ($_GET['file']). Co będzie w przypadku, jeśli ktoś poda w nazwie pliku ../../../.htpasswd ?
Polecam Ci stworzyć jakiś mechanizm zabezpieczający dane na serwerze, a przede wszystkim filtrowanie danych wejściowych. Nie mam też pewności czy masz kompletne nagłówki czy nie powinno być mniej więcej coś takiego:
header ("Content-disposition: attachment; filename=".$file.";");
header("Content-Length: ".filesize($file));

oczywiście $file jest przefiltrowaną wcześniej lokalizacją pliku wraz z jego nazwą. Wycinałbym wszystkie znaki specjalne oraz zagrywki typu ../.. oraz ~ i /
Kiubus
Wiem, ze skrypt moze byc dziurawy, ale niezbyt mam pomysl jak zrobic dobrze to pobieranie bo tak jak wspomnialem href mnie nie urzadza. Bez hrefa jest ciezko i zostaje tylko php i dlatego potrzebuje pomocy wink.gif
by_ikar
Jest podatny na atak directory traversal, najprościej można zabezpieczyć taki skrypt poprzez basename który zawsze zwróci tylko nazwę pliku, zamiast pełnej ścieżki, dzięki czemu nikt nie będzie mógł się "wydostać" poza katalog w którym będziesz miał pliki do pobrania. Bo w ten sposób można pobrać cały twój kod ze strony, łącznie z konfiguracją (np dostępem do bazy danych).

  1. <?php
  2.  
  3. if(isset($_GET['file']) && substr($_GET['file'], -3)=='mp3')
  4. {
  5. $file = basename($_GET['file']);
  6.  
  7. header('Content-Type: application/octet-stream');
  8. header('Content-Transfer-Encoding: Binary');
  9. header('Content-disposition: attachment; filename="'.$file.'"');
  10. header('Content-Length: '.filesize($file));
  11.  
  12. readfile($file);
  13. }
Kiubus
Ok, dzięki za podpowiedź odnośnie zabezpieczeń. A co do mojego drugiego problemu macie jakąś radę? Na 4 linki pobiera tylko 1 piosenkę do odsłuchu, resztę ściąga rozmiarze np. 23 bajtów gdzie utwór ma rozmiar 2,29 MB. Czy ktoś może mi pomóc? Pliki nie są uszkodzone, bo normalnie działają, w całości zostały przesłane na serwer a jest jak jest ;/
by_ikar
Jeżeli pobiera ci tylko niektóre pliki, to raczej już nie jest wina skryptu samego w sobie. Może te pliki są uszkodzone czy może połączenie ci zrywa - ciężko stwierdzić..
trueblue
Cytat(Kiubus @ 7.08.2014, 22:30:06 ) *
Na 4 linki pobiera tylko 1 piosenkę do odsłuchu, resztę ściąga rozmiarze np. 23 bajtów gdzie utwór ma rozmiar 2,29 MB.

Podejrzyj edytorem tekstu taki 23 bajtowy plik.
Pyton_000
Obstawiam

"404/ File bla blabala.mp3 not found"
smile.gif
Kiubus
Cytat(by_ikar @ 8.08.2014, 11:19:35 ) *
Jeżeli pobiera ci tylko niektóre pliki, to raczej już nie jest wina skryptu samego w sobie. Może te pliki są uszkodzone czy może połączenie ci zrywa - ciężko stwierdzić..

Pliki działają, sprawdzałem je na komputerze przed wysłaniem. Wysyłałem każdy z osobna, żeby mieć pewność, że przesłały się całe - przesłały się całe a jest jak jest. Połączenia nie zrywa, bo tak już występuje u dwóch osób.

Cytat(trueblue @ 8.08.2014, 11:22:24 ) *
Podejrzyj edytorem tekstu taki 23 bajtowy plik.

Plik ma format MP3, w winampie ma długość 0:00, po otworzeniu Notepadem jest pusty.

Cytat(Pyton_000 @ 8.08.2014, 12:00:01 ) *
Obstawiam

"404/ File bla blabala.mp3 not found"
smile.gif

Problem jest taki, że plik zostaje ściągnięty, ale tak jakby jego minimalna część. Jest to piosenka w formacie mp3 o wadze np. 2 MB, a pobiera 23 bajty.
Pyton_000
Dodaj sobie przed head
  1. var_dump($_GET['file']);die();

i sprawdź czy istnieje taki plik w podanej ścieżce względem skryptu
Turson
  1. var_dump($_GET['file']);die;

co mówi?
Kiubus
dodałem w pliku html przed <head> tą linijkę co pisaliście, ale nic nie zauważyłem na stronie.
Pyton_000
nie przed <head> tylko header('....
Kiubus
po kliknięciu w link downloadu:
  1. string(10) "nazwapliku.mp3"
Pyton_000
i czy na pewno masz taki plik dokładnie w tym samym miejscu w którym plik PHP ?
Kiubus
dokładnie tak, wszystkie pliki strony + mp3 i skrypt download.php są w jednym folderze.

@edit
Problem został rozwiązany. Gdyby kiedyś ktoś miał podobny problem, to z nazw pobieranych plików wystarczy usunąć polskie znaki i z hiperłącza również smile.gif Dzięki wszystkim za pomoc!
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.