File letöltési probléma, php.

File letöltési probléma, php.
2012-07-26T10:51:49+02:00
2012-07-26T18:24:21+02:00
2022-11-26T10:30:37+01:00
Bajnok125
Sziasztok!
Itt is szeretném a segítségeteket kérni. Weblapról file letöltésekor (nemcsak kép fájl esetében, hanem, amit a tulaj korábban feltöltött: exe, excel, word, stb)a letöltés helyett a file "megnyitódik", de csak a bájtképei jelennek meg. Ez a Chrome, IE, FF alatt is így van.
Itt a forráskód, bogarásszatok benne, és ha lehet pontosítsátok a konkrét sort, ha hibás, és ne csak utalgassatok, hogy mit is kellene tenni, így szerintem hamarabb dűlőre jutunk! Egyébként ami érdekes, az, hogy a kód localhoston tökéletesen működik (WAMP szerver). Ezért is nem értem, mi a hiba...

Itt a kód, (aminek a header részét a a PHP manualból vettem:http://php.net/manual/en/function.readfile.php)


<?php
// Start the session
require_once('startsession.php');

// Fejléc beillesztése
$page_title = 'Árlista letöltése';
require_once('header.php');


require_once('connect_db.php');

//Ellenőrizze, hogy a felhasználó be van-e jelentkezve, mielött folytatná!
if (!isset($_SESSION['id'])) {
echo '<p class="login">Kérem <a href="login.php">jelentkezzen</a> be!</p>';
exit();
}

// A navigációs menü megjelenítése
require_once('navmenu.php');

// Ha megnyomták a letöltés gombot
if (isset($_POST['submit']))

{ //01

// Változókhoz rendeljük az adatbázisból nyert, POST-tal átadott adatokat
$file_nev = $_POST['file_name'];
$file_meret = $_POST['file_size'];
$file_tipus = $_POST['file_type'];
$csoport_szam = $_POST['file_csoport'];

// Az aktuális könyvtár megadása

switch ($csoport_szam)
{ //02
case 1:
$aktualis_konyvtar = "./arlista/csoport_1/";
break;
case 2:
$aktualis_konyvtar = "./arlista/csoport_2/";
break;
case 3:
$aktualis_konyvtar = "./arlista/csoport_3/";
break;
default:
echo '';
break;
} //02

$file = $aktualis_konyvtar.'/'.$file_nev;

if ( file_exists ( $file ))
{ // nyitó file_exists



header ( 'Content-Description: File Transfer' );
header ( 'Content-Type: application/octet-stream' );
header ( 'Content-Disposition: attachment; filename='.basename( $file ));
header ( 'Content-Transfer-Encoding: binary' );
header ( 'Expires: 0' );
header ( 'Cache-Control: must-revalidate' );
header ( 'Pragma: public' );
header ( 'Content-Length: '.$file_meret);
ob_clean ();
flush ();
readfile ( $file );
exit;

} // záró file_exists

} //01

// Csatlakozás az adatbázishoz
$dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);


// Lekérdezzük a felhasználó csoportszámának megfelelő feltöltött fájlokat

$csoport_szam = $_SESSION['csoport'];

$query = "SELECT * FROM files WHERE file_csoport = '$csoport_szam'";
$data = mysqli_query($dbc, $query);
mysqli_close($dbc);

$sorok = mysqli_num_rows($data);

if ($sorok > 0)

{ // a nyitó



echo '<table align ="center">';

echo '<caption class="caption">Letölthető Fájl(ok)</caption>';
echo '<br/>';
echo '<br/>';

echo '<tr class="table_fejlec">';
echo '<th id = "fajl" > Fájl </th>';
echo '<th id = "feltoltve"> Feltöltve: </th>';
echo '<th id = "letoltes"> Letöltés </th>';
echo '</tr>';


while ($row = mysqli_fetch_array($data))

{//nyitó while
echo '<tr>';
echo '<td headers="fajl">' . $row['file_name'] .'</td>';
echo '<td headers="feltoltve">' . $row['datum'].'</td>';


echo '<form name="form_user" method="post" action="letoltes.php"/>';

echo '<td> <input type="submit"value="Letöltés" name="submit"/></td>';
echo '<input type="hidden" name="id" value="' . $row['id'] . '" />';
echo '<input type="hidden" name="file_name" value="' . $row['file_name'] . '" />';
echo '<input type="hidden" name="file_size" value="' . $row['file_size'] . '" />';
echo '<input type="hidden" name="file_type" value="' . $row['file_type'] . '" />';
echo '<input type="hidden" name="file_csoport" value="' . $row['file_csoport'] . '" />';

echo'</form>';
echo '</tr>';

} // while záró
echo '</table>';

} // if záró

