html/php/mySQL blob-Datei herunterladen

BuTCh4

Cadet 3rd Year
Registriert
Jan. 2006
Beiträge
36
Hallo,
ich entwickel aktuell eine Datenbank und habe Probleme die in der Datenbank im blob-Format gespeicherten Dateien (pdf,jpeg,bmp) herunterzuladen. Die Dateien sind vollständig in der Datenbank gespeichert, beim Download erhalte ich fehlerhafte Dateien.

Den Download starte ich über einen Link der wie folgt in HTML erstellt wird:

<a href='certification/imageView.php?id=$imgDataX[$i]' class='btn btn-primary'>Download</a>


Der durch den Link aufgerufene Code lautet:

<?php

chdir("..");
chdir("..");
chdir("..");
include('config/logindata_db.php');


$imgDataX = $_GET['id'];
if(isset($imgDataX)) {

$sql = "SELECT * FROM output_images WHERE imageId=" . $imgDataX;
$result = mysqli_query($db, $sql) or die("<b>Error:</b> Problem on Retrieving Image BLOB<br/>" . mysqli_error($db));


list($id, $type, $content, $size, $file) = mysqli_fetch_array($result);

// header("Content-length: $size");
header("Content-type: $type");
header("Content-Disposition: attachment; filename=$file");
/* header('Accept-Ranges: bytes');
header('Content-Transfer-Encoding: binary'); */

ob_clean();
flush();
$content = stripslashes($content);
echo $content;
mysqli_close($db);
exit;


}

?>


Ich habe etwas mit den headern herumgespielt, jedoch ergab dies keine Besserung.
Kann mir jemand mit dem Problem helfen? Sieht jemand einen Fehler bzw eine fehlende Eingabe?

Vielen Dank
 
Bevor du irgendwas weiter machst: Mach dich schlau über SQL Injections und Prepared Statements! Das ist brandgefährlich, was du das zusammenbaust.

Ansonsten: Hast du mal geschaut, ob in deinen Variablen überhaupt was drin steht und die Länge von $content mit $size übereinstimmt?
 
Lass das am besten gleich sein. Dateien speichert man nicht in der Datenbank. Dort gehören nur relationale Daten hinein.

Erstell dir irgendwo nen Ordner, leg die Dateien dort rein, hol dir aus der DB den Pfad dahin und verlinke dann/leite weiter. Ggf. noch ne eigene URL für den Download mit Zeitbeschränkung oder was auch immer. Den Zugriffsschutz musst du dir dann lediglich selbst basteln.
 
Schonmal danke für die Antworten.
Die Gefahr von SQL Injections sind mir bekannt, das Skript soll so nicht zum Einsatz kommen.

Auffällig ist, das unter $size eine falsche Dateigröße beim upload hinterlegt wird. Gebe ich diese Größe durch 'header("Content-length: $size") ' an, bricht der Download ab. Bin aktuell nicht an dem Rechner wo die Daten zur Verfügung stehen, daher kann ich jetzt leider kein Code des Uploades posten.
 
Was ist denn jetzt imgdatax? Ein Array? Oder doch eine Id? Oder noch was anderes?

Blob ist erstmal ok für kleine Dateien.

Kritischer ist mysqli - nimm PDO wenn möglich.

Außerdem ist select * brandgefährlich zusätzlich zum Erwähnten. Liste die Spalten explizit.

Und dann schreib erstmal alles in den Body. Wer weiß, vielleicht zickt irgendwas irgendwo. Laut snippet oben kommt vielleicht einfach nichts brauchbares für den Suchschlüssel raus. Das sieht man halt binär nicht.

Was ich grad nicht im Kopf hab ist, ob Echo binarysafe ist.


Ps, was soll das chdir tun? IMO läuft an der Stelle was schief. Pfade ändern in der we Anwendung ist arg suspekt.
 
  • Gefällt mir
Reaktionen: BuTCh4
BuTCh4 schrieb:
Schonmal danke für die Antworten.
Die Gefahr von SQL Injections sind mir bekannt, das Skript soll so nicht zum Einsatz kommen.

Auffällig ist, das unter $size eine falsche Dateigröße beim upload hinterlegt wird. Gebe ich diese Größe durch 'header("Content-length: $size") ' an, bricht der Download ab. Bin aktuell nicht an dem Rechner wo die Daten zur Verfügung stehen, daher kann ich jetzt leider kein Code des Uploades posten.

Dann mach halt ein strlen auf Content. Nach dem Download dann mal die Originaldatei und die runtergeladene im Hexeditor vergleichen, nicht dass in der runtergeladenen vorne direkt ne Php Fehlermeldung im Inhalt steht :D anders wirst du wohl nicht hinterherkommen. Im Browser dann nochmal die Header checken, nicht dass du beim fetch einfach die falsche Reihenfolge der Variablen hast wo du das per list() belegst!
 
  • Gefällt mir
Reaktionen: BuTCh4
So, habe mich nochmal dransetzen können und habe die Dateiinhalte im Hexeditor verglichen. Nachdem ich auf fehlende Backslashes gestoßen bin habe ich die Zeile $content = stripslashes($content); auskommentiert und siehe da, alles Läuft wie gewünscht.

Vielen Danke für eure Hilfe.

P.S.: werde mich ab jetzt mit PDO auseinander setzen um das kritische an MYSQLI zu erfahren. Habe die SQL abfrage nun so gestaltet:
$sql = "SELECT *
FROM output_images
WHERE imageId=?" ;

$stmt = $mysqli->prepare($sql);

$stmt->bind_param('i',$imgDataX);

$stmt->execute();


$result = $stmt->get_result();

Gibt es hier ein Problem/ eine Gefahr? Sollte ich
RalphS schrieb:
Außerdem ist select * brandgefährlich zusätzlich zum Erwähnten. Liste die Spalten explizit.
umsetzen?
 
Nur nicht vergessen das Insert auch prepared zu machen ;) dann kann man sich nämlich auch das strip sparen was dir da das Genick gebrochen hat ;)
 
  • Gefällt mir
Reaktionen: BuTCh4
Zurück
Oben