Autor Zpráva
Zetrozet
Profil *
Jak lze upravit Header v PHP-skriptu, aby .htaccess rozlišil pokus o přímé stažení souboru od stažení PHP-skriptem

Řešil jsem, způsob rozlišení přímého stahování souboru od stahování prostřednictvím php-skriptu. Pak jsem zjistil, že funkce download() - viz níže - posílá na server hlavičku shodnou s přímým downloadem souboru.

Teď už mám jen otázku - co a jak lze funkcí download() přidat do hlavičky pro stahování, aby se stáhlo to, co má a přitom .htaccess odlišil stahování download() od přímého downloadu.

<?
if (isset($_GET["href"])){
Header("Content-Description: File Transfer"); 
Header("Content-Type: application/force-download"); 
$pos=strrpos($_GET["href"],"/")+1;
$fle=substr($_GET["href"],$pos,strlen($_GET["href"])-$pos);
if (isset($_GET["name"])) $fle=$_GET["name"];
Header("Content-Disposition: attachment; filename=".$fle);
include($_GET["href"]) ;
die();
}
//p&oslash;esm&igrave;rování k souboru ke stažení, pokud existuje
function download(){
//zkouška, zda se jedná o php soubor
if (strpos(strtolower($_GET['file']),".php")){
header("Content-Description: File Transfer");
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=\"".$_GET['name']."\"");
include($_GET['fold']."/".$_GET['file']);
hlasen();
die();
}

if (strpos(strtolower($_GET['file']),".exe")){
header ("Location: ".$_GET['fold']."/".$_GET['file']);

}

if (strpos(strtolower($_GET['file']),".zip")){
header ("Location: ".$_GET['fold']."/".$_GET['file']);

}

//stažení souboru, vnutí prohlíže&egrave;i stažení html, pdf,... souboru, místo jeho zobrazení
if (!isset($_GET['name'])) $_GET['name']=$_GET['file'];
header("Content-Description: File Transfer");
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=\"".$_GET['name']."\"");
$f=fopen($_GET['fold']."/".$_GET['file'],"r");
echo fread($f,filesize($_GET['fold']."/".$_GET['file']));
fclose($f);
hlasen();
die();
}

Moderátor Davex: Vkládej prosím kódy mezi značky [pre] a [/pre] (stačí kliknout na ).
Davex
Profil
Zetrozet:
Pak jsem zjistil, že funkce download() - viz níže - posílá na server hlavičku shodnou s přímým downloadem souboru.
Tu hlavičku pošle prohlížeči a ne serveru a za ní odešle výstup z includovaného souboru. V tomto skriptu mimochodem k volání funkce download() nikdy nedojde.

co a jak lze funkcí download() přidat do hlavičky pro stahování, aby se stáhlo to, co má a přitom .htaccess odlišil stahování download() od přímého downloadu
Ono se stahuje něco jiného? Co je myšleno tím odlišením stahování a jaká je tam spojitost se souborem .htaccess?
Zetrozet
Profil *
1) Ano, v této části skriptu není volání fce download. Dolů tedy připojím skript celý.

2) když uživatel nebo program v uživatelově počítači zadá například "http://www.zetrozet.biz/U2010/cisfu39.exe" dojde ke stahování mimo jakoukoli kontrolu. Já tohle stahování povolit musím, ale pokud tento příkaz přesměruji do PHP-skriptu, vytvoří po "kontrole" stejné volání a celé se to zacyklí.

Teď ten kompletní download.php:
<?
if (isset($_GET["href"])){
Header("Content-Description: File Transfer"); 
Header("Content-Type: application/force-download"); 
$pos=strrpos($_GET["href"],"/")+1;
$fle=substr($_GET["href"],$pos,strlen($_GET["href"])-$pos);
if (isset($_GET["name"])) $fle=$_GET["name"];
Header("Content-Disposition: attachment; filename=".$fle);
include($_GET["href"]) ;
die();
}
//přesměrování k souboru ke stažení, pokud existuje
function download(){
//zkouška, zda se jedná o php soubor
if (strpos(strtolower($_GET['file']),".php")){
header("Content-Description: File Transfer");
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=\"".$_GET['name']."\"");
include($_GET['fold']."/".$_GET['file']);
hlasen();
die();
}

if (strpos(strtolower($_GET['file']),".exe")){
header ("Location: ".$_GET['fold']."/".$_GET['file']);

}

if (strpos(strtolower($_GET['file']),".zip")){
header ("Location: ".$_GET['fold']."/".$_GET['file']);

}

//stažení souboru, vnutí prohlížeči stažení html, pdf,... souboru, místo jeho zobrazení
if (!isset($_GET['name'])) $_GET['name']=$_GET['file'];
header("Content-Description: File Transfer");
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=\"".$_GET['name']."\"");
$f=fopen($_GET['fold']."/".$_GET['file'],"r");
echo fread($f,filesize($_GET['fold']."/".$_GET['file']));
fclose($f);
hlasen();
die();
}

