package api import ( "crypto/sha256" "encoding/hex" "fmt" "io" "log" "net/http" ) // POST /api/v1/installer/upload?platform=freebsd — Installer-Paket hochladen (ZIP oder Script) func (h *Handler) uploadInstaller(w http.ResponseWriter, r *http.Request) { platform := r.URL.Query().Get("platform") if platform == "" { platform = "freebsd" } validPlatforms := map[string]bool{"freebsd": true, "linux": true, "windows": true} if !validPlatforms[platform] { writeError(w, http.StatusBadRequest, "Ungueltige Plattform (freebsd, linux, windows)") return } // Max 50MB r.Body = http.MaxBytesReader(w, r.Body, 50*1024*1024) // Multipart oder raw body var data []byte var filename string var err error if ct := r.Header.Get("Content-Type"); ct != "" && len(ct) > 19 && ct[:19] == "multipart/form-data" { file, header, ferr := r.FormFile("file") if ferr != nil { writeError(w, http.StatusBadRequest, "Datei fehlt im Upload") return } defer file.Close() data, err = io.ReadAll(file) filename = header.Filename } else { data, err = io.ReadAll(r.Body) filename = r.URL.Query().Get("filename") if filename == "" { filename = fmt.Sprintf("installer-%s.zip", platform) } } if err != nil || len(data) == 0 { writeError(w, http.StatusBadRequest, "Leere oder fehlerhafte Datei") return } hash := sha256.Sum256(data) hashStr := hex.EncodeToString(hash[:]) if err := h.db.SaveInstaller(platform, filename, hashStr, data); err != nil { log.Printf("Installer speichern fehlgeschlagen: %v", err) writeError(w, http.StatusInternalServerError, "Speichern fehlgeschlagen") return } log.Printf("Installer fuer %s hochgeladen: %s (%d bytes, SHA256: %s)", platform, filename, len(data), hashStr[:16]) writeJSON(w, http.StatusOK, map[string]interface{}{ "platform": platform, "filename": filename, "sha256": hashStr, "size": len(data), "message": "Installer hochgeladen", }) } // GET /api/v1/installer — Installer-Info (alle Plattformen) func (h *Handler) getInstallerInfo(w http.ResponseWriter, r *http.Request) { all, err := h.db.GetAllInstallerInfo() if err != nil || len(all) == 0 { writeJSON(w, http.StatusOK, map[string]interface{}{ "installers": []interface{}{}, }) return } writeJSON(w, http.StatusOK, map[string]interface{}{ "installers": all, }) } // GET /api/v1/installer/download?platform=freebsd — Installer herunterladen func (h *Handler) downloadInstaller(w http.ResponseWriter, r *http.Request) { platform := r.URL.Query().Get("platform") if platform == "" { platform = "freebsd" } filename, hashStr, data, err := h.db.GetInstaller(platform) if err != nil { writeError(w, http.StatusNotFound, fmt.Sprintf("Kein Installer fuer Plattform '%s' vorhanden", platform)) return } w.Header().Set("Content-Type", "application/octet-stream") w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename)) w.Header().Set("X-Installer-SHA256", hashStr) w.Header().Set("Content-Length", fmt.Sprintf("%d", len(data))) w.Write(data) }