else
{
echo 'Nincs letölthető fájl!';
}



// Lábléc beillesztése
require_once('footer.php');
?>

Köszönöm a segítséget!
Mutasd a teljes hozzászólást!
A mysqli_real_escape_string nem erre találták ki, semmit nem ér, a megoldás egy kicsit árnyaltabb.

Meghatározol egy könyvtárat jogosultság szerint.
Pl 'felhasznalo1' csak a 'lev1' könyvtár tartalmát töltheti le.


$dlFile = $_POST['file_name']; $basepath = '/home/domains/ize.hu/public_html/lev1/'; $realBase = realpath($basepath); $userpath = $basepath . $dlFile; $realUserPath = realpath($userpath); if ($realUserPath === false || strpos($realUserPath, $realBase) !== 0) {. //Nincsen jogosultsaga header("HTTP/1.0 403 Forbidden"); die(); echo "<h1>403 - Forbidden</h1>"; } else { //Letoltheti a filet }


A letőltő scriptel nincsen semmi gond, inkább az a probléma, hogy pl a
require_once('header.php');
kikuldi a headereket, mert van benne pl html tartalom.

Nem tudsz egyszerre HTML-t és filet is küldeni ebben a formában.
Rakd az egészet egy külön fileba, pl letolt.php és $_POST helyett használj $_GET -et.

Mutasd a teljes hozzászólást!

  • A MIME type-t rosszul állítod be, minden fájlt bináris fájlként kezelsz.


    header ( 'Content-Transfer-Encoding: binary' );
    Mutasd a teljes hozzászólást!
  • Live HTTP Headers-el nézd meg milyen headereket ad vissza a script.

    Valamint írasd ki a hibákat, lehet hogy valamelyik kódrészlet kiküld már valami tartalmat, és ezért a headerek is kimennek.

    OFF:
    Ha ez egy letőltő script akar lenni, akkor volna 1-2 dolog amit érdemes lenne átgondolni. Pl mi történne akkor ha $_POST['file_csoport'] változó értékét 3 nak adnám meg és esetleg nincsen jogosultságom hozzá.

    Nagyobb gond ha pl $_POST['file_name'] -nek a következőt adom meg:
    ../../connect_db.php

    ekkor a scripted a db jelszavadot fogja elküldeni.
    Mutasd a teljes hozzászólást!
  • Köszi a biztonsági résre vonatkozó észrevézelt.
    A

    $file_nev = mysqli_real_escape_string($dbc, trim($_POST['file_name']));
    szerinted már megfelelő védelem?

    header ( 'Content-Transfer-Encoding:binary' );
    helyett mi a megfelelő? Köszi a segítséget!
    Mutasd a teljes hozzászólást!
  • A mysqli_real_escape_string nem erre találták ki, semmit nem ér, a megoldás egy kicsit árnyaltabb.

    Meghatározol egy könyvtárat jogosultság szerint.
    Pl 'felhasznalo1' csak a 'lev1' könyvtár tartalmát töltheti le.


    $dlFile = $_POST['file_name']; $basepath = '/home/domains/ize.hu/public_html/lev1/'; $realBase = realpath($basepath); $userpath = $basepath . $dlFile; $realUserPath = realpath($userpath); if ($realUserPath === false || strpos($realUserPath, $realBase) !== 0) {. //Nincsen jogosultsaga header("HTTP/1.0 403 Forbidden"); die(); echo "<h1>403 - Forbidden</h1>"; } else { //Letoltheti a filet }


    A letőltő scriptel nincsen semmi gond, inkább az a probléma, hogy pl a
    require_once('header.php');
    kikuldi a headereket, mert van benne pl html tartalom.

    Nem tudsz egyszerre HTML-t és filet is küldeni ebben a formában.
    Rakd az egészet egy külön fileba, pl letolt.php és $_POST helyett használj $_GET -et.

    Mutasd a teljes hozzászólást!
  • Üdv,

    nem kéne annyi megjegyzés oda, mert pl. a záró file_exists az felesleges

    amúgy szerintem az eddigi emberek elmondták a hibát...

    - skullkidhun
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd