#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
import os
import time
import urllib.parse
import mimetypes
import re
import traceback
import sys
import signal
import socket

# Konfiguration
PORT = 8081
UPLOAD_DIR = "uploads"
SERVER_ADDRESS = "77.90.60.235"  # Ändern Sie diese zu Ihrer Server-IP
ADMIN_USERNAME = "admin"
ADMIN_PASSWORD = "emoreJ15!"  # Ändern Sie dies zu Ihrem gewünschten Passwort
LOG_FILE = "server.log"

# Stellen Sie sicher, dass das Upload-Verzeichnis existiert
if not os.path.exists(UPLOAD_DIR):
    os.makedirs(UPLOAD_DIR)

# Logging-Funktion
def log_message(message, level="INFO"):
    timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
    log_entry = f"[{timestamp}] [{level}] {message}\n"
    
    print(log_entry, end="")
    
    try:
        with open(LOG_FILE, "a") as log_file:
            log_file.write(log_entry)
    except Exception as e:
        print(f"Fehler beim Schreiben ins Log-File: {str(e)}")

# Signal-Handler für ordnungsgemäßes Herunterfahren
def signal_handler(sig, frame):
    log_message("Server wird heruntergefahren...", "INFO")
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)

class FileServerHandler(BaseHTTPRequestHandler):
    # Errorhandling für Verbindungsabbrüche
    def handle(self):
        try:
            super().handle()
        except (BrokenPipeError, ConnectionResetError) as e:
            log_message(f"Verbindung abgebrochen: {str(e)}", "WARNING")
        except Exception as e:
            log_message(f"Fehler bei der Verbindungsbehandlung: {str(e)}", "ERROR")
            traceback.print_exc()
    
    def log_message(self, format, *args):
        """Verbesserte Protokollierung"""
        client_address = self.address_string()
        log_message(f"{client_address} - {format % args}", "INFO")
    
    def send_html_response(self, content, status=200):
        """Sendet eine HTML-Antwort"""
        try:
            self.send_response(status)
            self.send_header('Content-Type', 'text/html; charset=utf-8')
            self.end_headers()
            self.wfile.write(content.encode('utf-8'))
        except (BrokenPipeError, ConnectionResetError) as e:
            log_message(f"Verbindung abgebrochen beim Senden der HTML-Antwort: {str(e)}", "WARNING")
        except Exception as e:
            log_message(f"Fehler beim Senden der HTML-Antwort: {str(e)}", "ERROR")
    
    def send_json_response(self, data, status=200):
        """Sendet eine JSON-Antwort"""
        try:
            self.send_response(status)
            self.send_header('Content-Type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps(data).encode('utf-8'))
        except (BrokenPipeError, ConnectionResetError) as e:
            log_message(f"Verbindung abgebrochen beim Senden der JSON-Antwort: {str(e)}", "WARNING")
        except Exception as e:
            log_message(f"Fehler beim Senden der JSON-Antwort: {str(e)}", "ERROR")
    
    def send_error_response(self, message, status=500):
        """Sendet eine Fehlerantwort"""
        try:
            self.send_response(status)
            self.send_header('Content-Type', 'text/html; charset=utf-8')
            self.end_headers()
            error_page = f"""
            <!DOCTYPE html>
            <html lang="de">
            <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>Fehler</title>
                <style>
                    body {{ font-family: Arial, sans-serif; margin: 0; padding: 20px; }}
                    .error {{ background-color: #ffebee; border: 1px solid #ffcdd2; padding: 15px; border-radius: 4px; }}
                    h1 {{ color: #d32f2f; }}
                    a {{ color: #2196F3; text-decoration: none; margin-top: 20px; display: inline-block; }}
                </style>
            </head>
            <body>
                <h1>Fehler</h1>
                <div class="error">
                    <p>{message}</p>
                </div>
                <a href="/">Zurück zur Startseite</a>
            </body>
            </html>
            """
            self.wfile.write(error_page.encode('utf-8'))
        except (BrokenPipeError, ConnectionResetError) as e:
            log_message(f"Verbindung abgebrochen beim Senden der Fehlerantwort: {str(e)}", "WARNING")
        except Exception as e:
            log_message(f"Fehler beim Senden der Fehlerantwort: {str(e)}", "ERROR")
    
    def check_admin_auth(self):
        """Überprüft, ob der Benutzer authentifiziert ist"""
        auth_header = self.headers.get('Authorization')
        if not auth_header:
            return False
        
        try:
            auth_type, auth_string = auth_header.split(' ', 1)
            if auth_type.lower() != 'basic':
                return False
            
            import base64
            decoded = base64.b64decode(auth_string).decode('utf-8')
            username, password = decoded.split(':', 1)
            
            return username == ADMIN_USERNAME and password == ADMIN_PASSWORD
        except Exception:
            return False
    
    def request_admin_auth(self):
        """Fordert Authentifizierung an"""
        try:
            self.send_response(401)
            self.send_header('WWW-Authenticate', 'Basic realm="Admin-Bereich"')
            self.send_header('Content-Type', 'text/html; charset=utf-8')
            self.end_headers()
            
            auth_page = """
            <!DOCTYPE html>
            <html lang="de">
            <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>Authentifizierung erforderlich</title>
                <style>
                    body { font-family: Arial, sans-serif; margin: 0; padding: 20px; }
                    .message { background-color: #e3f2fd; border: 1px solid #bbdefb; padding: 15px; border-radius: 4px; }
                    h1 { color: #1976D2; }
                    a { color: #2196F3; text-decoration: none; margin-top: 20px; display: inline-block; }
                </style>
            </head>
            <body>
                <h1>Authentifizierung erforderlich</h1>
                <div class="message">
                    <p>Bitte geben Sie Ihren Benutzernamen und Passwort ein, um auf den Admin-Bereich zuzugreifen.</p>
                </div>
                <a href="/">Zurück zur Startseite</a>
            </body>
            </html>
            """
            self.wfile.write(auth_page.encode('utf-8'))
        except (BrokenPipeError, ConnectionResetError) as e:
            log_message(f"Verbindung abgebrochen beim Anfordern der Admin-Auth: {str(e)}", "WARNING")
        except Exception as e:
            log_message(f"Fehler beim Anfordern der Admin-Auth: {str(e)}", "ERROR")
    
    def generate_main_page(self):
        """Generiert die Hauptseite"""
        return f"""
        <!DOCTYPE html>
        <html lang="de">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Vantastic Uploads</title>
            <style>
                :root {{
                    --primary-color: #2196F3;
                    --primary-dark: #1976D2;
                    --accent-color: #FF4081;
                    --accent-dark: #F50057;
                    --success-color: #4CAF50;
                    --success-dark: #388E3C;
                    --error-color: #F44336;
                    --error-dark: #D32F2F;
                    --text-color: #333;
                    --light-text: #757575;
                    --bg-color: #fff;
                    --light-bg: #f5f5f5;
                    --border-color: #ddd;
                }}
                
                body {{
                    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                    line-height: 1.6;
                    color: var(--text-color);
                    background-color: var(--bg-color);
                    margin: 0;
                    padding: 0;
                }}
                
                .container {{
                    max-width: 1000px;
                    margin: 0 auto;
                    padding: 20px;
                }}
                
                header {{
                    background-color: var(--primary-color);
                    color: white;
                    padding: 1rem;
                    text-align: center;
                }}
                
                h1 {{
                    margin: 0;
                    font-size: 1.8rem;
                }}
                
                h2 {{
                    color: var(--primary-dark);
                    margin-top: 2rem;
                    margin-bottom: 1rem;
                    border-bottom: 2px solid var(--primary-color);
                    padding-bottom: 0.5rem;
                }}
                
                .upload-container {{
                    background-color: var(--light-bg);
                    border: 1px solid var(--border-color);
                    border-radius: 8px;
                    padding: 20px;
                    margin-bottom: 30px;
                }}
                
                .drop-area {{
                    border: 2px dashed var(--primary-color);
                    border-radius: 8px;
                    padding: 40px;
                    text-align: center;
                    color: var(--light-text);
                    margin-bottom: 20px;
                    transition: all 0.3s ease;
                    background-color: rgba(33, 150, 243, 0.05);
                }}
                
                .drop-area.highlight {{
                    background-color: rgba(33, 150, 243, 0.1);
                    border-color: var(--primary-dark);
                }}
                
                .file-input {{
                    display: none;
                }}
                
                .btn {{
                    background-color: var(--primary-color);
                    color: white;
                    border: none;
                    padding: 10px 20px;
                    border-radius: 4px;
                    cursor: pointer;
                    font-size: 16px;
                    transition: background-color 0.3s;
                }}
                
                .btn:hover {{
                    background-color: var(--primary-dark);
                }}
                
                .btn-upload {{
                    display: none;
                    margin-top: 10px;
                    background-color: var(--success-color);
                }}
                
                .btn-upload:hover {{
                    background-color: var(--success-dark);
                }}
                
                .btn-admin {{
                    background-color: #9c27b0;
                    margin-bottom: 20px;
                }}
                
                .btn-admin:hover {{
                    background-color: #7b1fa2;
                }}
                
                .file-info {{
                    margin-top: 15px;
                    font-weight: bold;
                }}
                
                .files-list {{
                    border: 1px solid var(--border-color);
                    border-radius: 8px;
                    overflow: hidden;
                }}
                
                .file-item {{
                    padding: 15px;
                    border-bottom: 1px solid var(--border-color);
                    display: flex;
                    align-items: center;
                    transition: background-color 0.2s;
                }}
                
                .file-item:last-child {{
                    border-bottom: none;
                }}
                
                .file-item:nth-child(odd) {{
                    background-color: rgba(0, 0, 0, 0.02);
                }}
                
                .file-item:hover {{
                    background-color: rgba(0, 0, 0, 0.05);
                }}
                
                .file-icon {{
                    margin-right: 15px;
                    color: var(--primary-color);
                    font-size: 24px;
                }}
                
                .file-details {{
                    flex: 1;
                }}
                
                .file-name {{
                    font-weight: bold;
                }}
                
                .file-meta {{
                    font-size: 14px;
                    color: var(--light-text);
                    margin-top: 5px;
                }}
                
                .file-actions {{
                    display: flex;
                    gap: 10px;
                    align-items: center;
                    min-width: 150px;
                    justify-content: flex-end;
                }}
                
                .download-link {{
                    background-color: var(--primary-color);
                    color: white;
                    text-decoration: none;
                    padding: 6px 12px;
                    border-radius: 4px;
                    font-size: 14px;
                    transition: background-color 0.3s;
                }}
                
                .download-link:hover {{
                    background-color: var(--primary-dark);
                }}
                
                .copy-link {{
                    background-color: #607D8B;
                    color: white;
                    border: none;
                    padding: 6px 12px;
                    border-radius: 4px;
                    cursor: pointer;
                    font-size: 14px;
                    transition: background-color 0.3s;
                }}
                
                .copy-link:hover {{
                    background-color: #455A64;
                }}
                
                .alert {{
                    padding: 15px;
                    border-radius: 4px;
                    margin-bottom: 20px;
                    display: none;
                }}
                
                .alert-success {{
                    background-color: rgba(76, 175, 80, 0.1);
                    border: 1px solid rgba(76, 175, 80, 0.2);
                    color: var(--success-dark);
                }}
                
                .alert-error {{
                    background-color: rgba(244, 67, 54, 0.1);
                    border: 1px solid rgba(244, 67, 54, 0.2);
                    color: var(--error-dark);
                }}
                
                .upload-progress {{
                    height: 6px;
                    width: 100%;
                    background-color: #e0e0e0;
                    margin-top: 10px;
                    border-radius: 3px;
                    overflow: hidden;
                    display: none;
                }}
                
                .progress-bar {{
                    height: 100%;
                    background-color: var(--primary-color);
                    width: 0%;
                    transition: width 0.2s;
                }}
                
                .loading {{
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    padding: 20px;
                }}
                
                .spinner {{
                    border: 4px solid rgba(0, 0, 0, 0.1);
                    width: 36px;
                    height: 36px;
                    border-radius: 50%;
                    border-left-color: var(--primary-color);
                    animation: spin 1s linear infinite;
                }}
                
                @keyframes spin {{
                    0% {{ transform: rotate(0deg); }}
                    100% {{ transform: rotate(360deg); }}
                }}
                
                .share-link {{
                    margin-top: 10px;
                    padding: 10px;
                    background-color: #f5f5f5;
                    border: 1px solid #ddd;
                    border-radius: 4px;
                    word-break: break-all;
                    font-family: monospace;
                }}
                
                .empty-message {{
                    text-align: center;
                    padding: 30px;
                    color: var(--light-text);
                }}
                
                footer {{
                    margin-top: 30px;
                    padding: 20px;
                    text-align: center;
                    color: var(--light-text);
                    font-size: 14px;
                }}
                
                .refresh-btn {{
                    background-color: #607D8B;
                    color: white;
                    border: none;
                    padding: 8px 15px;
                    border-radius: 4px;
                    cursor: pointer;
                    font-size: 14px;
                    float: right;
                    margin-bottom: 10px;
                }}
                
                .refresh-btn:hover {{
                    background-color: #455A64;
                }}
                
                /* Responsive */
                @media (max-width: 768px) {{
                    .file-item {{
                        flex-direction: column;
                        align-items: flex-start;
                    }}
                    
                    .file-icon {{
                        margin-right: 0;
                        margin-bottom: 10px;
                    }}
                    
                    .file-actions {{
                        margin-top: 10px;
                        width: 100%;
                    }}
                    
                    .download-link, .copy-link {{
                        flex: 1;
                        text-align: center;
                    }}
                }}
            </style>
        </head>
        <body>
            <header>
                <h1>Vantastic Uploads</h1>
            </header>
            
            <div class="container">
                <button class="btn btn-admin" onclick="window.location.href='/admin'">Verwaltungsbereich</button>
                
                <div class="upload-container">
                    <h2>Datei hochladen</h2>
                    
                    <div id="dropArea" class="drop-area">
                        <p>Dateien hier hinziehen oder klicken zum Auswählen</p>
                        <input type="file" id="fileInput" class="file-input">
                        <button class="btn" onclick="document.getElementById('fileInput').click()">Datei auswählen</button>
                        <div id="fileInfo" class="file-info"></div>
                        <button id="uploadBtn" class="btn btn-upload">Datei hochladen</button>
                        <div id="uploadProgress" class="upload-progress">
                            <div id="progressBar" class="progress-bar"></div>
                        </div>
                    </div>
                    
                    <div id="alertSuccess" class="alert alert-success">
                        Die Datei wurde erfolgreich hochgeladen!
                    </div>
                    
                    <div id="alertError" class="alert alert-error">
                        Beim Hochladen der Datei ist ein Fehler aufgetreten.
                    </div>
                </div>
                
                <div id="filesContainer">
                    <div style="overflow: hidden;">
                        <h2 style="float: left;">Verfügbare Dateien</h2>
                        <button id="refreshBtn" class="refresh-btn" onclick="loadFiles()">Aktualisieren</button>
                    </div>
                    
                    <div id="loading" class="loading">
                        <div class="spinner"></div>
                    </div>
                    
                    <div id="filesList" class="files-list"></div>
                </div>
            </div>
            
            <footer>
                &copy; {time.strftime('%Y')} Datei-Upload-Service
            </footer>
            
            <script>
                // DOM-Elemente
                const dropArea = document.getElementById('dropArea');
                const fileInput = document.getElementById('fileInput');
                const fileInfo = document.getElementById('fileInfo');
                const uploadBtn = document.getElementById('uploadBtn');
                const alertSuccess = document.getElementById('alertSuccess');
                const alertError = document.getElementById('alertError');
                const uploadProgress = document.getElementById('uploadProgress');
                const progressBar = document.getElementById('progressBar');
                const loading = document.getElementById('loading');
                const filesList = document.getElementById('filesList');
                
                // Event-Listener für Drag & Drop
                ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {{
                    dropArea.addEventListener(eventName, preventDefaults, false);
                }});
                
                function preventDefaults(e) {{
                    e.preventDefault();
                    e.stopPropagation();
                }}
                
                ['dragenter', 'dragover'].forEach(eventName => {{
                    dropArea.addEventListener(eventName, highlight, false);
                }});
                
                ['dragleave', 'drop'].forEach(eventName => {{
                    dropArea.addEventListener(eventName, unhighlight, false);
                }});
                
                function highlight() {{
                    dropArea.classList.add('highlight');
                }}
                
                function unhighlight() {{
                    dropArea.classList.remove('highlight');
                }}
                
                // Event-Handler für Datei-Drop
                dropArea.addEventListener('drop', handleDrop, false);
                
                function handleDrop(e) {{
                    const dt = e.dataTransfer;
                    const files = dt.files;
                    handleFiles(files);
                }}
                
                // Event-Handler für Dateiauswahl
                fileInput.addEventListener('change', function() {{
                    handleFiles(this.files);
                }});
                
                // Datei verarbeiten
                function handleFiles(files) {{
                    if (files.length > 0) {{
                        const file = files[0];
                        fileInfo.textContent = `${{file.name}} (${{formatFileSize(file.size)}})`;
                        uploadBtn.style.display = 'inline-block';
                    }}
                }}
                
                // Event-Handler für Upload-Button
                uploadBtn.addEventListener('click', uploadFile);
                
                // Datei hochladen
                function uploadFile() {{
                    const file = fileInput.files[0];
                    if (!file) return;
                    
                    // FormData erstellen
                    const formData = new FormData();
                    formData.append('file', file);
                    
                    // UI-Status zurücksetzen
                    alertSuccess.style.display = 'none';
                    alertError.style.display = 'none';
                    uploadProgress.style.display = 'block';
                    progressBar.style.width = '0%';
                    uploadBtn.disabled = true;
                    
                    // Datei hochladen mit Fortschrittsanzeige
                    const xhr = new XMLHttpRequest();
                    
                    xhr.upload.addEventListener('progress', function(e) {{
                        if (e.lengthComputable) {{
                            const percentComplete = (e.loaded / e.total) * 100;
                            progressBar.style.width = percentComplete + '%';
                        }}
                    }});
                    
                    xhr.addEventListener('load', function() {{
                        uploadProgress.style.display = 'none';
                        uploadBtn.disabled = false;
                        
                        if (xhr.status === 200) {{
                            const response = JSON.parse(xhr.responseText);
                            
                            if (response.success) {{
                                // Erfolgreich
                                alertSuccess.style.display = 'block';
                                setTimeout(() => alertSuccess.style.display = 'none', 3000);
                                
                                // Formular zurücksetzen
                                fileInput.value = '';
                                fileInfo.textContent = '';
                                uploadBtn.style.display = 'none';
                                
                                // Dateien neu laden
                                loadFiles();
                            }} else {{
                                // Fehler
                                alertError.textContent = response.error || 'Beim Hochladen der Datei ist ein Fehler aufgetreten.';
                                alertError.style.display = 'block';
                            }}
                        }} else {{
                            // HTTP-Fehler
                            alertError.textContent = 'HTTP-Fehler: ' + xhr.status;
                            alertError.style.display = 'block';
                        }}
                    }});
                    
                    xhr.addEventListener('error', function() {{
                        uploadProgress.style.display = 'none';
                        uploadBtn.disabled = false;
                        
                        alertError.textContent = 'Ein Netzwerkfehler ist aufgetreten.';
                        alertError.style.display = 'block';
                    }});
                    
                    xhr.open('POST', '/upload');
                    xhr.send(formData);
                }}
                
                // Dateien laden
                function loadFiles() {{
                    loading.style.display = 'flex';
                    filesList.innerHTML = '';
                    
                    fetch('/list-files')
                        .then(response => response.json())
                        .then(files => {{
                            loading.style.display = 'none';
                            
                            if (files.length === 0) {{
                                filesList.innerHTML = '<div class="empty-message">Keine Dateien vorhanden</div>';
                                return;
                            }}
                            
                            // Dateien nach Datum sortieren (neueste zuerst)
                            files.sort((a, b) => b.timestamp - a.timestamp);
                            
                            // Dateien anzeigen
                            files.forEach(file => {{
                                const fileItem = document.createElement('div');
                                fileItem.className = 'file-item';
                                
                                const fileIcon = document.createElement('div');
                                fileIcon.className = 'file-icon';
                                fileIcon.innerHTML = getFileIcon(file.name);
                                
                                const fileDetails = document.createElement('div');
                                fileDetails.className = 'file-details';
                                
                                const fileName = document.createElement('div');
                                fileName.className = 'file-name';
                                fileName.textContent = file.name;
                                
                                const fileMeta = document.createElement('div');
                                fileMeta.className = 'file-meta';
                                fileMeta.textContent = `${{formatFileSize(file.size)}} • Hochgeladen am ${{formatDate(file.timestamp)}}`;
                                
                                fileDetails.appendChild(fileName);
                                fileDetails.appendChild(fileMeta);
                                
                                const fileActions = document.createElement('div');
                                fileActions.className = 'file-actions';
                                
                                const downloadLink = document.createElement('a');
                                downloadLink.href = file.download_url;
                                downloadLink.className = 'download-link';
                                downloadLink.textContent = 'Download';
                                downloadLink.setAttribute('download', '');
                                
                                const copyLink = document.createElement('button');
                                copyLink.className = 'copy-link';
                                copyLink.textContent = 'Link kopieren';
                                copyLink.onclick = function() {{
                                    copyToClipboard(file.full_url);
                                    this.textContent = 'Kopiert!';
                                    setTimeout(() => this.textContent = 'Link kopieren', 2000);
                                }};
                                
                                fileActions.appendChild(downloadLink);
                                fileActions.appendChild(copyLink);
                                
                                fileItem.appendChild(fileIcon);
                                fileItem.appendChild(fileDetails);
                                fileItem.appendChild(fileActions);
                                
                                const shareLink = document.createElement('div');
                                shareLink.className = 'share-link';
                                shareLink.textContent = file.full_url;
                                
                                fileItem.appendChild(shareLink);
                                
                                filesList.appendChild(fileItem);
                            }});
                        }})
                        .catch(error => {{
                            loading.style.display = 'none';
                            filesList.innerHTML = `<div class="empty-message">Fehler beim Laden der Dateien: ${{error.message}}</div>`;
                        }});
                }}
                
                // Hilfsfunktionen
                function formatFileSize(bytes) {{
                    if (bytes < 1024) return bytes + ' Bytes';
                    else if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
                    else if (bytes < 1073741824) return (bytes / 1048576).toFixed(1) + ' MB';
                    else return (bytes / 1073741824).toFixed(1) + ' GB';
                }}
                
                function formatDate(timestamp) {{
                    const date = new Date(timestamp * 1000);
                    return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
                }}
                
                function copyToClipboard(text) {{
                    navigator.clipboard.writeText(text).catch(err => {{
                        console.error('Fehler beim Kopieren: ', err);
                        
                        // Fallback für Browser ohne Clipboard API
                        const textarea = document.createElement('textarea');
                        textarea.value = text;
                        textarea.style.position = 'fixed';
                        document.body.appendChild(textarea);
                        textarea.select();
                        
                        try {{
                            document.execCommand('copy');
                        }} catch (err) {{
                            console.error('Fallback fehlgeschlagen:', err);
                        }}
                        
                        document.body.removeChild(textarea);
                    }});
                }}
                
                function getFileIcon(filename) {{
                    const ext = filename.split('.').pop().toLowerCase();
                    
                    // Einfache Datei-Icon-Zuordnung
                    const iconMap = {{
                        'pdf': '📄',
                        'doc': '📝',
                        'docx': '📝',
                        'xls': '📊',
                        'xlsx': '📊',
                        'ppt': '📊',
                        'pptx': '📊',
                        'txt': '📝',
                        'jpg': '🖼️',
                        'jpeg': '🖼️',
                        'png': '🖼️',
                        'gif': '🖼️',
                        'svg': '🖼️',
                        'mp3': '🎵',
                        'mp4': '🎬',
                        'zip': '📦',
                        'rar': '📦',
                        '7z': '📦',
                        'exe': '⚙️',
                        'html': '🌐',
                        'css': '🌐',
                        'js': '🌐',
                    }};
                    
                    return iconMap[ext] || '📄';
                }}
                
                // Automatischer Reconnect, wenn die Verbindung unterbrochen wird
                let reconnectAttempts = 0;
                
                function checkServerConnection() {{
                    fetch('/health-check', {{
                        method: 'HEAD',
                        cache: 'no-store'
                    }})
                    .catch(() => {{
                        reconnectAttempts++;
                        if (reconnectAttempts <= 3) {{
                            // Nach 5 Sekunden erneut versuchen
                            setTimeout(checkServerConnection, 5000);
                        }} else {{
                            // Bei wiederholten Fehlern die Seite neu laden
                            location.reload();
                        }}
                    }})
                    .then(response => {{
                        if (response && response.ok) {{
                            // Verbindung wiederhergestellt
                            reconnectAttempts = 0;
                        }}
                    }});
                }}
                
                // Wenn ein Netzwerkfehler auftritt, sofort versuchen erneut zu verbinden
                window.addEventListener('offline', () => {{
                    // Warten auf Online-Status
                    window.addEventListener('online', () => {{
                        checkServerConnection();
                    }}, {{once: true}});
                }});
                
                // Dateien beim Laden der Seite laden
                document.addEventListener('DOMContentLoaded', loadFiles);
                
                // Alle 60 Sekunden prüfen, ob der Server noch erreichbar ist
                setInterval(checkServerConnection, 60000);
            </script>
        </body>
        </html>
        """
    
    def generate_admin_page(self):
        """Generiert die Admin-Seite"""
        return """
        <!DOCTYPE html>
        <html lang="de">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Vantastic Uploads</title>
            <style>
                :root {
                    --primary-color: #2196F3;
                    --primary-dark: #1976D2;
                    --accent-color: #FF4081;
                    --accent-dark: #F50057;
                    --success-color: #4CAF50;
                    --success-dark: #388E3C;
                    --error-color: #F44336;
                    --error-dark: #D32F2F;
                    --admin-color: #9c27b0;
                    --admin-dark: #7b1fa2;
                    --text-color: #333;
                    --light-text: #757575;
                    --bg-color: #fff;
                    --light-bg: #f5f5f5;
                    --border-color: #ddd;
                }
                
                body {
                    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                    line-height: 1.6;
                    color: var(--text-color);
                    background-color: var(--bg-color);
                    margin: 0;
                    padding: 0;
                }
                
                .container {
                    max-width: 1000px;
                    margin: 0 auto;
                    padding: 20px;
                }
                
                header {
                    background-color: var(--admin-color);
                    color: white;
                    padding: 1rem;
                    text-align: center;
                }
                
                h1 {
                    margin: 0;
                    font-size: 1.8rem;
                }
                
                h2 {
                    color: var(--admin-dark);
                    margin-top: 2rem;
                    margin-bottom: 1rem;
                    border-bottom: 2px solid var(--admin-color);
                    padding-bottom: 0.5rem;
                }
                
                .admin-toolbar {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    margin-bottom: 20px;
                }
                
                .admin-toolbar .btn {
                    margin-right: 10px;
                }
                
                .search-container {
                    display: flex;
                    margin-bottom: 20px;
                }
                
                .search-input {
                    flex: 1;
                    padding: 10px;
                    border: 1px solid var(--border-color);
                    border-radius: 4px 0 0 4px;
                    font-size: 16px;
                }
                
                .search-btn {
                    background-color: var(--admin-color);
                    color: white;
                    border: none;
                    padding: 10px 20px;
                    border-radius: 0 4px 4px 0;
                    cursor: pointer;
                    font-size: 16px;
                }
                
                .search-btn:hover {
                    background-color: var(--admin-dark);
                }
                
                .files-list {
                    border: 1px solid var(--border-color);
                    border-radius: 8px;
                    overflow: hidden;
                }
                
                .file-item {
                    padding: 15px;
                    border-bottom: 1px solid var(--border-color);
                    display: flex;
                    align-items: center;
                    transition: background-color 0.2s;
                }
                
                .file-item:last-child {
                    border-bottom: none;
                }
                
                .file-item:nth-child(odd) {
                    background-color: rgba(0, 0, 0, 0.02);
                }
                
                .file-item:hover {
                    background-color: rgba(0, 0, 0, 0.05);
                }
                
                .file-icon {
                    margin-right: 15px;
                    color: var(--admin-color);
                    font-size: 24px;
                }
                
                .file-details {
                    flex: 1;
                }
                
                .file-name {
                    font-weight: bold;
                }
                
                .file-meta {
                    font-size: 14px;
                    color: var(--light-text);
                    margin-top: 5px;
                }
                
                .file-actions {
                    display: flex;
                    gap: 10px;
                    align-items: center;
                    min-width: 150px;
                    justify-content: flex-end;
                }
                
                .btn {
                    border: none;
                    padding: 8px 15px;
                    border-radius: 4px;
                    cursor: pointer;
                    font-size: 14px;
                    transition: background-color 0.3s;
                }
                
                .btn-home {
                    background-color: var(--primary-color);
                    color: white;
                    text-decoration: none;
                }
                
                .btn-home:hover {
                    background-color: var(--primary-dark);
                }
                
                .btn-download {
                    background-color: var(--primary-color);
                    color: white;
                    text-decoration: none;
                }
                
                .btn-download:hover {
                    background-color: var(--primary-dark);
                }
                
                .btn-delete {
                    background-color: var(--error-color);
                    color: white;
                }
                
                .btn-delete:hover {
                    background-color: var(--error-dark);
                }
                
                .alert {
                    padding: 15px;
                    border-radius: 4px;
                    margin-bottom: 20px;
                }
                
                .alert-success {
                    background-color: rgba(76, 175, 80, 0.1);
                    border: 1px solid rgba(76, 175, 80, 0.2);
                    color: var(--success-dark);
                }
                
                .alert-error {
                    background-color: rgba(244, 67, 54, 0.1);
                    border: 1px solid rgba(244, 67, 54, 0.2);
                    color: var(--error-dark);
                }
                
                .loading {
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    padding: 20px;
                }
                
                .spinner {
                    border: 4px solid rgba(0, 0, 0, 0.1);
                    width: 36px;
                    height: 36px;
                    border-radius: 50%;
                    border-left-color: var(--admin-color);
                    animation: spin 1s linear infinite;
                }
                
                @keyframes spin {
                    0% { transform: rotate(0deg); }
                    100% { transform: rotate(360deg); }
                }
                
                .empty-message {
                    text-align: center;
                    padding: 30px;
                    color: var(--light-text);
                }
                
                .confirmation-modal {
                    display: none;
                    position: fixed;
                    z-index: 1000;
                    left: 0;
                    top: 0;
                    width: 100%;
                    height: 100%;
                    background-color: rgba(0, 0, 0, 0.5);
                }
                
                .modal-content {
                    background-color: #fff;
                    margin: 15% auto;
                    padding: 20px;
                    border-radius: 8px;
                    max-width: 500px;
                    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
                }
                
                .close-modal {
                    color: #aaa;
                    float: right;
                    font-size: 28px;
                    font-weight: bold;
                    cursor: pointer;
                }
                
                .close-modal:hover {
                    color: black;
                }
                
                .modal-title {
                    margin-top: 0;
                    color: var(--error-dark);
                }
                
                .modal-actions {
                    display: flex;
                    justify-content: flex-end;
                    margin-top: 20px;
                    gap: 10px;
                }
                
                .pagination {
                    display: flex;
                    justify-content: center;
                    margin-top: 20px;
                    gap: 5px;
                }
                
                .pagination button {
                    padding: 8px 12px;
                    border: 1px solid var(--border-color);
                    background-color: white;
                    border-radius: 4px;
                    cursor: pointer;
                }
                
                .pagination button.active {
                    background-color: var(--admin-color);
                    color: white;
                    border-color: var(--admin-color);
                }
                
                .pagination button:hover:not(.active) {
                    background-color: #f0f0f0;
                }
                
                .pagination .disabled {
                    opacity: 0.5;
                    cursor: not-allowed;
                }
                
                footer {
                    margin-top: 30px;
                    padding: 20px;
                    text-align: center;
                    color: var(--light-text);
                    font-size: 14px;
                }
                
                /* Responsive */
                @media (max-width: 768px) {
                    .file-item {
                        flex-direction: column;
                        align-items: flex-start;
                    }
                    
                    .file-icon {
                        margin-right: 0;
                        margin-bottom: 10px;
                    }
                    
                    .file-actions {
                       	display: flex;
   			gap: 10px;
    			align-items: center;
    			min-width: 150px; /* Sorgt für konsistente Breite */
    			justify-content: flex-end; /* Buttons rechts ausrichten */
                    }
                    
                    .admin-toolbar {
                        flex-direction: column;
                        align-items: flex-start;
                    }
                    
                    .admin-toolbar .btn {
                        margin-bottom: 10px;
                    }
                }
            </style>
        </head>
        <body>
            <header>
                <h1>Vantastic Uploads</h1>
            </header>
            
            <div class="container">
                <div class="admin-toolbar">
                    <a href="/" class="btn btn-home">Zurück zur Startseite</a>
                </div>
                
                <div id="alertContainer"></div>
                
                <div class="search-container">
                    <input type="text" id="searchInput" class="search-input" placeholder="Dateien suchen...">
                    <button id="searchBtn" class="search-btn">Suchen</button>
                </div>
                
                <div id="loading" class="loading">
                    <div class="spinner"></div>
                </div>
                
                <div id="filesList" class="files-list"></div>
                <div id="pagination" class="pagination"></div>
                
                <div id="confirmationModal" class="confirmation-modal">
                    <div class="modal-content">
                        <span class="close-modal" onclick="closeModal()">&times;</span>
                        <h3 class="modal-title">Datei löschen</h3>
                        <p>Sind Sie sicher, dass Sie die Datei <strong id="fileToDelete"></strong> löschen möchten?</p>
                        <p>Diese Aktion kann nicht rückgängig gemacht werden.</p>
                        <div class="modal-actions">
                            <button class="btn" onclick="closeModal()">Abbrechen</button>
                            <button id="confirmDeleteBtn" class="btn btn-delete">Löschen</button>
                        </div>
                    </div>
                </div>
            </div>
            
            <footer>
                &copy; 2025 Datei-Verwaltung | Admin-Bereich
            </footer>
            
            <script>
                // DOM-Elemente
                const loading = document.getElementById('loading');
                const filesList = document.getElementById('filesList');
                const pagination = document.getElementById('pagination');
                const alertContainer = document.getElementById('alertContainer');
                const searchInput = document.getElementById('searchInput');
                const searchBtn = document.getElementById('searchBtn');
                const confirmationModal = document.getElementById('confirmationModal');
                const fileToDeleteElem = document.getElementById('fileToDelete');
                const confirmDeleteBtn = document.getElementById('confirmDeleteBtn');
                
                // Status
                let allFiles = [];
                let filteredFiles = [];
                let currentPage = 1;
                const filesPerPage = 10;
                let fileToDelete = '';
                
                // Event-Listener
                searchBtn.addEventListener('click', filterFiles);
                searchInput.addEventListener('keypress', function(e) {
                    if (e.key === 'Enter') {
                        filterFiles();
                    }
                });
                
                // Dateien laden
                function loadFiles() {
                    loading.style.display = 'flex';
                    filesList.innerHTML = '';
                    pagination.innerHTML = '';
                    
                    fetch('/list-files')
                        .then(response => response.json())
                        .then(files => {
                            loading.style.display = 'none';
                            
                            // Dateien nach Datum sortieren (neueste zuerst)
                            files.sort((a, b) => b.timestamp - a.timestamp);
                            
                            allFiles = files;
                            filteredFiles = [...files];
                            
                            if (files.length === 0) {
                                filesList.innerHTML = '<div class="empty-message">Keine Dateien vorhanden</div>';
                                return;
                            }
                            
                            displayFiles();
                        })
                        .catch(error => {
                            loading.style.display = 'none';
                            filesList.innerHTML = `<div class="empty-message">Fehler beim Laden der Dateien: ${error.message}</div>`;
                            
                            // Bei Verbindungsfehlern nach einer Weile erneut versuchen
                            setTimeout(loadFiles, 5000);
                        });
                }
                
                // Dateien anzeigen
                function displayFiles() {
                    filesList.innerHTML = '';
                    
                    // Keine Dateien gefunden
                    if (filteredFiles.length === 0) {
                        filesList.innerHTML = '<div class="empty-message">Keine Dateien gefunden</div>';
                        pagination.innerHTML = '';
                        return;
                    }
                    
                    // Paginierung berechnen
                    const totalPages = Math.ceil(filteredFiles.length / filesPerPage);
                    const startIndex = (currentPage - 1) * filesPerPage;
                    const endIndex = Math.min(startIndex + filesPerPage, filteredFiles.length);
                    
                    // Aktuell angezeigte Dateien
                    const currentFiles = filteredFiles.slice(startIndex, endIndex);
                    
                    // Dateien anzeigen
                    currentFiles.forEach(file => {
                        const fileItem = document.createElement('div');
                        fileItem.className = 'file-item';
                        
                        const fileIcon = document.createElement('div');
                        fileIcon.className = 'file-icon';
                        fileIcon.innerHTML = getFileIcon(file.name);
                        
                        const fileDetails = document.createElement('div');
                        fileDetails.className = 'file-details';
                        
                        const fileName = document.createElement('div');
                        fileName.className = 'file-name';
                        fileName.textContent = file.name;
                        
                        const fileMeta = document.createElement('div');
                        fileMeta.className = 'file-meta';
                        fileMeta.textContent = `${formatFileSize(file.size)} • Hochgeladen am ${formatDate(file.timestamp)}`;
                        
                        fileDetails.appendChild(fileName);
                        fileDetails.appendChild(fileMeta);
                        
                        const fileActions = document.createElement('div');
                        fileActions.className = 'file-actions';
                        
                        const downloadLink = document.createElement('a');
                        downloadLink.href = file.download_url;
                        downloadLink.className = 'btn btn-download';
                        downloadLink.textContent = 'Download';
                        downloadLink.setAttribute('download', '');
                        
                        const deleteBtn = document.createElement('button');
                        deleteBtn.className = 'btn btn-delete';
                        deleteBtn.textContent = 'Löschen';
                        deleteBtn.onclick = function() {
                            showDeleteConfirmation(file.name);
                        };
                        
                        fileActions.appendChild(downloadLink);
                        fileActions.appendChild(deleteBtn);
                        
                        fileItem.appendChild(fileIcon);
                        fileItem.appendChild(fileDetails);
                        fileItem.appendChild(fileActions);
                        
                        filesList.appendChild(fileItem);
                    });
                    
                    // Paginierung anzeigen
                    updatePagination(totalPages);
                }
                
                // Paginierung aktualisieren
                function updatePagination(totalPages) {
                    pagination.innerHTML = '';
                    
                    if (totalPages <= 1) return;
                    
                    // Zurück-Button
                    const prevBtn = document.createElement('button');
                    prevBtn.textContent = '«';
                    prevBtn.disabled = currentPage === 1;
                    prevBtn.className = currentPage === 1 ? 'disabled' : '';
                    prevBtn.onclick = function() {
                        if (currentPage > 1) {
                            currentPage--;
                            displayFiles();
                        }
                    };
                    pagination.appendChild(prevBtn);
                    
                    // Seitenzahlen
                    const maxPages = 5;
                    let startPage = Math.max(1, currentPage - Math.floor(maxPages / 2));
                    let endPage = Math.min(totalPages, startPage + maxPages - 1);
                    
                    if (endPage - startPage + 1 < maxPages) {
                        startPage = Math.max(1, endPage - maxPages + 1);
                    }
                    
                    for (let i = startPage; i <= endPage; i++) {
                        const pageBtn = document.createElement('button');
                        pageBtn.textContent = i;
                        pageBtn.className = i === currentPage ? 'active' : '';
                        pageBtn.onclick = function() {
                            currentPage = i;
                            displayFiles();
                        };
                        pagination.appendChild(pageBtn);
                    }
                    
                    // Weiter-Button
                    const nextBtn = document.createElement('button');
                    nextBtn.textContent = '»';
                    nextBtn.disabled = currentPage === totalPages;
                    nextBtn.className = currentPage === totalPages ? 'disabled' : '';
                    nextBtn.onclick = function() {
                        if (currentPage < totalPages) {
                            currentPage++;
                            displayFiles();
                        }
                    };
                    pagination.appendChild(nextBtn);
                }
                
                // Suchen/Filtern
                function filterFiles() {
                    const searchTerm = searchInput.value.trim().toLowerCase();
                    
                    if (searchTerm === '') {
                        filteredFiles = [...allFiles];
                    } else {
                        filteredFiles = allFiles.filter(file => 
                            file.name.toLowerCase().includes(searchTerm)
                        );
                    }
                    
                    currentPage = 1;
                    displayFiles();
                }
                
                // Löschen-Dialog anzeigen
                function showDeleteConfirmation(filename) {
                    fileToDelete = filename;
                    fileToDeleteElem.textContent = filename;
                    confirmationModal.style.display = 'block';
                    
                    confirmDeleteBtn.onclick = function() {
                        deleteFile(filename);
                    };
                }
                
                // Modal schließen
                function closeModal() {
                    confirmationModal.style.display = 'none';
                }
                
                // Datei löschen
                function deleteFile(filename) {
                    loading.style.display = 'flex';
                    
                    fetch('/delete-file', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify({ filename: filename })
                    })
                    .then(response => {
                        if (!response.ok) {
                            throw new Error('Server-Fehler: ' + response.status);
                        }
                        return response.json();
                    })
                    .then(data => {
                        loading.style.display = 'none';
                        closeModal();
                        
                        if (data.success) {
                            showAlert('Die Datei wurde erfolgreich gelöscht.', 'success');
                            
                            // Dateien neu laden
                            loadFiles();
                        } else {
                            showAlert(`Fehler: ${data.error || 'Unbekannter Fehler'}`, 'error');
                        }
                    })
                    .catch(error => {
                        loading.style.display = 'none';
                        closeModal();
                        showAlert(`Fehler: ${error.message}`, 'error');
                        
                        // Bei Netzwerkfehlern später erneut versuchen
                        setTimeout(loadFiles, 5000);
                    });
                }
                
                // Hilfsfunktionen
                function showAlert(message, type) {
                    const alert = document.createElement('div');
                    alert.className = `alert alert-${type}`;
                    alert.textContent = message;
                    
                    alertContainer.innerHTML = '';
                    alertContainer.appendChild(alert);
                    
                    setTimeout(() => {
                        alert.style.opacity = '0';
                        alert.style.transition = 'opacity 0.5s';
                        
                        setTimeout(() => {
                            if (alertContainer.contains(alert)) {
                                alertContainer.removeChild(alert);
                            }
                        }, 500);
                    }, 3000);
                }
                
                function formatFileSize(bytes) {
                    if (bytes < 1024) return bytes + ' Bytes';
                    else if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
                    else if (bytes < 1073741824) return (bytes / 1048576).toFixed(1) + ' MB';
                    else return (bytes / 1073741824).toFixed(1) + ' GB';
                }
                
                function formatDate(timestamp) {
                    const date = new Date(timestamp * 1000);
                    return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
                }
                
                function getFileIcon(filename) {
                    const ext = filename.split('.').pop().toLowerCase();
                    
                    // Einfache Datei-Icon-Zuordnung
                    const iconMap = {
                        'pdf': '📄',
                        'doc': '📝',
                        'docx': '📝',
                        'xls': '📊',
                        'xlsx': '📊',
                        'ppt': '📊',
                        'pptx': '📊',
                        'txt': '📝',
                        'jpg': '🖼️',
                        'jpeg': '🖼️',
                        'png': '🖼️',
                        'gif': '🖼️',
                        'svg': '🖼️',
                        'mp3': '🎵',
                        'mp4': '🎬',
                        'zip': '📦',
                        'rar': '📦',
                        '7z': '📦',
                        'exe': '⚙️',
                        'html': '🌐',
                        'css': '🌐',
                        'js': '🌐',
                    };
                    
                    return iconMap[ext] || '📄';
                }
                
                // Klick außerhalb des Modals schließt es
                window.onclick = function(event) {
                    if (event.target === confirmationModal) {
                        closeModal();
                    }
                };
                
                // Escape-Taste schließt das Modal
                document.addEventListener('keydown', function(event) {
                    if (event.key === 'Escape') {
                        closeModal();
                    }
                });
                
                // Automatischer Reconnect, wenn die Verbindung unterbrochen wird
                let reconnectAttempts = 0;
                
                function checkServerConnection() {
                    fetch('/health-check', {
                        method: 'HEAD',
                        cache: 'no-store'
                    })
                    .catch(() => {
                        reconnectAttempts++;
                        if (reconnectAttempts <= 3) {
                            // Nach 5 Sekunden erneut versuchen
                            setTimeout(checkServerConnection, 5000);
                        } else {
                            // Bei wiederholten Fehlern die Seite neu laden
                            location.reload();
                        }
                    })
                    .then(response => {
                        if (response && response.ok) {
                            // Verbindung wiederhergestellt
                            reconnectAttempts = 0;
                        }
                    });
                }
                
                // Wenn ein Netzwerkfehler auftritt, sofort versuchen erneut zu verbinden
                window.addEventListener('offline', () => {
                    // Warten auf Online-Status
                    window.addEventListener('online', () => {
                        checkServerConnection();
                    }, {once: true});
                });
                
                // Dateien beim Laden der Seite laden
                document.addEventListener('DOMContentLoaded', loadFiles);
                
                // Alle 60 Sekunden prüfen, ob der Server noch erreichbar ist
                setInterval(checkServerConnection, 60000);
            </script>
        </body>
        </html>
        """
    
    def do_GET(self):
        try:
            path = urllib.parse.urlparse(self.path).path
            
            # Health-Check Endpunkt für Client-Reconnect
            if path == '/health-check':
                self.send_response(200)
                self.send_header('Content-Type', 'application/json')
                self.end_headers()
                self.wfile.write(json.dumps({'status': 'ok'}).encode('utf-8'))
                return
            
            # Hauptseite
            if path == '/':
                self.send_html_response(self.generate_main_page())
                return
            
            # Admin-Bereich
            if path == '/admin':
                if not self.check_admin_auth():
                    self.request_admin_auth()
                    return
                
                self.send_html_response(self.generate_admin_page())
                return
            
            # Liste der Dateien abfragen
            if path == '/list-files':
                file_list = []
                
                try:
                    for filename in os.listdir(UPLOAD_DIR):
                        file_path = os.path.join(UPLOAD_DIR, filename)
                        if os.path.isfile(file_path):
                            file_size = os.path.getsize(file_path)
                            file_mtime = os.path.getmtime(file_path)
                            
                            file_info = {
                                'name': filename,
                                'size': file_size,
                                'timestamp': int(file_mtime),
                                'download_url': f'/uploads/{filename}',
                                'full_url': f'http://{SERVER_ADDRESS}/uploads/{filename}'
                            }
                            
                            file_list.append(file_info)
                except Exception as e:
                    log_message(f"Fehler beim Lesen des Upload-Verzeichnisses: {str(e)}", "ERROR")
                
                self.send_json_response(file_list)
                return
            
            # Datei herunterladen
            if path.startswith('/uploads/'):
                filename = path.split('/')[-1]
                file_path = os.path.join(UPLOAD_DIR, filename)
                
                if os.path.exists(file_path) and os.path.isfile(file_path):
                    try:
                        # MIME-Typ bestimmen
                        content_type, _ = mimetypes.guess_type(file_path)
                        if not content_type:
                            content_type = 'application/octet-stream'
                        
                        # Datei senden
                        file_size = os.path.getsize(file_path)
                        self.send_response(200)
                        self.send_header('Content-Type', content_type)
                        self.send_header('Content-Length', str(file_size))
                        self.send_header('Content-Disposition', f'attachment; filename="{filename}"')
                        self.end_headers()
                        
                        # Datei in Chunks lesen und senden, um Speicherverbrauch zu reduzieren
                        with open(file_path, 'rb') as f:
                            chunk_size = 8192  # 8K Chunks
                            while True:
                                chunk = f.read(chunk_size)
                                if not chunk:
                                    break
                                try:
                                    self.wfile.write(chunk)
                                except (BrokenPipeError, ConnectionResetError):
                                    log_message(f"Client hat die Verbindung beim Herunterladen von {filename} abgebrochen", "WARNING")
                                    break
                        
                        log_message(f"Datei {filename} wurde heruntergeladen", "INFO")
                        return
                    except Exception as e:
                        log_message(f"Fehler beim Senden der Datei {filename}: {str(e)}", "ERROR")
                        self.send_error_response(f"Fehler beim Herunterladen der Datei: {str(e)}")
                        return
                else:
                    self.send_error_response('Die angeforderte Datei wurde nicht gefunden.', 404)
                    return
            
            # Standardmäßig 404
            self.send_error_response('Die angeforderte Seite wurde nicht gefunden.', 404)
        
        except Exception as e:
            log_message(f"Fehler beim Verarbeiten der GET-Anfrage: {str(e)}", "ERROR")
            traceback.print_exc()
            try:
                self.send_error_response(f"Ein Fehler ist aufgetreten: {str(e)}")
            except:
                pass
    
    def do_POST(self):
        try:
            path = urllib.parse.urlparse(self.path).path
            
            # Datei hochladen
            if path == '/upload':
                try:
                    content_type = self.headers.get('Content-Type', '')
                    
                    # Content-Type überprüfen
                    if not content_type.startswith('multipart/form-data'):
                        self.send_json_response({'success': False, 'error': 'Ungültiger Content-Type'}, 400)
                        return
                    
                    # Boundary aus dem Content-Type extrahieren
                    boundary = content_type.split('=')[1].strip()
                    
                    # Content-Length überprüfen
                    content_length = int(self.headers.get('Content-Length', 0))
                    if content_length <= 0:
                        self.send_json_response({'success': False, 'error': 'Keine Daten gesendet'}, 400)
                        return
                    
                    # Daten lesen
                    post_data = self.rfile.read(content_length)
                    
                    # Multipart-Daten verarbeiten
                    boundary_bytes = f'--{boundary}'.encode()
                    parts = post_data.split(boundary_bytes)
                    
                    # Datei aus den Multipart-Daten extrahieren
                    file_data = None
                    file_name = None
                    
                    for part in parts:
                        # Nach Content-Disposition und Dateinamen suchen
                        match = re.search(b'Content-Disposition: form-data; name="file"; filename="(.*?)"', part)
                        if match:
                            file_name = match.group(1).decode('utf-8', 'replace')
                            
                            # Header vom Inhalt trennen
                            header_end = part.find(b'\r\n\r\n')
                            if header_end > 0:
                                file_data = part[header_end + 4:]
                                # Abschließenden Zeilenumbruch entfernen
                                if file_data.endswith(b'\r\n'):
                                    file_data = file_data[:-2]
                            break

                    if not file_data or not file_name:
                        self.send_json_response({'success': False, 'error': 'Keine Datei gefunden'}, 400)
                        return

                    # Eindeutigen Dateinamen erstellen
                    safe_filename = self.get_safe_filename(file_name)
                    timestamp = int(time.time())
                    unique_filename = safe_filename
                    file_path = os.path.join(UPLOAD_DIR, unique_filename)

                    # Datei speichern
                    with open(file_path, 'wb') as f:
                        f.write(file_data)

                    log_message(f"Datei {unique_filename} wurde hochgeladen", "INFO")
                    
                    # Erfolgreiche Antwort senden
                    self.send_json_response({
                        'success': True,
                        'filename': safe_filename,
                        'stored_as': unique_filename,
                        'size': len(file_data),
                        'timestamp': timestamp,
                        'download_url': f'/uploads/{unique_filename}',
                        'full_url': f'http://{SERVER_ADDRESS}/uploads/{unique_filename}'
                    })
                    return
                except Exception as e:
                    log_message(f"Fehler beim Hochladen der Datei: {str(e)}", "ERROR")
                    traceback.print_exc()
                    self.send_json_response({'success': False, 'error': f'Fehler beim Hochladen: {str(e)}'}, 500)
                    return
            
            # Datei löschen
            if path == '/delete-file':
                try:
                    # Admin-Berechtigungen prüfen
                    if not self.check_admin_auth():
                        self.send_json_response({'success': False, 'error': 'Nicht autorisiert'}, 401)
                        return
                    
                    # Content-Type überprüfen
                    content_type = self.headers.get('Content-Type', '')
                    if content_type != 'application/json':
                        self.send_json_response({'success': False, 'error': 'Ungültiger Content-Type'}, 400)
                        return
                    
                    # Content-Length überprüfen
                    content_length = int(self.headers.get('Content-Length', 0))
                    if content_length <= 0:
                        self.send_json_response({'success': False, 'error': 'Keine Daten gesendet'}, 400)
                        return
                    
                    # Daten lesen und parsen
                    post_data = self.rfile.read(content_length).decode('utf-8')
                    try:
                        data = json.loads(post_data)
                    except json.JSONDecodeError:
                        self.send_json_response({'success': False, 'error': 'Ungültiges JSON'}, 400)
                        return
                    
                    # Dateinamen überprüfen
                    filename = data.get('filename')
                    if not filename:
                        self.send_json_response({'success': False, 'error': 'Kein Dateiname angegeben'}, 400)
                        return
                    
                    # Pfadmanipulation verhindern
                    if '..' in filename or filename.startswith('/'):
                        self.send_json_response({'success': False, 'error': 'Ungültiger Dateiname'}, 400)
                        return
                    
                    # Datei löschen
                    file_path = os.path.join(UPLOAD_DIR, filename)
                    if os.path.exists(file_path) and os.path.isfile(file_path):
                        try:
                            os.remove(file_path)
                            log_message(f"Datei {filename} wurde gelöscht", "INFO")
                            self.send_json_response({'success': True, 'message': f'Datei {filename} wurde gelöscht'})
                        except Exception as e:
                            log_message(f"Fehler beim Löschen der Datei {filename}: {str(e)}", "ERROR")
                            self.send_json_response({'success': False, 'error': f'Fehler beim Löschen: {str(e)}'}, 500)
                    else:
                        self.send_json_response({'success': False, 'error': 'Datei nicht gefunden'}, 404)
                    
                    return
                except Exception as e:
                    log_message(f"Fehler beim Löschen der Datei: {str(e)}", "ERROR")
                    traceback.print_exc()
                    self.send_json_response({'success': False, 'error': f'Ein Fehler ist aufgetreten: {str(e)}'}, 500)
                    return
            
            # Unbekannter Pfad
            self.send_json_response({'success': False, 'error': 'Unbekannter Endpunkt'}, 404)
        
        except Exception as e:
            log_message(f"Fehler beim Verarbeiten der POST-Anfrage: {str(e)}", "ERROR")
            traceback.print_exc()
            try:
                self.send_json_response({'success': False, 'error': f'Ein Fehler ist aufgetreten: {str(e)}'}, 500)
            except:
                pass
    
    def get_safe_filename(self, filename):
        """Erstellt einen sicheren Dateinamen"""
        # Ersetzt ungültige Zeichen mit Unterstrichen
        safe_name = re.sub(r'[^\w\.-]', '_', filename)
        return safe_name

class ThreadedHTTPServer(HTTPServer):
    """Handle requests in a separate thread."""
    def __init__(self, server_address, RequestHandlerClass):
        HTTPServer.__init__(self, server_address, RequestHandlerClass)
        self.daemon_threads = True
        
        # Timeouts setzen
        self.socket.settimeout(5)  # 5 Sekunden Socket-Timeout
        
        # Socket-Optionen für bessere Stabilität
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        
        # TCP Keep-Alive aktivieren
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
        
        # Zusätzliche TCP Keep-Alive Parameter, wenn verfügbar
        try:
            TCP_KEEPIDLE = getattr(socket, 'TCP_KEEPIDLE', None)
            if TCP_KEEPIDLE:
                self.socket.setsockopt(socket.IPPROTO_TCP, TCP_KEEPIDLE, 60)  # Beginne nach 60s
            
            TCP_KEEPINTVL = getattr(socket, 'TCP_KEEPINTVL', None)
            if TCP_KEEPINTVL:
                self.socket.setsockopt(socket.IPPROTO_TCP, TCP_KEEPINTVL, 10)  # 10s Intervall
            
            TCP_KEEPCNT = getattr(socket, 'TCP_KEEPCNT', None)
            if TCP_KEEPCNT:
                self.socket.setsockopt(socket.IPPROTO_TCP, TCP_KEEPCNT, 5)  # 5 Versuche
        except (AttributeError, OSError) as e:
            log_message(f"TCP Keep-Alive Einstellungen nicht verfügbar: {str(e)}", "WARNING")

# In das Skriptverzeichnis wechseln
script_dir = os.path.dirname(os.path.abspath(__file__))
if script_dir:
    os.chdir(script_dir)

# Server starten
log_message(f"Server startet auf http://{SERVER_ADDRESS}:{PORT}", "INFO")
log_message(f"Upload-Verzeichnis: {os.path.abspath(UPLOAD_DIR)}", "INFO")
log_message(f"Admin-Bereich: http://{SERVER_ADDRESS}/admin", "INFO")
log_message(f"Admin-Benutzername: {ADMIN_USERNAME}", "INFO")
log_message(f"Log-Datei: {os.path.abspath(LOG_FILE)}", "INFO")

try:
    # Verbesserte Server-Klasse verwenden
    httpd = ThreadedHTTPServer(('0.0.0.0', PORT), FileServerHandler)
    httpd.serve_forever()
except KeyboardInterrupt:
    log_message("Server wird durch Benutzer beendet...", "INFO")
except Exception as e:
    log_message(f"Kritischer Fehler beim Starten des Servers: {str(e)}", "ERROR")
    traceback.print_exc()