//adresa pro odeslání hlášení o chybě
$adresa="chybawww@trunecek.cz";
$fold=$_GET["fold"];


if(isset($_SERVER["HTTP_REFERER"])) $back="<a href=\"".htmlspecialchars($_SERVER["HTTP_REFERER"])."\">Návrat zpět</a> &nbsp; &nbsp;" ; else $back="";
$foo="<br><br>$back<a href=\"index.php\">Úvodní stránka</a>\n</body></html>";
$kontakt="<br><br>Kontakujte prosím administrátora na <a href=\"mailto:$adresa?subject=".rawurlencode("Hlášení o chybě")."\">$adresa</a>, aby byla chyba rychle napravena.";
$top="<html>\n<head>\n<meta http-equiv=\"content-type\" content=\"text/html; charset=windows-1250\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"engine/simple.css\">\n</head><body>";
$chyba1="<h3>Upozornění</h3>Chystáte se stáhnout soubor <strong>".$_GET['file']."</strong>.<br>
Omlouváme se za vzniklé potíže, ale víše uvedený soubor doporučujeme nestahovat.<br>
<strong>Požadovaný soubor je zřejmě poškozen, nebo byl napaden virem.</strong><br>
Pokud jej přesto chcete stáhnout, můžete tak učinit <a href=\"".$_GET["fold"]."/".$_GET["file"]."\">zde</a> na vlastní nebezpečí.<br>
Můžete také zkusit stáhnout soubor z alternativního serveru, adresy jsou uvedeny na úvodní stránce $kontakt";

$chyba2="<h3>Soubor je nedostupný</h3>\nPožadovaný soubor <strong>".$_GET['file']."</strong> neexistuje, nebo nemáte oprávnění jej stáhnout.<br>Můžete zkusit stáhnout soubor z alternativního serveru, adresy jsou uvedeny na úvodní stránce<br>Omlouváme se za vzniklé potíže.";


//zkouška, zda existuje stahovaný soubor
if (file_exists($_GET['fold']."/".$_GET['file'])){
$fil=explode(".",$_GET['file']);
//zkouška, zda existuje příslušný md5 soubor
if (file_exists($_GET['fold']."/".$fil[0].".md5")) $data=file($_GET['fold']."/".$fil[0].".md5"); else echo download(); 
$data=explode(" *",$data[0]);
//kontrola md5 hashů
if (md5_file($_GET['fold']."/".$_GET['file'])==$data[0]) echo download(); else echo $top.$chyba1.$foo; 
}
else echo $top.$chyba2.$kontakt.$foo; 
?>

Moderátor Davex: Vkládej prosím kódy mezi značky [pre] a [/pre] (stačí kliknout na ).
Davex
Profil
Zetrozet:
Takže jestli to dobře chápu, tak se ten uživatelův požadavek přepíše pomocí pravidla mod_rewrite na stahovací skript, který soubor includuje ze serveru pomocí http://, aby ho odeslal uživateli?

Soubor by se neměl includovat z http:// a asi by se měl odeslat pomocí funkce readfile() přímo z disku. Také je dobré, nedůvěřovat obsahu GET proměnných, které mohou obsahovat cokoliv - je to veliká bezpečnostní díra.
Zetrozet
Profil *
Je to tak. S použitím readfile() moc spěchat nebudu, už jednou jsem řešil ze dne na den problém, když se poskytovatel rozhodl zakázat některé funkce, které považoval za nebezpečné.
Potřebuju získat přehled o dowloadech souborů, abych věděl, jak moc uživatelé aktualizují.
Taky nechápu pravidelné přístupy z IP na jiných kontinentech, když jim je české účetnictví i daňová evidence na prd, a navíc ani nemohou rozumět programovacímu jazyku, který je ryze český a jehož autoři tvrdí, že už 15 roků měl být převálcován dějinami.
Keeehi
Profil
Zetrozet:
Taky nechápu pravidelné přístupy z IP na jiných kontinentech.
A co třeba vyhledávače?
Zetrozet
Profil *
To je mi jasné, že jsou to podle všeho vyhledávače - těm je ale jedno, jak konkrétní informace jm předhodím, stejně je pro okolní svět nechápatelné povídání o dvou zcela konkrétních českých účetních programech. Naopak pro ty zahraniční vyhledávače má větší vypovídací schopnost obecná stránečka o českém účetnicví a daňové evidenci. Mám tam Kanadskou IP, která cca 3x denně vleze na hlavní stránku a odkráčí pryč - a tím se má jako o tom webu něco dozvědět.

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0