fda61e6ec2c91bfaa4797b777238196e807203dd

Author
TheEdgeOfRage <git@theedgeofrage.com>
Committer
TheEdgeOfRage <git@theedgeofrage.com>
Date

Message

fix request handling

Diff

  1diff --git a/db/channels.go b/db/channels.go
  2index 79073cfca542df8d37f841979cf16cf535f3b6ef..7d90c2fc5abff2a8ea1489e52d696ce3b88785cf 100644
  3--- a/db/channels.go
  4+++ b/db/channels.go
  5@@ -63,6 +63,9 @@ func (db *postgresDB) ListChannels(ctx context.Context) ([]models.Channel, error
  6 		}
  7 		channels = append(channels, channel)
  8 	}
  9+	if err := rows.Err(); err != nil {
 10+		return nil, err
 11+	}
 12 
 13 	return channels, nil
 14 }
 15diff --git a/db/videos.go b/db/videos.go
 16index c03c97ee056024b390cf1af59cc16ca3017dea7b..0c9dda467e85bf108cd429363f2d235c3320d1a4 100644
 17--- a/db/videos.go
 18+++ b/db/videos.go
 19@@ -67,6 +67,9 @@ func (db *postgresDB) GetNewVideos(ctx context.Context, sortDesc bool) ([]models
 20 		}
 21 		videos = append(videos, video)
 22 	}
 23+	if err := rows.Err(); err != nil {
 24+		return nil, err
 25+	}
 26 
 27 	return videos, nil
 28 }
 29@@ -135,6 +138,9 @@ func (db *postgresDB) GetWatchedVideos(
 30 		}
 31 		videos = append(videos, video)
 32 	}
 33+	if err := rows.Err(); err != nil {
 34+		return nil, err
 35+	}
 36 
 37 	return videos, nil
 38 }
 39@@ -391,6 +397,9 @@ func (db *postgresDB) GetVideosForCleanup(ctx context.Context, olderThan time.Du
 40 		}
 41 		videos = append(videos, video)
 42 	}
 43+	if err := rows.Err(); err != nil {
 44+		return nil, err
 45+	}
 46 
 47 	return videos, nil
 48 }
 49@@ -415,6 +424,9 @@ func (db *postgresDB) GetLiveVideos(ctx context.Context) ([]models.Video, error)
 50 		}
 51 		videos = append(videos, video)
 52 	}
 53+	if err := rows.Err(); err != nil {
 54+		return nil, err
 55+	}
 56 
 57 	return videos, nil
 58 }
 59diff --git a/feedparser/feedparser.go b/feedparser/feedparser.go
 60index a322638f9718ee399fa7965f3e92ff68aa0a2611..6dc33cc23dbdec2bcd2439729e5da2abc25b20b0 100644
 61--- a/feedparser/feedparser.go
 62+++ b/feedparser/feedparser.go
 63@@ -34,7 +34,7 @@ func NewParser(l *slog.Logger) *parser {
 64 }
 65 
 66 func (p *parser) fetch(url string) (io.ReadCloser, error) {
 67-	req, err := http.NewRequest("GET", url, nil)
 68+	req, err := http.NewRequest(http.MethodGet, url, nil)
 69 	if err != nil {
 70 		p.log.Error("Failed to create request", "call", "http.NewRequest", "error", err)
 71 		return nil, err
 72@@ -47,8 +47,10 @@ func (p *parser) fetch(url string) (io.ReadCloser, error) {
 73 	}
 74 
 75 	if response.StatusCode == http.StatusNotFound {
 76+		response.Body.Close()
 77 		return nil, fmt.Errorf("%w: %s", ErrInvalidChannelID, url)
 78 	} else if response.StatusCode != http.StatusOK {
 79+		response.Body.Close()
 80 		return nil, fmt.Errorf("failed to get feed with status %d", response.StatusCode)
 81 	}
 82 
 83diff --git a/handler/downloads.go b/handler/downloads.go
 84index f85965cfad5d357bb26eb44d02607f5a25274c07..0d0fb2632231f42c63a1433b9f101a3029b245d4 100644
 85--- a/handler/downloads.go
 86+++ b/handler/downloads.go
 87@@ -91,7 +91,9 @@ func (h *handler) ServeVideoFile(ctx context.Context, videoID string) (filePath
 88 	}
 89 
 90 	if _, err := os.Stat(*video.FilePath); os.IsNotExist(err) {
 91-		h.db.DeleteVideoFile(ctx, videoID)
 92+		if dbErr := h.db.DeleteVideoFile(ctx, videoID); dbErr != nil {
 93+			h.log.Error("Failed to clear missing file from database", "video_id", videoID, "error", dbErr)
 94+		}
 95 		return "", "", fmt.Errorf("file not found on disk")
 96 	}
 97 
 98diff --git a/handler/videos.go b/handler/videos.go
 99index 409338214bce1a3b47f1ce1074762dc8c2b9c64c..8a62810becffc139771626cac4fc2e37b4fc2da4 100644
100--- a/handler/videos.go
101+++ b/handler/videos.go
102@@ -231,7 +231,7 @@ func (h *handler) SetVideoProgress(ctx context.Context, videoID string, progress
103 
104 	video, err := h.db.SetVideoProgress(ctx, videoID, int(progress.Seconds()))
105 	if err != nil {
106-		return nil, fmt.Errorf("%w: %v", ErrInvalidProgress, err.Error())
107+		return nil, fmt.Errorf("set video progress: %w", err)
108 	}
109 
110 	return video, nil
111diff --git a/httpserver/auth/auth.go b/httpserver/auth/auth.go
112index aae426d79d6a5e982b7bfd9326e070a5dc7d585e..f53b29d2cffce072c620d2a3af12be23b2b97e07 100644
113--- a/httpserver/auth/auth.go
114+++ b/httpserver/auth/auth.go
115@@ -12,10 +12,12 @@ func PageAuthMiddleware(authToken string) gin.HandlerFunc {
116 		tokenCookie, err := c.Request.Cookie("token")
117 		if err != nil {
118 			c.Redirect(http.StatusFound, "/auth")
119+			c.Abort()
120 			return
121 		}
122 		if tokenCookie.Value != authToken {
123 			c.Redirect(http.StatusFound, "/auth")
124+			c.Abort()
125 			return
126 		}
127 
128diff --git a/httpserver/auth/auth_test.go b/httpserver/auth/auth_test.go
129index c6cb38a7f0ef538cebf49cec477484833a7d01ff..1d978e816b5a439274de665fc820d4f2c3a3ad4c 100644
130--- a/httpserver/auth/auth_test.go
131+++ b/httpserver/auth/auth_test.go
132@@ -67,3 +67,21 @@ func (s *AuthTestSuite) TestWrongCredentials() {
133 	s.Equal(http.StatusUnauthorized, w.Code)
134 	s.Equal(`{"error":"invalid auth token"}`, w.Body.String())
135 }
136+
137+func (s *AuthTestSuite) TestPageAuthenticationStopsHandler() {
138+	engine := gin.New()
139+	handlerCalled := false
140+	engine.Use(PageAuthMiddleware(s.cfg.AuthToken))
141+	engine.POST("/", func(c *gin.Context) {
142+		handlerCalled = true
143+		c.Status(http.StatusNoContent)
144+	})
145+
146+	w := httptest.NewRecorder()
147+	req, _ := http.NewRequest(http.MethodPost, "/", nil)
148+	engine.ServeHTTP(w, req)
149+
150+	s.Equal(http.StatusFound, w.Code)
151+	s.Equal("/auth", w.Header().Get("Location"))
152+	s.False(handlerCalled)
153+}
154diff --git a/httpserver/ytrssil/videos.go b/httpserver/ytrssil/videos.go
155index 19c616e26a6e731cecc3a3c8649f9f1cf836bb07..acb6793b78298836275c141343398e01872d0a24 100644
156--- a/httpserver/ytrssil/videos.go
157+++ b/httpserver/ytrssil/videos.go
158@@ -138,7 +138,7 @@ func (srv *server) DownloadVideoJSON(c *gin.Context) {
159 		return
160 	}
161 
162-	if !isSupportedDownloadFormat(request.Format) {
163+	if request.Format <= 0 {
164 		c.JSON(http.StatusBadRequest, gin.H{"error": "invalid download format"})
165 		return
166 	}
167@@ -162,12 +162,3 @@ func (srv *server) ServeVideoFileJSON(c *gin.Context) {
168 	c.Header("Content-Disposition", "attachment; filename=\""+filename+"\"")
169 	c.File(filePath)
170 }
171-
172-func isSupportedDownloadFormat(format int) bool {
173-	switch format {
174-	case 480, 720, 1080, 1440, 2160:
175-		return true
176-	default:
177-		return false
178-	}
179-}
180diff --git a/lib/clients/youtube/is_short.go b/lib/clients/youtube/is_short.go
181index a331e6485c72720f555515f348e45c8047228107..51545f867e641d5932e360d4421dcde2a28f4516 100644
182--- a/lib/clients/youtube/is_short.go
183+++ b/lib/clients/youtube/is_short.go
184@@ -28,6 +28,7 @@ func (c *youTubeClient) isShort(ctx context.Context, videoID string) (bool, erro
185 		c.log.Error("Failed to check if a video is a short", "videoID", videoID, "error", err)
186 		return false, err
187 	}
188+	defer resp.Body.Close()
189 
190 	return resp.StatusCode == http.StatusOK, nil
191 }
192diff --git a/models/video.go b/models/video.go
193index 73fb15b7edea7324797e80a49df04b2bfd0d0ecf..d843c078895597b12f4658944c982e197b0e49a0 100644
194--- a/models/video.go
195+++ b/models/video.go
196@@ -43,7 +43,18 @@ type Video struct {
197 
198 // ProgressPercentage returns the current progress of the video as an integer from 0-100
199 func (v Video) ProgressPercentage() int {
200-	return int(100 * float64(v.ProgressSeconds) / float64(v.DurationSeconds))
201+	if v.DurationSeconds <= 0 {
202+		return 0
203+	}
204+
205+	percentage := 100 * v.ProgressSeconds / v.DurationSeconds
206+	if percentage < 0 {
207+		return 0
208+	}
209+	if percentage > 100 {
210+		return 100
211+	}
212+	return percentage
213 }
214 
215 // WatchURL returns the formatted YouTube watch URL including the timestamp pointing to  the current progress