package handlers import ( "SimpleTutorialHosting/internal/storage" "fmt" "html/template" "io" "log" "net/http" ) type Handlers struct { store *storage.S3Client tmpl *template.Template } func New(store *storage.S3Client) (*Handlers, error) { tmpl, err := template.ParseFiles("templates/index.html") if err != nil { return nil, err } return &Handlers{ store: store, tmpl: tmpl, }, nil } func (h *Handlers) HandleIndex(w http.ResponseWriter, r *http.Request) { config, err := h.store.GetConfig(r.Context()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Printf("Error getting config: %v", err) return } h.tmpl.Execute(w, config) } func (h *Handlers) HandleStreamVideo(w http.ResponseWriter, r *http.Request) { videoKey := r.URL.Query().Get("key") if videoKey == "" { http.Error(w, "No key provided", http.StatusBadRequest) return } result, err := h.store.StreamVideo(r.Context(), videoKey, r.Header.Get("Range")) if err != nil { http.Error(w, "Failed to get video", http.StatusInternalServerError) log.Printf("Error streaming video: %v", err) return } defer result.Body.Close() w.Header().Set("Content-Type", *result.ContentType) w.Header().Set("Content-Length", fmt.Sprintf("%d", result.ContentLength)) if r.Header.Get("Range") != "" { w.Header().Set("Accept-Ranges", "bytes") w.Header().Set("Content-Range", *result.ContentRange) w.WriteHeader(http.StatusPartialContent) } if _, err := io.Copy(w, result.Body); err != nil { log.Printf("Error copying video: %v", err) } }