Auf dieser Dreamcodes Datei Sharing Seite kannst du die von dir oder anderen hochgeladene Datei herunterladen. Jede Datei erhält beim Hochladen einen eindeutigen, zufällig generierten Link. Dieser Link ist ausschließlich dir bekannt und kann nur von Personen genutzt werden, die ihn direkt erhalten haben. Damit ist sichergestellt, dass deine Daten nicht öffentlich zugänglich sind.
Funktionen und Sicherheit
Die hochgeladene Datei liegt auf einem geschützten Server und wird nicht indiziert oder über Suchmaschinen gefunden. Es gibt keine offene Dateiübersicht. Der Download ist nur über den individuellen Link möglich. Falls ein Ablaufdatum beim Hochladen gesetzt wurde, wird die Datei automatisch nach Ablauf dieser Zeitspanne entfernt und ist dann nicht mehr verfügbar. Wurde kein Ablaufdatum gewählt, bleibt der Link bestehen, bis die Datei manuell oder systemseitig gelöscht wird.
Dateigröße und Ablaufdatum
Für den Upload gilt eine maximale Dateigröße, die in der Benutzeroberfläche angegeben ist. Beim Hochladen kannst du zusätzlich festlegen, nach wie vielen Tagen der Link automatisch ablaufen soll. Nach Ablauf dieser Zeit wird die Datei dauerhaft gelöscht und kann nicht wiederhergestellt werden.
Hinweis
Bitte achte darauf, nur Dateien hochzuladen und weiterzugeben, für die du die Berechtigung hast. Vertrauliche oder persönliche Daten sollten nur an Empfänger weitergegeben werden, denen du vertraust. Abgelaufene oder gelöschte Dateien können nicht wiederhergestellt werden.
<?php
// Configuration
define('MAX_FILE_SIZE', 10 * 1024 * 1024); // 10 MB default limit
define('UPLOAD_DIR', __DIR__ . '/uploads');
define('DB_FILE', __DIR__ . '/file_share.sqlite');
// Initialize storage
if (!is_dir(UPLOAD_DIR)) {
mkdir(UPLOAD_DIR, 0755, true);
}
$db = new SQLite3(DB_FILE);
$db->exec("CREATE TABLE IF NOT EXISTS files (
id INTEGER PRIMARY KEY,
token TEXT UNIQUE,
filename TEXT,
original_name TEXT,
size INTEGER,
mime TEXT,
created_at INTEGER,
expires_at INTEGER,
downloads INTEGER DEFAULT 0
)");
// Helper functions
function jsonResponse($data, $code = 200) {
http_response_code($code);
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data);
exit;
}
function sanitizeFileName($name) {
// keep only safe chars, preserve extension
$name = preg_replace('/[^A-Za-z0-9_. ]/', '', $name);
$name = preg_replace('/\s+/', '_', $name);
return $name;
}
// Upload handler
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['action']) && $_GET['action'] === 'upload') {
if (!isset($_FILES['file'])) {
jsonResponse(['error' => 'Keine Datei gefunden'], 400);
}
$file = $_FILES['file'];
if ($file['error'] !== UPLOAD_ERR_OK) {
jsonResponse(['error' => 'Upload Fehler ' . $file['error']], 400);
}
if ($file['size'] > MAX_FILE_SIZE) {
jsonResponse(['error' => 'Datei zu gross, maximale Groesse '. (MAX_FILE_SIZE / 1024 / 1024) .' MB'], 400);
}
$originalName = $file['name'];
$safeName = sanitizeFileName($originalName);
$mime = mime_content_type($file['tmp_name']) ?: 'application/octet-stream';
$size = intval($file['size']);
try {
$token = bin2hex(random_bytes(16));
} catch (Exception $e) {
$token = substr(md5(uniqid('', true)), 0, 32);
}
$ext = pathinfo($safeName, PATHINFO_EXTENSION);
$storeName = $token . ($ext ? '.' . $ext : '');
$destination = UPLOAD_DIR . '/' . $storeName;
if (!move_uploaded_file($file['tmp_name'], $destination)) {
jsonResponse(['error' => 'Konnte Datei nicht speichern'], 500);
}
// compute expiry
$expiresAt = null;
if (isset($_POST['expire_days'])) {
$days = intval($_POST['expire_days']);
if ($days > 0) {
$expiresAt = time() + $days * 24 * 60 * 60;
}
}
$stmt = $db->prepare('INSERT INTO files (token, filename, original_name, size, mime, created_at, expires_at) VALUES (:token, :filename, :original_name, :size, :mime, :created_at, :expires_at)');
$stmt->bindValue(':token', $token, SQLITE3_TEXT);
$stmt->bindValue(':filename', $storeName, SQLITE3_TEXT);
$stmt->bindValue(':original_name', $originalName, SQLITE3_TEXT);
$stmt->bindValue(':size', $size, SQLITE3_INTEGER);
$stmt->bindValue(':mime', $mime, SQLITE3_TEXT);
$stmt->bindValue(':created_at', time(), SQLITE3_INTEGER);
$stmt->bindValue(':expires_at', $expiresAt, SQLITE3_INTEGER);
$res = $stmt->execute();
$downloadUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . '?file=' . $token;
jsonResponse(['success' => true, 'link' => $downloadUrl]);
}
// Download handler
if (isset($_GET['file'])) {
$token = preg_replace('/[^a-f0-9]/', '', $_GET['file']);
if (!$token) {
http_response_code(404);
echo 'Datei nicht gefunden';
exit;
}
$stmt = $db->prepare('SELECT * FROM files WHERE token = :token LIMIT 1');
$stmt->bindValue(':token', $token, SQLITE3_TEXT);
$row = $stmt->execute()->fetchArray(SQLITE3_ASSOC);
if (!$row) {
http_response_code(404);
echo 'Datei nicht gefunden';
exit;
}
// check expiry
if (!empty($row['expires_at']) && time() > intval($row['expires_at'])) {
// delete file and db entry
$path = UPLOAD_DIR . '/' . $row['filename'];
if (file_exists($path)) {
unlink($path);
}
$del = $db->prepare('DELETE FROM files WHERE id = :id');
$del->bindValue(':id', $row['id'], SQLITE3_INTEGER);
$del->execute();
http_response_code(410);
echo 'Link abgelaufen';
exit;
}
$path = UPLOAD_DIR . '/' . $row['filename'];
if (!file_exists($path)) {
http_response_code(404);
echo 'Datei nicht gefunden';
exit;
}
// increment downloads
$upd = $db->prepare('UPDATE files SET downloads = downloads + 1 WHERE id = :id');
$upd->bindValue(':id', $row['id'], SQLITE3_INTEGER);
$upd->execute();
header('Content-Description: File Transfer');
header('Content-Type: ' . ($row['mime'] ?: 'application/octet-stream'));
header('Content-Disposition: attachment; filename="' . basename($row['original_name']) . '"');
header('Content-Length: ' . filesize($path));
readfile($path);
exit;
}
// API endpoint to get server config
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['action']) && $_GET['action'] === 'config') {
jsonResponse([
'maxFileSize' => MAX_FILE_SIZE,
'uploadUrl' => $_SERVER['PHP_SELF'] . '?action=upload'
]);
}
// Serve UI
?>
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Dreamcodes - Share it Now</title>
<style>
:root{
--bg:#0f1724;
--card:#0b1220;
--accent:#7c3aed;
--muted:#9aa4b2;
--glass: rgba(255,255,255,0.03);
}
body{font-family:Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial; background:linear-gradient(180deg,var(--bg),#071028); color:#e6eef8; margin:0; padding:40px;}
.container{max-width:900px;margin:0 auto}
.card{background:linear-gradient(180deg,var(--card),#071022); padding:28px;border-radius:16px; box-shadow:0 10px 30px rgba(2,6,23,0.7);}
h1{font-size:24px;margin:0 0 8px}
p.lead{color:var(--muted);margin:0 0 20px}
.uploader{display:flex;gap:16px;align-items:center}
.filebox{flex:1;padding:14px;border-radius:12px;background:var(--glass);border:1px solid rgba(255,255,255,0.03)}
input[type=file]{display:block}
.controls{display:flex;gap:12px;align-items:center}
.btn{background:var(--accent);color:white;padding:10px 14px;border-radius:10px;border:none;cursor:pointer;font-weight:600}
.small{font-size:13px;color:var(--muted)}
.result{margin-top:16px;padding:12px;background:rgba(255,255,255,0.02);border-radius:10px}
.linkbox{display:flex;justify-content:space-between;gap:12px;align-items:center}
.inputtext{background:transparent;border:1px solid rgba(255,255,255,0.04);padding:8px 10px;border-radius:8px;color:inherit;width:100%}
footer{margin-top:18px;text-align:center;color:var(--muted);font-size:13px}
.meta{display:flex;gap:16px;margin-top:12px;color:var(--muted);font-size:13px}
.note{margin-top:12px;color:#9aa4b2;font-size:13px}
.thin{opacity:0.8}
</style>
</head>
<body>
<div class="container">
<div class="card">
<h1>Datei teilen</h1>
<p class="lead">Datei schnell hochladen, Download Link erhalten, Ablaufdatum optional setzen</p>
<div class="uploader">
<div class="filebox">
<label class="small">Datei</label>
<input id="fileInput" type="file">
</div>
<div style="width:160px">
<label class="small">Ablauf in Tagen</label>
<input id="expireDays" class="inputtext" type="number" min="0" placeholder="0 kein Ablauf">
</div>
<div style="display:flex;flex-direction:column;gap:8px">
<button id="uploadBtn" class="btn">Hochladen</button>
<div class="small thin">Max {{maxmb}} MB</div>
</div>
</div>
<div id="result" class="result" style="display:none">
<div class="linkbox">
<input id="downloadLink" class="inputtext" readonly>
<button id="copyBtn" class="btn">Kopieren</button>
</div>
<div class="meta">
<div id="metaSize"> </div>
<div id="metaExpires"> </div>
</div>
</div>
<div id="error" class="note" style="display:none;color:#ffb4b4"></div>
<div class="note">Hinweis, es wird empfohlen nur Dateien zu teilen, die du teilen darfst. Gelöschte oder abgelaufene Links koennen nicht wiederhergestellt werden.</div>
</div>
<footer>
<div class="thin">Made by Dreamcodes.NET</div>
</footer>
</div>
<script>
(async function(){
const maxFileSize = await (async ()=>{
try{
const r = await fetch(location.pathname + '?action=config');
const j = await r.json();
return j.maxFileSize || 0;
}catch(e){return 0}
})();
const maxMb = Math.round((maxFileSize / 1024 / 1024) * 100) / 100 || 10;
document.querySelector('.thin').textContent = 'Max ' + maxMb + ' MB';
const fileInput = document.getElementById('fileInput');
const uploadBtn = document.getElementById('uploadBtn');
const expireDays = document.getElementById('expireDays');
const result = document.getElementById('result');
const downloadLink = document.getElementById('downloadLink');
const copyBtn = document.getElementById('copyBtn');
const error = document.getElementById('error');
const metaSize = document.getElementById('metaSize');
const metaExpires = document.getElementById('metaExpires');
function showError(msg){ error.style.display = 'block'; error.textContent = msg; }
function clearError(){ error.style.display = 'none'; error.textContent = ''; }
uploadBtn.addEventListener('click', async ()=>{
clearError();
if (!fileInput.files || fileInput.files.length === 0){ showError('Bitte Datei waehlen'); return; }
const file = fileInput.files[0];
if (maxFileSize && file.size > maxFileSize){ showError('Datei zu gross, maximale Groesse ' + maxMb + ' MB'); return; }
uploadBtn.disabled = true; uploadBtn.textContent = 'Upload läuft';
const fd = new FormData();
fd.append('file', file);
fd.append('expire_days', expireDays.value || 0);
try{
const resp = await fetch(location.pathname + '?action=upload', { method: 'POST', body: fd });
const data = await resp.json();
if (!resp.ok){ showError(data.error || 'Fehler beim Upload'); }
else{
result.style.display = 'block';
downloadLink.value = data.link;
metaSize.textContent = 'Groesse ' + Math.round(file.size / 1024) + ' KB';
metaExpires.textContent = expireDays.value > 0 ? 'Ablauf in ' + expireDays.value + ' Tagen' : 'Kein Ablauf gesetzt';
}
}catch(e){ showError('Netzwerkfehler'); }
uploadBtn.disabled = false; uploadBtn.textContent = 'Hochladen';
});
copyBtn.addEventListener('click', async ()=>{
try{ await navigator.clipboard.writeText(downloadLink.value); copyBtn.textContent = 'Kopiert'; setTimeout(()=> copyBtn.textContent = 'Kopieren', 2000); }catch(e){ showError('Kopieren nicht moeglich'); }
});
})();
</script>
</body>
</html>