68 lines
1.5 KiB
Go
68 lines
1.5 KiB
Go
|
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)
|
||
|
}
|
||
|
}
|