Fix proxy for other formats

This commit is contained in:
Evan Fiordeliso 2025-11-10 15:56:13 -05:00
parent 2630af4921
commit c281da0eb0
4 changed files with 31 additions and 17 deletions

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"log/slog" "log/slog"
@ -13,25 +14,26 @@ import (
"go.fifitido.net/ytdl-web/pkg/ytdl/metadata" "go.fifitido.net/ytdl-web/pkg/ytdl/metadata"
) )
func getUrlParam(r *http.Request) (string, bool) { func getUrlParam(r *http.Request) (string, error) {
urlRaw := r.URL.Query().Get("url") urlRaw := r.URL.Query().Get("url")
if urlRaw == "" { if urlRaw == "" {
return "", false return "", errors.New("url param not specified")
} }
urlUnescaped, err := url.QueryUnescape(urlRaw) urlUnescaped, err := url.QueryUnescape(urlRaw)
if err != nil || len(urlUnescaped) < 1 { if err != nil || len(urlUnescaped) < 1 {
return "", false return "", errors.New("invalid url")
} }
return urlUnescaped, true return urlUnescaped, nil
} }
func download(w http.ResponseWriter, r *http.Request) { func download(w http.ResponseWriter, r *http.Request) {
ytdl := ytdl.Default() ytdl := ytdl.Default()
videoUrl, ok := getUrlParam(r) videoUrl, err := getUrlParam(r)
if !ok { if err != nil {
slog.ErrorContext(r.Context(), "Failed to get video url param", slog.Any("error", err))
views.Render(w, r, views.Home(&views.Error{Message: "Invalid URL"})) views.Render(w, r, views.Home(&views.Error{Message: "Invalid URL"}))
return return
} }
@ -47,15 +49,16 @@ func download(w http.ResponseWriter, r *http.Request) {
func proxyDownload(w http.ResponseWriter, r *http.Request) { func proxyDownload(w http.ResponseWriter, r *http.Request) {
ytdl := ytdl.Default() ytdl := ytdl.Default()
videoUrl, ok := getUrlParam(r) videoUrl, err := getUrlParam(r)
if !ok { if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) slog.ErrorContext(r.Context(), "Failed to get video url param", slog.Any("error", err))
http.Error(w, "Video URL not specified or invalid URL", http.StatusBadRequest)
return return
} }
formatId := r.URL.Query().Get("format") formatId := r.URL.Query().Get("format")
if formatId == "" { if formatId == "" {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) http.Error(w, "Format ID not specified", http.StatusBadRequest)
return return
} }
@ -69,7 +72,8 @@ func proxyDownload(w http.ResponseWriter, r *http.Request) {
index, err := strconv.Atoi(r.URL.Query().Get("index")) index, err := strconv.Atoi(r.URL.Query().Get("index"))
if err != nil || index < 0 || index >= len(videos) { if err != nil || index < 0 || index >= len(videos) {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) slog.Error("Failed to parse index", slog.Any("error", err), slog.Int("index", index), slog.Int("len", len(videos)))
http.Error(w, "Index not specified or invalid index", http.StatusBadRequest)
return return
} }
@ -82,8 +86,19 @@ func proxyDownload(w http.ResponseWriter, r *http.Request) {
break break
} }
} }
if format == nil { if format == nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) for _, f := range video.OtherFormats {
if f.FormatID == formatId {
format = &f
break
}
}
}
if format == nil {
slog.Error("Failed to find format", slog.String("format_id", formatId), slog.String("video_id", video.Meta.ID), slog.Int("index", index))
http.Error(w, "Format not found", http.StatusBadRequest)
return return
} }
@ -97,6 +112,7 @@ func proxyDownload(w http.ResponseWriter, r *http.Request) {
} }
read, write := io.Pipe() read, write := io.Pipe()
defer write.Close()
go func() { go func() {
_, err := io.Copy(w, read) _, err := io.Copy(w, read)
@ -109,6 +125,4 @@ func proxyDownload(w http.ResponseWriter, r *http.Request) {
slog.Error("Failed to download", slog.String("error", err.Error())) slog.Error("Failed to download", slog.String("error", err.Error()))
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
} }
write.Close()
} }

View File

@ -1,4 +1,4 @@
{ pkgs, lib, config, inputs, ... }: { pkgs, config, ... }:
{ {
# https://devenv.sh/basics/ # https://devenv.sh/basics/

View File

@ -31,7 +31,7 @@ templ videoFormatView(vm *DownloadsViewModel, vidIndex int, format metadata.Form
<a <a
class="btn btn-primary flex-grow-1" class="btn btn-primary flex-grow-1"
download={ filename } download={ filename }
href={ pathTo(ctx, fmt.Sprintf("download/proxy?url=%s&format=%s&index=%d", vm.Url, format.FormatID, vidIndex)) } href={ pathTo(ctx, fmt.Sprintf("/download/proxy?url=%s&format=%s&index=%d", vm.Url, format.FormatID, vidIndex)) }
aria-label="Proxied Download" aria-label="Proxied Download"
> >
Download (proxied) Download (proxied)

View File

@ -9,5 +9,5 @@ import (
) )
func pathTo(ctx context.Context, path ...string) templ.SafeURL { func pathTo(ctx context.Context, path ...string) templ.SafeURL {
return templ.SafeURL(serverctx.BasePath(ctx) + "/" + strings.TrimPrefix(strings.Join(path, "/"), "/")) return templ.SafeURL(strings.TrimSuffix(serverctx.BasePath(ctx), "/") + "/" + strings.TrimPrefix(strings.Join(path, "/"), "/"))
} }