add cache endpoint, basic auth
Marco Andronaco andronacomarco@gmail.com
Thu, 17 Oct 2024 11:13:16 +0200
6 files changed,
66 insertions(+),
18 deletions(-)
M
.env.example
→
.env.example
@@ -1,2 +1,4 @@
-APP_DEBUG=true +APP_DEBUG=false APP_PORT=3000 +APP_ADMIN_USER=admin +APP_ADMIN_PASS=admin
M
src/app/handlers.go
→
src/app/handlers.go
@@ -8,6 +8,7 @@ "net/http"
"regexp" g "github.com/birabittoh/gopipe/src/globals" + "github.com/kkdai/youtube/v2" "golang.org/x/time/rate" )@@ -15,6 +16,7 @@ const (
fmtYouTubeURL = "https://www.youtube.com/watch?v=%s" err404 = "Not Found" err500 = "Internal Server Error" + err401 = "Unauthorized" heading = `<!-- .d8888b. 88888888888 888 d88P Y88b 888 888@@ -30,8 +32,7 @@ -->`
) var ( - userAgentRegex = regexp.MustCompile(`(?i)bot|facebook|embed|got|firefox\/92|firefox\/38|curl|wget|go-http|yahoo|generator|whatsapp|preview|link|proxy|vkshare|images|analyzer|index|crawl|spider|python|cfnetwork|node`) - videoRegex = regexp.MustCompile(`(?i)^[a-z0-9_-]{11}$`) + videoRegex = regexp.MustCompile(`(?i)^[a-z0-9_-]{11}$`) ) func limit(limiter *rate.Limiter, next http.Handler) http.Handler {@@ -64,18 +65,9 @@ return
} } - if !userAgentRegex.MatchString(r.UserAgent()) { - log.Println("Regex did not match. UA: ", r.UserAgent()) - if !g.Debug { - log.Println("Redirecting.") - http.Redirect(w, r, getURL(videoID), http.StatusFound) - return - } - } - if !videoRegex.MatchString(videoID) { log.Println("Invalid video ID: ", videoID) - http.Error(w, "Invalid video ID.", http.StatusBadRequest) + http.Error(w, err404, http.StatusNotFound) return }@@ -111,7 +103,6 @@ "Description": video.Description,
"Thumbnail": thumbnail, "Duration": video.Duration, "Captions": getCaptions(*video), - "Debug": g.Debug, "Heading": template.HTML(heading), }@@ -122,3 +113,29 @@ http.Error(w, err500, http.StatusInternalServerError)
return } } + +func cacheHandler(w http.ResponseWriter, r *http.Request) { + username, password, ok := r.BasicAuth() + if !ok || username != g.AdminUser || password != g.AdminPass { + w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) + http.Error(w, err401, http.StatusUnauthorized) + return + } + + var videos []youtube.Video + for s := range g.KS.Keys() { + video, err := g.KS.Get(s) + if err != nil || video == nil { + continue + } + videos = append(videos, *video) + } + + data := map[string]interface{}{"Videos": videos} + err := g.XT.ExecuteTemplate(w, "cache.tmpl", data) + if err != nil { + log.Println("cacheHandler ERROR: ", err) + http.Error(w, err500, http.StatusInternalServerError) + return + } +}
M
src/app/main.go
→
src/app/main.go
@@ -30,6 +30,13 @@ }
g.Port = getEnvDefault("APP_PORT", "3000") + g.AdminUser = getEnvDefault("APP_ADMIN_USER", "admin") + g.AdminPass = getEnvDefault("APP_ADMIN_PASS", "admin") + + if g.AdminUser == "admin" && g.AdminPass == "admin" { + log.Println("Admin credentials not set. Please set APP_ADMIN_USER and APP_ADMIN_PASS.") + } + // set up extemplate err := g.XT.ParseDir("templates", []string{".tmpl"}) if err != nil {@@ -58,7 +65,7 @@ r.HandleFunc("GET /proxy/{videoID}", proxyHandler)
r.HandleFunc("GET /proxy/{videoID}/{formatID}", proxyHandler) r.HandleFunc("GET /sub/{videoID}/{language}", subHandler) - // r.HandleFunc("GET /robots.txt", robotsHandler) + r.HandleFunc("GET /cache", cacheHandler) log.Println("Serving on port " + g.Port) log.Fatal(http.ListenAndServe(":"+g.Port, serveMux))
M
src/globals/globals.go
→
src/globals/globals.go
@@ -21,4 +21,7 @@ XT = extemplate.New()
KS = myks.New[youtube.Video](3 * time.Hour) PKS *myks.KeyStore[bytes.Buffer] + + AdminUser string + AdminPass string )
A
templates/cache.tmpl
@@ -0,0 +1,22 @@
+{{ extends "base.tmpl" }} + +{{define "heading"}}{{end}} + +{{define "meta" -}} + <title>Cache - GoPipe</title> +{{end}} + + +{{define "content" -}} + <h1>Cached videos</h1> + <a href="/">← Home</a> + <ul style="margin-top: 30px"> + {{ range .Videos }} + <li> + <a href="/{{ .ID }}">{{ .Title }}</a> + <br /> + <small>{{ .Author }}</small> + </li> + {{ end }} + </ul> +{{end}}
M
templates/video.tmpl
→
templates/video.tmpl
@@ -3,9 +3,6 @@
{{define "meta" -}} <title>{{ .Title }} - GoPipe</title> <link rel="canonical" href="https://www.youtube.com/watch?v={{ .VideoID }}" /> - {{ if not .Debug }} - <meta http-equiv="refresh" content="0;url=https://www.youtube.com/watch?v={{ .VideoID }}" /> - {{ end }} <meta property="og:url" content="https://www.youtube.com/watch?v={{ .VideoID }}" /> <meta property="theme-color" content="0000FF" /> <meta property="twitter:card" content="player" />